@acala-network/chopsticks-core 0.9.6 → 0.9.8-1
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/api.d.ts +1 -0
- package/dist/cjs/api.js +26 -0
- package/dist/cjs/blockchain/block.js +1 -3
- package/dist/cjs/blockchain/storage-layer.js +125 -69
- package/dist/cjs/logger.d.ts +2 -12
- package/dist/cjs/rpc/shared.d.ts +1 -6
- package/dist/cjs/utils/index.d.ts +2 -0
- package/dist/cjs/utils/index.js +11 -5
- package/dist/cjs/utils/key-cache.d.ts +2 -1
- package/dist/cjs/utils/key-cache.js +27 -25
- package/dist/cjs/wasm-executor/index.js +2 -3
- package/dist/cjs/xcm/index.d.ts +1 -6
- package/dist/esm/api.d.ts +1 -0
- package/dist/esm/api.js +21 -0
- package/dist/esm/blockchain/block.js +1 -3
- package/dist/esm/blockchain/storage-layer.js +121 -27
- package/dist/esm/logger.d.ts +2 -12
- package/dist/esm/rpc/shared.d.ts +1 -6
- package/dist/esm/utils/index.d.ts +2 -0
- package/dist/esm/utils/index.js +6 -4
- package/dist/esm/utils/key-cache.d.ts +2 -1
- package/dist/esm/utils/key-cache.js +25 -14
- package/dist/esm/wasm-executor/index.js +1 -2
- package/dist/esm/xcm/index.d.ts +1 -6
- package/package.json +13 -13
package/dist/cjs/api.d.ts
CHANGED
|
@@ -50,6 +50,7 @@ export declare class Api {
|
|
|
50
50
|
getBlock(hash?: string): Promise<SignedBlock | null>;
|
|
51
51
|
getStorage(key: string, hash?: string): Promise<`0x${string}` | null>;
|
|
52
52
|
getKeysPaged(prefix: string, pageSize: number, startKey: string, hash?: string): Promise<string[]>;
|
|
53
|
+
getStorageBatch(prefix: HexString, keys: HexString[], hash?: HexString): Promise<[`0x${string}`, `0x${string}` | null][]>;
|
|
53
54
|
subscribeRemoteNewHeads(cb: ProviderInterfaceCallback): Promise<string | number>;
|
|
54
55
|
subscribeRemoteFinalizedHeads(cb: ProviderInterfaceCallback): Promise<string | number>;
|
|
55
56
|
}
|
package/dist/cjs/api.js
CHANGED
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "Api", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
const _index = require("./utils/index.js");
|
|
12
|
+
const _lodash = /*#__PURE__*/ _interop_require_default(require("lodash"));
|
|
12
13
|
function _check_private_redeclaration(obj, privateCollection) {
|
|
13
14
|
if (privateCollection.has(obj)) {
|
|
14
15
|
throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
@@ -62,6 +63,11 @@ function _define_property(obj, key, value) {
|
|
|
62
63
|
}
|
|
63
64
|
return obj;
|
|
64
65
|
}
|
|
66
|
+
function _interop_require_default(obj) {
|
|
67
|
+
return obj && obj.__esModule ? obj : {
|
|
68
|
+
default: obj
|
|
69
|
+
};
|
|
70
|
+
}
|
|
65
71
|
var _provider = /*#__PURE__*/ new WeakMap(), _ready = /*#__PURE__*/ new WeakMap(), _chain = /*#__PURE__*/ new WeakMap(), _chainProperties = /*#__PURE__*/ new WeakMap();
|
|
66
72
|
class Api {
|
|
67
73
|
async disconnect() {
|
|
@@ -163,6 +169,26 @@ class Api {
|
|
|
163
169
|
return _class_private_field_get(this, _provider).send('state_getKeysPaged', params, !!hash);
|
|
164
170
|
}
|
|
165
171
|
}
|
|
172
|
+
async getStorageBatch(prefix, keys, hash) {
|
|
173
|
+
const [child] = (0, _index.splitChildKey)(prefix);
|
|
174
|
+
if (child) {
|
|
175
|
+
// child storage key, use childstate_getStorageEntries
|
|
176
|
+
// strip child prefix from keys
|
|
177
|
+
const params = [
|
|
178
|
+
child,
|
|
179
|
+
keys.map((key)=>(0, _index.stripChildPrefix)(key))
|
|
180
|
+
];
|
|
181
|
+
if (hash) params.push(hash);
|
|
182
|
+
return _class_private_field_get(this, _provider).send('childstate_getStorageEntries', params, !!hash).then((values)=>_lodash.default.zip(keys, values));
|
|
183
|
+
} else {
|
|
184
|
+
// main storage key, use state_getStorageAt
|
|
185
|
+
const params = [
|
|
186
|
+
keys
|
|
187
|
+
];
|
|
188
|
+
if (hash) params.push(hash);
|
|
189
|
+
return _class_private_field_get(this, _provider).send('state_queryStorageAt', params, !!hash).then((result)=>result[0]?.['changes'] || []);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
166
192
|
async subscribeRemoteNewHeads(cb) {
|
|
167
193
|
if (!_class_private_field_get(this, _provider).hasSubscriptions) {
|
|
168
194
|
throw new Error('subscribeRemoteNewHeads only works with subscriptions');
|
|
@@ -139,12 +139,10 @@ class Block {
|
|
|
139
139
|
/**
|
|
140
140
|
* Get paged storage keys.
|
|
141
141
|
*/ async getKeysPaged(options) {
|
|
142
|
-
const layer = new _storagelayer.StorageLayer(this.storage);
|
|
143
|
-
await layer.fold();
|
|
144
142
|
const prefix = options.prefix ?? '0x';
|
|
145
143
|
const startKey = options.startKey ?? '0x';
|
|
146
144
|
const pageSize = options.pageSize;
|
|
147
|
-
return
|
|
145
|
+
return this.storage.getKeysPaged(prefix, pageSize, startKey);
|
|
148
146
|
}
|
|
149
147
|
/**
|
|
150
148
|
* Push a layer to the storage stack.
|
|
@@ -20,8 +20,9 @@ _export(exports, {
|
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
const _lodash = /*#__PURE__*/ _interop_require_default(require("lodash"));
|
|
23
|
+
const _index = require("../utils/index.js");
|
|
23
24
|
const _logger = require("../logger.js");
|
|
24
|
-
const _keycache = /*#__PURE__*/
|
|
25
|
+
const _keycache = /*#__PURE__*/ _interop_require_default(require("../utils/key-cache.js"));
|
|
25
26
|
function _check_private_redeclaration(obj, privateCollection) {
|
|
26
27
|
if (privateCollection.has(obj)) {
|
|
27
28
|
throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
@@ -77,47 +78,6 @@ function _interop_require_default(obj) {
|
|
|
77
78
|
default: obj
|
|
78
79
|
};
|
|
79
80
|
}
|
|
80
|
-
function _getRequireWildcardCache(nodeInterop) {
|
|
81
|
-
if (typeof WeakMap !== "function") return null;
|
|
82
|
-
var cacheBabelInterop = new WeakMap();
|
|
83
|
-
var cacheNodeInterop = new WeakMap();
|
|
84
|
-
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
85
|
-
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
86
|
-
})(nodeInterop);
|
|
87
|
-
}
|
|
88
|
-
function _interop_require_wildcard(obj, nodeInterop) {
|
|
89
|
-
if (!nodeInterop && obj && obj.__esModule) {
|
|
90
|
-
return obj;
|
|
91
|
-
}
|
|
92
|
-
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
93
|
-
return {
|
|
94
|
-
default: obj
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
var cache = _getRequireWildcardCache(nodeInterop);
|
|
98
|
-
if (cache && cache.has(obj)) {
|
|
99
|
-
return cache.get(obj);
|
|
100
|
-
}
|
|
101
|
-
var newObj = {
|
|
102
|
-
__proto__: null
|
|
103
|
-
};
|
|
104
|
-
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
105
|
-
for(var key in obj){
|
|
106
|
-
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
107
|
-
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
108
|
-
if (desc && (desc.get || desc.set)) {
|
|
109
|
-
Object.defineProperty(newObj, key, desc);
|
|
110
|
-
} else {
|
|
111
|
-
newObj[key] = obj[key];
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
newObj.default = obj;
|
|
116
|
-
if (cache) {
|
|
117
|
-
cache.set(obj, newObj);
|
|
118
|
-
}
|
|
119
|
-
return newObj;
|
|
120
|
-
}
|
|
121
81
|
const logger = _logger.defaultLogger.child({
|
|
122
82
|
name: 'layer'
|
|
123
83
|
});
|
|
@@ -127,7 +87,7 @@ var StorageValueKind;
|
|
|
127
87
|
StorageValueKind["Deleted"] = "Deleted";
|
|
128
88
|
StorageValueKind["DeletedPrefix"] = "DeletedPrefix";
|
|
129
89
|
})(StorageValueKind || (StorageValueKind = {}));
|
|
130
|
-
var _api = /*#__PURE__*/ new WeakMap(), _at = /*#__PURE__*/ new WeakMap(), _db = /*#__PURE__*/ new WeakMap(), _keyCache = /*#__PURE__*/ new WeakMap();
|
|
90
|
+
var _api = /*#__PURE__*/ new WeakMap(), _at = /*#__PURE__*/ new WeakMap(), _db = /*#__PURE__*/ new WeakMap(), _keyCache = /*#__PURE__*/ new WeakMap(), _defaultChildKeyCache = /*#__PURE__*/ new WeakMap();
|
|
131
91
|
class RemoteStorageLayer {
|
|
132
92
|
async get(key, _cache) {
|
|
133
93
|
if (_class_private_field_get(this, _db)) {
|
|
@@ -156,14 +116,16 @@ class RemoteStorageLayer {
|
|
|
156
116
|
pageSize,
|
|
157
117
|
startKey
|
|
158
118
|
}, 'RemoteStorageLayer getKeysPaged');
|
|
119
|
+
const isChild = (0, _index.isPrefixedChildKey)(prefix);
|
|
120
|
+
const minPrefixLen = isChild ? _index.CHILD_PREFIX_LENGTH : _index.PREFIX_LENGTH;
|
|
159
121
|
// can't handle keyCache without prefix
|
|
160
|
-
if (prefix.length <
|
|
122
|
+
if (prefix.length < minPrefixLen || startKey.length < minPrefixLen) {
|
|
161
123
|
return _class_private_field_get(this, _api).getKeysPaged(prefix, pageSize, startKey, _class_private_field_get(this, _at));
|
|
162
124
|
}
|
|
163
125
|
let batchComplete = false;
|
|
164
126
|
const keysPaged = [];
|
|
165
127
|
while(keysPaged.length < pageSize){
|
|
166
|
-
const nextKey = await _class_private_field_get(this, _keyCache).next(startKey);
|
|
128
|
+
const nextKey = isChild ? await _class_private_field_get(this, _defaultChildKeyCache).next(startKey) : await _class_private_field_get(this, _keyCache).next(startKey);
|
|
167
129
|
if (nextKey) {
|
|
168
130
|
keysPaged.push(nextKey);
|
|
169
131
|
startKey = nextKey;
|
|
@@ -178,14 +140,29 @@ class RemoteStorageLayer {
|
|
|
178
140
|
batchComplete = batch.length < BATCH_SIZE;
|
|
179
141
|
// feed the key cache
|
|
180
142
|
if (batch.length > 0) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
143
|
+
if (isChild) {
|
|
144
|
+
_class_private_field_get(this, _defaultChildKeyCache).feed([
|
|
145
|
+
startKey,
|
|
146
|
+
...batch
|
|
147
|
+
]);
|
|
148
|
+
} else {
|
|
149
|
+
_class_private_field_get(this, _keyCache).feed([
|
|
150
|
+
startKey,
|
|
151
|
+
...batch
|
|
152
|
+
]);
|
|
153
|
+
}
|
|
185
154
|
}
|
|
186
155
|
if (batch.length === 0) {
|
|
187
156
|
break;
|
|
188
157
|
}
|
|
158
|
+
if (_class_private_field_get(this, _db)) {
|
|
159
|
+
// batch fetch storage values and save to db, they may be used later
|
|
160
|
+
_class_private_field_get(this, _api).getStorageBatch(prefix, batch, _class_private_field_get(this, _at)).then((storage)=>{
|
|
161
|
+
for (const [key, value] of storage){
|
|
162
|
+
_class_private_field_get(this, _db).saveStorage(_class_private_field_get(this, _at), key, value);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
189
166
|
}
|
|
190
167
|
return keysPaged;
|
|
191
168
|
}
|
|
@@ -204,7 +181,11 @@ class RemoteStorageLayer {
|
|
|
204
181
|
});
|
|
205
182
|
_class_private_field_init(this, _keyCache, {
|
|
206
183
|
writable: true,
|
|
207
|
-
value: new _keycache.default()
|
|
184
|
+
value: new _keycache.default(_index.PREFIX_LENGTH)
|
|
185
|
+
});
|
|
186
|
+
_class_private_field_init(this, _defaultChildKeyCache, {
|
|
187
|
+
writable: true,
|
|
188
|
+
value: new _keycache.default(_index.CHILD_PREFIX_LENGTH)
|
|
208
189
|
});
|
|
209
190
|
_class_private_field_set(this, _api, api);
|
|
210
191
|
_class_private_field_set(this, _at, at);
|
|
@@ -278,30 +259,105 @@ class StorageLayer {
|
|
|
278
259
|
}
|
|
279
260
|
}
|
|
280
261
|
async getKeysPaged(prefix, pageSize, startKey) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
262
|
+
let parentFetchComplete = false;
|
|
263
|
+
const parentFetchKeys = async (batchSize, startKey)=>{
|
|
264
|
+
if (!_class_private_field_get(this, _deletedPrefix).some((dp)=>startKey.startsWith(dp))) {
|
|
265
|
+
const newKeys = [];
|
|
266
|
+
while(newKeys.length < batchSize){
|
|
267
|
+
const remote = await _class_private_field_get(this, _parent)?.getKeysPaged(prefix, batchSize, startKey) ?? [];
|
|
268
|
+
if (remote.length) {
|
|
269
|
+
startKey = remote[remote.length - 1];
|
|
270
|
+
}
|
|
271
|
+
for (const key of remote){
|
|
272
|
+
if (_class_private_field_get(this, _store).get(key) === "Deleted") {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (_class_private_field_get(this, _deletedPrefix).some((dp)=>key.startsWith(dp))) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
newKeys.push(key);
|
|
279
|
+
}
|
|
280
|
+
if (remote.length < batchSize) {
|
|
281
|
+
parentFetchComplete = true;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return newKeys;
|
|
286
|
+
} else {
|
|
287
|
+
parentFetchComplete = true;
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
const res = [];
|
|
292
|
+
const foundNextKey = (key)=>{
|
|
293
|
+
// make sure keys are unique
|
|
294
|
+
if (!res.includes(key)) {
|
|
295
|
+
res.push(key);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
const iterLocalKeys = (prefix, startKey, includeFirst, endKey)=>{
|
|
299
|
+
let idx = _class_private_field_get(this, _keys).findIndex((x)=>x.startsWith(startKey));
|
|
300
|
+
if (_class_private_field_get(this, _keys)[idx] !== startKey) {
|
|
301
|
+
idx = _class_private_field_get(this, _keys).findIndex((x)=>x.startsWith(prefix) && x > startKey);
|
|
302
|
+
const key = _class_private_field_get(this, _keys)[idx];
|
|
303
|
+
if (key) {
|
|
304
|
+
if (endKey && key >= endKey) {
|
|
305
|
+
return startKey;
|
|
306
|
+
}
|
|
307
|
+
foundNextKey(key);
|
|
308
|
+
++idx;
|
|
286
309
|
}
|
|
287
|
-
|
|
288
|
-
|
|
310
|
+
}
|
|
311
|
+
if (idx !== -1) {
|
|
312
|
+
if (includeFirst) {
|
|
313
|
+
const key = _class_private_field_get(this, _keys)[idx];
|
|
314
|
+
if (key) {
|
|
315
|
+
foundNextKey(key);
|
|
316
|
+
}
|
|
289
317
|
}
|
|
290
|
-
|
|
318
|
+
while(res.length < pageSize){
|
|
319
|
+
++idx;
|
|
320
|
+
const key = _class_private_field_get(this, _keys)[idx];
|
|
321
|
+
if (!key || !key.startsWith(prefix)) {
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
if (endKey && key >= endKey) {
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
foundNextKey(key);
|
|
328
|
+
}
|
|
329
|
+
return _lodash.default.last(res) ?? startKey;
|
|
291
330
|
}
|
|
331
|
+
return startKey;
|
|
332
|
+
};
|
|
333
|
+
if (prefix !== startKey && _class_private_field_get(this, _keys).find((x)=>x === startKey)) {
|
|
334
|
+
startKey = iterLocalKeys(prefix, startKey, false);
|
|
292
335
|
}
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
336
|
+
// then iterate the parent keys
|
|
337
|
+
let keys = await parentFetchKeys(pageSize - res.length, startKey);
|
|
338
|
+
if (keys.length) {
|
|
339
|
+
let idx = 0;
|
|
340
|
+
while(res.length < pageSize){
|
|
341
|
+
const key = keys[idx];
|
|
342
|
+
if (!key || !key.startsWith(prefix)) {
|
|
343
|
+
if (parentFetchComplete) {
|
|
344
|
+
break;
|
|
345
|
+
} else {
|
|
346
|
+
keys = await parentFetchKeys(pageSize - res.length, _lodash.default.last(keys));
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
const keyPosition = _lodash.default.sortedIndex(_class_private_field_get(this, _keys), key);
|
|
351
|
+
const localParentKey = _class_private_field_get(this, _keys)[keyPosition - 1];
|
|
352
|
+
if (localParentKey < key) {
|
|
353
|
+
startKey = iterLocalKeys(prefix, startKey, false, key);
|
|
354
|
+
}
|
|
355
|
+
foundNextKey(key);
|
|
356
|
+
++idx;
|
|
302
357
|
}
|
|
303
|
-
|
|
304
|
-
|
|
358
|
+
}
|
|
359
|
+
if (res.length < pageSize) {
|
|
360
|
+
iterLocalKeys(prefix, startKey, prefix === startKey);
|
|
305
361
|
}
|
|
306
362
|
return res;
|
|
307
363
|
}
|
package/dist/cjs/logger.d.ts
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
1
|
import { pino } from 'pino';
|
|
2
|
-
export declare const pinoLogger: import("pino").Logger<
|
|
3
|
-
|
|
4
|
-
transport: {
|
|
5
|
-
target: string;
|
|
6
|
-
};
|
|
7
|
-
}>;
|
|
8
|
-
export declare const defaultLogger: pino.Logger<{
|
|
9
|
-
level: string;
|
|
10
|
-
transport: {
|
|
11
|
-
target: string;
|
|
12
|
-
};
|
|
13
|
-
}>;
|
|
2
|
+
export declare const pinoLogger: import("pino").Logger<never>;
|
|
3
|
+
export declare const defaultLogger: pino.Logger<never>;
|
|
14
4
|
export declare const truncate: (val: any) => any;
|
package/dist/cjs/rpc/shared.d.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { Blockchain } from '../blockchain/index.js';
|
|
2
|
-
export declare const logger: import("pino").default.Logger<
|
|
3
|
-
level: string;
|
|
4
|
-
transport: {
|
|
5
|
-
target: string;
|
|
6
|
-
};
|
|
7
|
-
}>;
|
|
2
|
+
export declare const logger: import("pino").default.Logger<never>;
|
|
8
3
|
export declare class ResponseError extends Error {
|
|
9
4
|
code: number;
|
|
10
5
|
constructor(code: number, message: string);
|
|
@@ -17,6 +17,8 @@ export type Deferred<T> = {
|
|
|
17
17
|
promise: Promise<T>;
|
|
18
18
|
};
|
|
19
19
|
export declare function defer<T>(): Deferred<T>;
|
|
20
|
+
export declare const CHILD_PREFIX_LENGTH: number;
|
|
21
|
+
export declare const PREFIX_LENGTH = 66;
|
|
20
22
|
export declare const prefixedChildKey: (prefix: HexString, key: HexString) => string;
|
|
21
23
|
export declare const isPrefixedChildKey: (key: HexString) => boolean;
|
|
22
24
|
export declare const splitChildKey: (key: HexString) => never[] | [`0x${string}`, `0x${string}`];
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -9,6 +9,12 @@ function _export(target, all) {
|
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
11
|
_export(exports, {
|
|
12
|
+
CHILD_PREFIX_LENGTH: function() {
|
|
13
|
+
return CHILD_PREFIX_LENGTH;
|
|
14
|
+
},
|
|
15
|
+
PREFIX_LENGTH: function() {
|
|
16
|
+
return PREFIX_LENGTH;
|
|
17
|
+
},
|
|
12
18
|
compactHex: function() {
|
|
13
19
|
return compactHex;
|
|
14
20
|
},
|
|
@@ -111,15 +117,15 @@ function defer() {
|
|
|
111
117
|
// The difference is that child storage keys are prefixed with the child storage key
|
|
112
118
|
// :child_storage:default: as hex string
|
|
113
119
|
const DEFAULT_CHILD_STORAGE = '0x3a6368696c645f73746f726167653a64656661756c743a';
|
|
114
|
-
|
|
115
|
-
const
|
|
120
|
+
const CHILD_PREFIX_LENGTH = DEFAULT_CHILD_STORAGE.length + 64;
|
|
121
|
+
const PREFIX_LENGTH = 66;
|
|
116
122
|
const prefixedChildKey = (prefix, key)=>prefix + (0, _hex.hexStripPrefix)(key);
|
|
117
123
|
const isPrefixedChildKey = (key)=>key.startsWith(DEFAULT_CHILD_STORAGE);
|
|
118
124
|
const splitChildKey = (key)=>{
|
|
119
125
|
if (!key.startsWith(DEFAULT_CHILD_STORAGE)) return [];
|
|
120
|
-
if (key.length <
|
|
121
|
-
const child = key.slice(0,
|
|
122
|
-
const rest = key.slice(
|
|
126
|
+
if (key.length < CHILD_PREFIX_LENGTH) return [];
|
|
127
|
+
const child = key.slice(0, CHILD_PREFIX_LENGTH);
|
|
128
|
+
const rest = key.slice(CHILD_PREFIX_LENGTH);
|
|
123
129
|
return [
|
|
124
130
|
child,
|
|
125
131
|
(0, _hex.hexAddPrefix)(rest)
|
|
@@ -2,17 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
get: all[name]
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
PREFIX_LENGTH: function() {
|
|
13
|
-
return PREFIX_LENGTH;
|
|
14
|
-
},
|
|
15
|
-
default: function() {
|
|
5
|
+
Object.defineProperty(exports, "default", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
16
8
|
return KeyCache;
|
|
17
9
|
}
|
|
18
10
|
});
|
|
@@ -35,21 +27,20 @@ function _interop_require_default(obj) {
|
|
|
35
27
|
default: obj
|
|
36
28
|
};
|
|
37
29
|
}
|
|
38
|
-
const PREFIX_LENGTH = 66;
|
|
39
30
|
class KeyCache {
|
|
40
31
|
feed(keys) {
|
|
41
|
-
const _keys = keys.filter((key)=>key.length >=
|
|
32
|
+
const _keys = keys.filter((key)=>key.length >= this.prefixLength);
|
|
42
33
|
if (_keys.length === 0) return;
|
|
43
|
-
const startKey = _keys[0].slice(
|
|
44
|
-
const endKey = _keys[_keys.length - 1].slice(
|
|
45
|
-
const grouped = _lodash.default.groupBy(_keys, (key)=>key.slice(0,
|
|
34
|
+
const startKey = _keys[0].slice(this.prefixLength);
|
|
35
|
+
const endKey = _keys[_keys.length - 1].slice(this.prefixLength);
|
|
36
|
+
const grouped = _lodash.default.groupBy(_keys, (key)=>key.slice(0, this.prefixLength));
|
|
46
37
|
for (const [prefix, keys] of Object.entries(grouped)){
|
|
47
38
|
const ranges = this.ranges.filter((range)=>range.prefix === prefix);
|
|
48
39
|
if (ranges.length === 0) {
|
|
49
40
|
// no existing range with prefix
|
|
50
41
|
this.ranges.push({
|
|
51
42
|
prefix,
|
|
52
|
-
keys: keys.map((i)=>i.slice(
|
|
43
|
+
keys: keys.map((i)=>i.slice(this.prefixLength))
|
|
53
44
|
});
|
|
54
45
|
continue;
|
|
55
46
|
}
|
|
@@ -58,14 +49,14 @@ class KeyCache {
|
|
|
58
49
|
const startPosition = _lodash.default.sortedIndex(range.keys, startKey);
|
|
59
50
|
if (startPosition >= 0 && range.keys[startPosition] === startKey) {
|
|
60
51
|
// found existing range with prefix
|
|
61
|
-
range.keys.splice(startPosition, keys.length, ...keys.map((i)=>i.slice(
|
|
52
|
+
range.keys.splice(startPosition, keys.length, ...keys.map((i)=>i.slice(this.prefixLength)));
|
|
62
53
|
merged = true;
|
|
63
54
|
break;
|
|
64
55
|
}
|
|
65
56
|
const endPosition = _lodash.default.sortedIndex(range.keys, endKey);
|
|
66
57
|
if (endPosition >= 0 && range.keys[endPosition] === endKey) {
|
|
67
58
|
// found existing range with prefix
|
|
68
|
-
range.keys.splice(0, endPosition + 1, ...keys.map((i)=>i.slice(
|
|
59
|
+
range.keys.splice(0, endPosition + 1, ...keys.map((i)=>i.slice(this.prefixLength)));
|
|
69
60
|
merged = true;
|
|
70
61
|
break;
|
|
71
62
|
}
|
|
@@ -74,17 +65,25 @@ class KeyCache {
|
|
|
74
65
|
if (!merged) {
|
|
75
66
|
this.ranges.push({
|
|
76
67
|
prefix,
|
|
77
|
-
keys: keys.map((i)=>i.slice(
|
|
68
|
+
keys: keys.map((i)=>i.slice(this.prefixLength))
|
|
78
69
|
});
|
|
79
70
|
}
|
|
80
71
|
}
|
|
81
72
|
// TODO: merge ranges if they overlap
|
|
82
73
|
}
|
|
83
74
|
async next(startKey) {
|
|
84
|
-
if (startKey.length <
|
|
85
|
-
const prefix = startKey.slice(0,
|
|
86
|
-
const key = startKey.slice(
|
|
75
|
+
if (startKey.length < this.prefixLength) return;
|
|
76
|
+
const prefix = startKey.slice(0, this.prefixLength);
|
|
77
|
+
const key = startKey.slice(this.prefixLength);
|
|
87
78
|
for (const range of this.ranges.filter((range)=>range.prefix === prefix)){
|
|
79
|
+
if (key.length === 0) {
|
|
80
|
+
// if key is empty then find the range with first key empty
|
|
81
|
+
if (range.keys[0] !== '') continue;
|
|
82
|
+
return [
|
|
83
|
+
prefix,
|
|
84
|
+
range.keys[1]
|
|
85
|
+
].join('');
|
|
86
|
+
}
|
|
88
87
|
const index = _lodash.default.sortedIndex(range.keys, key);
|
|
89
88
|
if (range.keys[index] !== key) continue;
|
|
90
89
|
const nextKey = range.keys[index + 1];
|
|
@@ -96,7 +95,10 @@ class KeyCache {
|
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
97
|
}
|
|
99
|
-
constructor(){
|
|
100
|
-
_define_property(this, "
|
|
98
|
+
constructor(prefixLength){
|
|
99
|
+
_define_property(this, "prefixLength", void 0);
|
|
100
|
+
_define_property(this, "ranges", void 0);
|
|
101
|
+
this.prefixLength = prefixLength;
|
|
102
|
+
this.ranges = [];
|
|
101
103
|
}
|
|
102
104
|
}
|
|
@@ -44,9 +44,8 @@ const _comlink = /*#__PURE__*/ _interop_require_wildcard(require("comlink"));
|
|
|
44
44
|
const _util = require("@polkadot/util");
|
|
45
45
|
const _utilcrypto = require("@polkadot/util-crypto");
|
|
46
46
|
const _lodash = /*#__PURE__*/ _interop_require_default(require("lodash"));
|
|
47
|
-
const _keycache = require("../utils/key-cache.js");
|
|
48
|
-
const _logger = require("../logger.js");
|
|
49
47
|
const _index = require("../utils/index.js");
|
|
48
|
+
const _logger = require("../logger.js");
|
|
50
49
|
function _interop_require_default(obj) {
|
|
51
50
|
return obj && obj.__esModule ? obj : {
|
|
52
51
|
default: obj
|
|
@@ -160,7 +159,7 @@ const taskHandler = (block)=>{
|
|
|
160
159
|
},
|
|
161
160
|
getNextKey: async function(prefix, key) {
|
|
162
161
|
const [nextKey] = await block.getKeysPaged({
|
|
163
|
-
prefix: prefix.length === 2 /** 0x */ ? key.slice(0,
|
|
162
|
+
prefix: prefix.length === 2 /** 0x */ ? key.slice(0, _index.PREFIX_LENGTH) : prefix,
|
|
164
163
|
pageSize: 1,
|
|
165
164
|
startKey: key
|
|
166
165
|
});
|
package/dist/cjs/xcm/index.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
import { Blockchain } from '../blockchain/index.js';
|
|
2
|
-
export declare const xcmLogger: import("pino").default.Logger<
|
|
3
|
-
level: string;
|
|
4
|
-
transport: {
|
|
5
|
-
target: string;
|
|
6
|
-
};
|
|
7
|
-
}>;
|
|
2
|
+
export declare const xcmLogger: import("pino").default.Logger<never>;
|
|
8
3
|
export declare const connectVertical: (relaychain: Blockchain, parachain: Blockchain) => Promise<void>;
|
|
9
4
|
export declare const connectParachains: (parachains: Blockchain[]) => Promise<void>;
|
package/dist/esm/api.d.ts
CHANGED
|
@@ -50,6 +50,7 @@ export declare class Api {
|
|
|
50
50
|
getBlock(hash?: string): Promise<SignedBlock | null>;
|
|
51
51
|
getStorage(key: string, hash?: string): Promise<`0x${string}` | null>;
|
|
52
52
|
getKeysPaged(prefix: string, pageSize: number, startKey: string, hash?: string): Promise<string[]>;
|
|
53
|
+
getStorageBatch(prefix: HexString, keys: HexString[], hash?: HexString): Promise<[`0x${string}`, `0x${string}` | null][]>;
|
|
53
54
|
subscribeRemoteNewHeads(cb: ProviderInterfaceCallback): Promise<string | number>;
|
|
54
55
|
subscribeRemoteFinalizedHeads(cb: ProviderInterfaceCallback): Promise<string | number>;
|
|
55
56
|
}
|
package/dist/esm/api.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { prefixedChildKey, splitChildKey, stripChildPrefix } from './utils/index.js';
|
|
2
|
+
import _ from 'lodash';
|
|
2
3
|
/**
|
|
3
4
|
* API class. Calls provider to get on-chain data.
|
|
4
5
|
* Either `endpoint` or `genesis` porvider must be provided.
|
|
@@ -119,6 +120,26 @@ import { prefixedChildKey, splitChildKey, stripChildPrefix } from './utils/index
|
|
|
119
120
|
return this.#provider.send('state_getKeysPaged', params, !!hash);
|
|
120
121
|
}
|
|
121
122
|
}
|
|
123
|
+
async getStorageBatch(prefix, keys, hash) {
|
|
124
|
+
const [child] = splitChildKey(prefix);
|
|
125
|
+
if (child) {
|
|
126
|
+
// child storage key, use childstate_getStorageEntries
|
|
127
|
+
// strip child prefix from keys
|
|
128
|
+
const params = [
|
|
129
|
+
child,
|
|
130
|
+
keys.map((key)=>stripChildPrefix(key))
|
|
131
|
+
];
|
|
132
|
+
if (hash) params.push(hash);
|
|
133
|
+
return this.#provider.send('childstate_getStorageEntries', params, !!hash).then((values)=>_.zip(keys, values));
|
|
134
|
+
} else {
|
|
135
|
+
// main storage key, use state_getStorageAt
|
|
136
|
+
const params = [
|
|
137
|
+
keys
|
|
138
|
+
];
|
|
139
|
+
if (hash) params.push(hash);
|
|
140
|
+
return this.#provider.send('state_queryStorageAt', params, !!hash).then((result)=>result[0]?.['changes'] || []);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
122
143
|
async subscribeRemoteNewHeads(cb) {
|
|
123
144
|
if (!this.#provider.hasSubscriptions) {
|
|
124
145
|
throw new Error('subscribeRemoteNewHeads only works with subscriptions');
|
|
@@ -129,12 +129,10 @@ import { getRuntimeVersion, runTask, taskHandler } from '../wasm-executor/index.
|
|
|
129
129
|
/**
|
|
130
130
|
* Get paged storage keys.
|
|
131
131
|
*/ async getKeysPaged(options) {
|
|
132
|
-
const layer = new StorageLayer(this.storage);
|
|
133
|
-
await layer.fold();
|
|
134
132
|
const prefix = options.prefix ?? '0x';
|
|
135
133
|
const startKey = options.startKey ?? '0x';
|
|
136
134
|
const pageSize = options.pageSize;
|
|
137
|
-
return
|
|
135
|
+
return this.storage.getKeysPaged(prefix, pageSize, startKey);
|
|
138
136
|
}
|
|
139
137
|
/**
|
|
140
138
|
* Push a layer to the storage stack.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
+
import { CHILD_PREFIX_LENGTH, PREFIX_LENGTH, isPrefixedChildKey } from '../utils/index.js';
|
|
2
3
|
import { defaultLogger } from '../logger.js';
|
|
3
|
-
import KeyCache
|
|
4
|
+
import KeyCache from '../utils/key-cache.js';
|
|
4
5
|
const logger = defaultLogger.child({
|
|
5
6
|
name: 'layer'
|
|
6
7
|
});
|
|
@@ -14,7 +15,8 @@ export class RemoteStorageLayer {
|
|
|
14
15
|
#api;
|
|
15
16
|
#at;
|
|
16
17
|
#db;
|
|
17
|
-
#keyCache = new KeyCache();
|
|
18
|
+
#keyCache = new KeyCache(PREFIX_LENGTH);
|
|
19
|
+
#defaultChildKeyCache = new KeyCache(CHILD_PREFIX_LENGTH);
|
|
18
20
|
constructor(api, at, db){
|
|
19
21
|
this.#api = api;
|
|
20
22
|
this.#at = at;
|
|
@@ -47,14 +49,16 @@ export class RemoteStorageLayer {
|
|
|
47
49
|
pageSize,
|
|
48
50
|
startKey
|
|
49
51
|
}, 'RemoteStorageLayer getKeysPaged');
|
|
52
|
+
const isChild = isPrefixedChildKey(prefix);
|
|
53
|
+
const minPrefixLen = isChild ? CHILD_PREFIX_LENGTH : PREFIX_LENGTH;
|
|
50
54
|
// can't handle keyCache without prefix
|
|
51
|
-
if (prefix.length <
|
|
55
|
+
if (prefix.length < minPrefixLen || startKey.length < minPrefixLen) {
|
|
52
56
|
return this.#api.getKeysPaged(prefix, pageSize, startKey, this.#at);
|
|
53
57
|
}
|
|
54
58
|
let batchComplete = false;
|
|
55
59
|
const keysPaged = [];
|
|
56
60
|
while(keysPaged.length < pageSize){
|
|
57
|
-
const nextKey = await this.#keyCache.next(startKey);
|
|
61
|
+
const nextKey = isChild ? await this.#defaultChildKeyCache.next(startKey) : await this.#keyCache.next(startKey);
|
|
58
62
|
if (nextKey) {
|
|
59
63
|
keysPaged.push(nextKey);
|
|
60
64
|
startKey = nextKey;
|
|
@@ -69,14 +73,29 @@ export class RemoteStorageLayer {
|
|
|
69
73
|
batchComplete = batch.length < BATCH_SIZE;
|
|
70
74
|
// feed the key cache
|
|
71
75
|
if (batch.length > 0) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
if (isChild) {
|
|
77
|
+
this.#defaultChildKeyCache.feed([
|
|
78
|
+
startKey,
|
|
79
|
+
...batch
|
|
80
|
+
]);
|
|
81
|
+
} else {
|
|
82
|
+
this.#keyCache.feed([
|
|
83
|
+
startKey,
|
|
84
|
+
...batch
|
|
85
|
+
]);
|
|
86
|
+
}
|
|
76
87
|
}
|
|
77
88
|
if (batch.length === 0) {
|
|
78
89
|
break;
|
|
79
90
|
}
|
|
91
|
+
if (this.#db) {
|
|
92
|
+
// batch fetch storage values and save to db, they may be used later
|
|
93
|
+
this.#api.getStorageBatch(prefix, batch, this.#at).then((storage)=>{
|
|
94
|
+
for (const [key, value] of storage){
|
|
95
|
+
this.#db.saveStorage(this.#at, key, value);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
80
99
|
}
|
|
81
100
|
return keysPaged;
|
|
82
101
|
}
|
|
@@ -169,30 +188,105 @@ export class StorageLayer {
|
|
|
169
188
|
}
|
|
170
189
|
}
|
|
171
190
|
async getKeysPaged(prefix, pageSize, startKey) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
191
|
+
let parentFetchComplete = false;
|
|
192
|
+
const parentFetchKeys = async (batchSize, startKey)=>{
|
|
193
|
+
if (!this.#deletedPrefix.some((dp)=>startKey.startsWith(dp))) {
|
|
194
|
+
const newKeys = [];
|
|
195
|
+
while(newKeys.length < batchSize){
|
|
196
|
+
const remote = await this.#parent?.getKeysPaged(prefix, batchSize, startKey) ?? [];
|
|
197
|
+
if (remote.length) {
|
|
198
|
+
startKey = remote[remote.length - 1];
|
|
199
|
+
}
|
|
200
|
+
for (const key of remote){
|
|
201
|
+
if (this.#store.get(key) === "Deleted") {
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (this.#deletedPrefix.some((dp)=>key.startsWith(dp))) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
newKeys.push(key);
|
|
208
|
+
}
|
|
209
|
+
if (remote.length < batchSize) {
|
|
210
|
+
parentFetchComplete = true;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
177
213
|
}
|
|
178
|
-
|
|
179
|
-
|
|
214
|
+
return newKeys;
|
|
215
|
+
} else {
|
|
216
|
+
parentFetchComplete = true;
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
const res = [];
|
|
221
|
+
const foundNextKey = (key)=>{
|
|
222
|
+
// make sure keys are unique
|
|
223
|
+
if (!res.includes(key)) {
|
|
224
|
+
res.push(key);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
const iterLocalKeys = (prefix, startKey, includeFirst, endKey)=>{
|
|
228
|
+
let idx = this.#keys.findIndex((x)=>x.startsWith(startKey));
|
|
229
|
+
if (this.#keys[idx] !== startKey) {
|
|
230
|
+
idx = this.#keys.findIndex((x)=>x.startsWith(prefix) && x > startKey);
|
|
231
|
+
const key = this.#keys[idx];
|
|
232
|
+
if (key) {
|
|
233
|
+
if (endKey && key >= endKey) {
|
|
234
|
+
return startKey;
|
|
235
|
+
}
|
|
236
|
+
foundNextKey(key);
|
|
237
|
+
++idx;
|
|
180
238
|
}
|
|
181
|
-
this.#addKey(key);
|
|
182
239
|
}
|
|
240
|
+
if (idx !== -1) {
|
|
241
|
+
if (includeFirst) {
|
|
242
|
+
const key = this.#keys[idx];
|
|
243
|
+
if (key) {
|
|
244
|
+
foundNextKey(key);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
while(res.length < pageSize){
|
|
248
|
+
++idx;
|
|
249
|
+
const key = this.#keys[idx];
|
|
250
|
+
if (!key || !key.startsWith(prefix)) {
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
if (endKey && key >= endKey) {
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
foundNextKey(key);
|
|
257
|
+
}
|
|
258
|
+
return _.last(res) ?? startKey;
|
|
259
|
+
}
|
|
260
|
+
return startKey;
|
|
261
|
+
};
|
|
262
|
+
if (prefix !== startKey && this.#keys.find((x)=>x === startKey)) {
|
|
263
|
+
startKey = iterLocalKeys(prefix, startKey, false);
|
|
183
264
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
265
|
+
// then iterate the parent keys
|
|
266
|
+
let keys = await parentFetchKeys(pageSize - res.length, startKey);
|
|
267
|
+
if (keys.length) {
|
|
268
|
+
let idx = 0;
|
|
269
|
+
while(res.length < pageSize){
|
|
270
|
+
const key = keys[idx];
|
|
271
|
+
if (!key || !key.startsWith(prefix)) {
|
|
272
|
+
if (parentFetchComplete) {
|
|
273
|
+
break;
|
|
274
|
+
} else {
|
|
275
|
+
keys = await parentFetchKeys(pageSize - res.length, _.last(keys));
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const keyPosition = _.sortedIndex(this.#keys, key);
|
|
280
|
+
const localParentKey = this.#keys[keyPosition - 1];
|
|
281
|
+
if (localParentKey < key) {
|
|
282
|
+
startKey = iterLocalKeys(prefix, startKey, false, key);
|
|
283
|
+
}
|
|
284
|
+
foundNextKey(key);
|
|
285
|
+
++idx;
|
|
193
286
|
}
|
|
194
|
-
|
|
195
|
-
|
|
287
|
+
}
|
|
288
|
+
if (res.length < pageSize) {
|
|
289
|
+
iterLocalKeys(prefix, startKey, prefix === startKey);
|
|
196
290
|
}
|
|
197
291
|
return res;
|
|
198
292
|
}
|
package/dist/esm/logger.d.ts
CHANGED
|
@@ -1,14 +1,4 @@
|
|
|
1
1
|
import { pino } from 'pino';
|
|
2
|
-
export declare const pinoLogger: import("pino").Logger<
|
|
3
|
-
|
|
4
|
-
transport: {
|
|
5
|
-
target: string;
|
|
6
|
-
};
|
|
7
|
-
}>;
|
|
8
|
-
export declare const defaultLogger: pino.Logger<{
|
|
9
|
-
level: string;
|
|
10
|
-
transport: {
|
|
11
|
-
target: string;
|
|
12
|
-
};
|
|
13
|
-
}>;
|
|
2
|
+
export declare const pinoLogger: import("pino").Logger<never>;
|
|
3
|
+
export declare const defaultLogger: pino.Logger<never>;
|
|
14
4
|
export declare const truncate: (val: any) => any;
|
package/dist/esm/rpc/shared.d.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { Blockchain } from '../blockchain/index.js';
|
|
2
|
-
export declare const logger: import("pino").default.Logger<
|
|
3
|
-
level: string;
|
|
4
|
-
transport: {
|
|
5
|
-
target: string;
|
|
6
|
-
};
|
|
7
|
-
}>;
|
|
2
|
+
export declare const logger: import("pino").default.Logger<never>;
|
|
8
3
|
export declare class ResponseError extends Error {
|
|
9
4
|
code: number;
|
|
10
5
|
constructor(code: number, message: string);
|
|
@@ -17,6 +17,8 @@ export type Deferred<T> = {
|
|
|
17
17
|
promise: Promise<T>;
|
|
18
18
|
};
|
|
19
19
|
export declare function defer<T>(): Deferred<T>;
|
|
20
|
+
export declare const CHILD_PREFIX_LENGTH: number;
|
|
21
|
+
export declare const PREFIX_LENGTH = 66;
|
|
20
22
|
export declare const prefixedChildKey: (prefix: HexString, key: HexString) => string;
|
|
21
23
|
export declare const isPrefixedChildKey: (key: HexString) => boolean;
|
|
22
24
|
export declare const splitChildKey: (key: HexString) => never[] | [`0x${string}`, `0x${string}`];
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -57,7 +57,9 @@ export function defer() {
|
|
|
57
57
|
// :child_storage:default: as hex string
|
|
58
58
|
const DEFAULT_CHILD_STORAGE = '0x3a6368696c645f73746f726167653a64656661756c743a';
|
|
59
59
|
// length of the child storage key
|
|
60
|
-
const
|
|
60
|
+
export const CHILD_PREFIX_LENGTH = DEFAULT_CHILD_STORAGE.length + 64;
|
|
61
|
+
// 0x + 32 module + 32 method
|
|
62
|
+
export const PREFIX_LENGTH = 66;
|
|
61
63
|
// returns a key that is prefixed with the child storage key
|
|
62
64
|
export const prefixedChildKey = (prefix, key)=>prefix + hexStripPrefix(key);
|
|
63
65
|
// returns true if the key is a child storage key
|
|
@@ -65,9 +67,9 @@ export const isPrefixedChildKey = (key)=>key.startsWith(DEFAULT_CHILD_STORAGE);
|
|
|
65
67
|
// returns a key that is split into the child storage key and the rest
|
|
66
68
|
export const splitChildKey = (key)=>{
|
|
67
69
|
if (!key.startsWith(DEFAULT_CHILD_STORAGE)) return [];
|
|
68
|
-
if (key.length <
|
|
69
|
-
const child = key.slice(0,
|
|
70
|
-
const rest = key.slice(
|
|
70
|
+
if (key.length < CHILD_PREFIX_LENGTH) return [];
|
|
71
|
+
const child = key.slice(0, CHILD_PREFIX_LENGTH);
|
|
72
|
+
const rest = key.slice(CHILD_PREFIX_LENGTH);
|
|
71
73
|
return [
|
|
72
74
|
child,
|
|
73
75
|
hexAddPrefix(rest)
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
// 0x + 32 module + 32 method
|
|
3
|
-
export const PREFIX_LENGTH = 66;
|
|
4
2
|
export default class KeyCache {
|
|
5
|
-
|
|
3
|
+
prefixLength;
|
|
4
|
+
constructor(prefixLength){
|
|
5
|
+
this.prefixLength = prefixLength;
|
|
6
|
+
this.ranges = [];
|
|
7
|
+
}
|
|
8
|
+
ranges;
|
|
6
9
|
feed(keys) {
|
|
7
|
-
const _keys = keys.filter((key)=>key.length >=
|
|
10
|
+
const _keys = keys.filter((key)=>key.length >= this.prefixLength);
|
|
8
11
|
if (_keys.length === 0) return;
|
|
9
|
-
const startKey = _keys[0].slice(
|
|
10
|
-
const endKey = _keys[_keys.length - 1].slice(
|
|
11
|
-
const grouped = _.groupBy(_keys, (key)=>key.slice(0,
|
|
12
|
+
const startKey = _keys[0].slice(this.prefixLength);
|
|
13
|
+
const endKey = _keys[_keys.length - 1].slice(this.prefixLength);
|
|
14
|
+
const grouped = _.groupBy(_keys, (key)=>key.slice(0, this.prefixLength));
|
|
12
15
|
for (const [prefix, keys] of Object.entries(grouped)){
|
|
13
16
|
const ranges = this.ranges.filter((range)=>range.prefix === prefix);
|
|
14
17
|
if (ranges.length === 0) {
|
|
15
18
|
// no existing range with prefix
|
|
16
19
|
this.ranges.push({
|
|
17
20
|
prefix,
|
|
18
|
-
keys: keys.map((i)=>i.slice(
|
|
21
|
+
keys: keys.map((i)=>i.slice(this.prefixLength))
|
|
19
22
|
});
|
|
20
23
|
continue;
|
|
21
24
|
}
|
|
@@ -24,14 +27,14 @@ export default class KeyCache {
|
|
|
24
27
|
const startPosition = _.sortedIndex(range.keys, startKey);
|
|
25
28
|
if (startPosition >= 0 && range.keys[startPosition] === startKey) {
|
|
26
29
|
// found existing range with prefix
|
|
27
|
-
range.keys.splice(startPosition, keys.length, ...keys.map((i)=>i.slice(
|
|
30
|
+
range.keys.splice(startPosition, keys.length, ...keys.map((i)=>i.slice(this.prefixLength)));
|
|
28
31
|
merged = true;
|
|
29
32
|
break;
|
|
30
33
|
}
|
|
31
34
|
const endPosition = _.sortedIndex(range.keys, endKey);
|
|
32
35
|
if (endPosition >= 0 && range.keys[endPosition] === endKey) {
|
|
33
36
|
// found existing range with prefix
|
|
34
|
-
range.keys.splice(0, endPosition + 1, ...keys.map((i)=>i.slice(
|
|
37
|
+
range.keys.splice(0, endPosition + 1, ...keys.map((i)=>i.slice(this.prefixLength)));
|
|
35
38
|
merged = true;
|
|
36
39
|
break;
|
|
37
40
|
}
|
|
@@ -40,17 +43,25 @@ export default class KeyCache {
|
|
|
40
43
|
if (!merged) {
|
|
41
44
|
this.ranges.push({
|
|
42
45
|
prefix,
|
|
43
|
-
keys: keys.map((i)=>i.slice(
|
|
46
|
+
keys: keys.map((i)=>i.slice(this.prefixLength))
|
|
44
47
|
});
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
// TODO: merge ranges if they overlap
|
|
48
51
|
}
|
|
49
52
|
async next(startKey) {
|
|
50
|
-
if (startKey.length <
|
|
51
|
-
const prefix = startKey.slice(0,
|
|
52
|
-
const key = startKey.slice(
|
|
53
|
+
if (startKey.length < this.prefixLength) return;
|
|
54
|
+
const prefix = startKey.slice(0, this.prefixLength);
|
|
55
|
+
const key = startKey.slice(this.prefixLength);
|
|
53
56
|
for (const range of this.ranges.filter((range)=>range.prefix === prefix)){
|
|
57
|
+
if (key.length === 0) {
|
|
58
|
+
// if key is empty then find the range with first key empty
|
|
59
|
+
if (range.keys[0] !== '') continue;
|
|
60
|
+
return [
|
|
61
|
+
prefix,
|
|
62
|
+
range.keys[1]
|
|
63
|
+
].join('');
|
|
64
|
+
}
|
|
54
65
|
const index = _.sortedIndex(range.keys, key);
|
|
55
66
|
if (range.keys[index] !== key) continue;
|
|
56
67
|
const nextKey = range.keys[index + 1];
|
|
@@ -2,9 +2,8 @@ import * as Comlink from 'comlink';
|
|
|
2
2
|
import { hexToString, hexToU8a, u8aToBn } from '@polkadot/util';
|
|
3
3
|
import { randomAsHex } from '@polkadot/util-crypto';
|
|
4
4
|
import _ from 'lodash';
|
|
5
|
-
import { PREFIX_LENGTH } from '../utils/
|
|
5
|
+
import { PREFIX_LENGTH, stripChildPrefix } from '../utils/index.js';
|
|
6
6
|
import { defaultLogger, truncate } from '../logger.js';
|
|
7
|
-
import { stripChildPrefix } from '../utils/index.js';
|
|
8
7
|
const logger = defaultLogger.child({
|
|
9
8
|
name: 'executor'
|
|
10
9
|
});
|
package/dist/esm/xcm/index.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
import { Blockchain } from '../blockchain/index.js';
|
|
2
|
-
export declare const xcmLogger: import("pino").default.Logger<
|
|
3
|
-
level: string;
|
|
4
|
-
transport: {
|
|
5
|
-
target: string;
|
|
6
|
-
};
|
|
7
|
-
}>;
|
|
2
|
+
export declare const xcmLogger: import("pino").default.Logger<never>;
|
|
8
3
|
export declare const connectVertical: (relaychain: Blockchain, parachain: Blockchain) => Promise<void>;
|
|
9
4
|
export declare const connectParachains: (parachains: Blockchain[]) => Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acala-network/chopsticks-core",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.8-1",
|
|
4
4
|
"author": "Acala Developers <hello@acala.network>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -12,28 +12,28 @@
|
|
|
12
12
|
"docs:prep": "typedoc"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@acala-network/chopsticks-executor": "0.9.
|
|
16
|
-
"@polkadot/rpc-provider": "^10.
|
|
17
|
-
"@polkadot/types": "^10.
|
|
18
|
-
"@polkadot/types-codec": "^10.
|
|
19
|
-
"@polkadot/types-known": "^10.
|
|
20
|
-
"@polkadot/util": "^12.
|
|
21
|
-
"@polkadot/util-crypto": "^12.
|
|
15
|
+
"@acala-network/chopsticks-executor": "0.9.8-1",
|
|
16
|
+
"@polkadot/rpc-provider": "^10.11.2",
|
|
17
|
+
"@polkadot/types": "^10.11.2",
|
|
18
|
+
"@polkadot/types-codec": "^10.11.2",
|
|
19
|
+
"@polkadot/types-known": "^10.11.2",
|
|
20
|
+
"@polkadot/util": "^12.6.2",
|
|
21
|
+
"@polkadot/util-crypto": "^12.6.2",
|
|
22
22
|
"comlink": "^4.4.1",
|
|
23
23
|
"eventemitter3": "^5.0.1",
|
|
24
24
|
"lodash": "^4.17.21",
|
|
25
25
|
"lru-cache": "^10.1.0",
|
|
26
|
-
"pino": "^8.
|
|
27
|
-
"pino-pretty": "^10.
|
|
26
|
+
"pino": "^8.17.2",
|
|
27
|
+
"pino-pretty": "^10.3.1",
|
|
28
28
|
"rxjs": "^7.8.1",
|
|
29
29
|
"zod": "^3.22.4"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@swc/cli": "0.1.
|
|
33
|
-
"@swc/core": "^1.3.
|
|
32
|
+
"@swc/cli": "0.1.65",
|
|
33
|
+
"@swc/core": "^1.3.105",
|
|
34
34
|
"@types/lodash": "^4.14.202",
|
|
35
35
|
"typescript": "^5.3.3",
|
|
36
|
-
"vitest": "^1.
|
|
36
|
+
"vitest": "^1.2.1"
|
|
37
37
|
},
|
|
38
38
|
"files": [
|
|
39
39
|
"dist/esm/**",
|