@acala-network/chopsticks-core 1.5.0 → 1.5.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/blockchain/inherent/data-renewal.d.ts +6 -0
- package/dist/cjs/blockchain/inherent/data-renewal.js +29 -0
- package/dist/cjs/blockchain/inherent/index.d.ts +2 -1
- package/dist/cjs/blockchain/inherent/index.js +3 -1
- package/dist/cjs/blockchain/storage-layer.js +30 -13
- package/dist/esm/blockchain/inherent/data-renewal.d.ts +6 -0
- package/dist/esm/blockchain/inherent/data-renewal.js +19 -0
- package/dist/esm/blockchain/inherent/index.d.ts +2 -1
- package/dist/esm/blockchain/inherent/index.js +3 -1
- package/dist/esm/blockchain/storage-layer.js +28 -12
- package/package.json +2 -2
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HexString } from '@polkadot/util/types';
|
|
2
|
+
import type { Block } from '../block.js';
|
|
3
|
+
import type { InherentProvider } from './index.js';
|
|
4
|
+
export declare class ProcessPendingRenewals implements InherentProvider {
|
|
5
|
+
createInherents(newBlock: Block): Promise<HexString[]>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "ProcessPendingRenewals", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return ProcessPendingRenewals;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _types = require("@polkadot/types");
|
|
12
|
+
class ProcessPendingRenewals {
|
|
13
|
+
async createInherents(newBlock) {
|
|
14
|
+
const parent = await newBlock.parentBlock;
|
|
15
|
+
if (!parent) throw new Error('parent block not found');
|
|
16
|
+
const meta = await parent.meta;
|
|
17
|
+
if (!meta.tx.dataRenewal?.processPendingRenewals) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
// Bulletin's pallet-bulletin-data-renewal mandatory drain inherent.
|
|
21
|
+
// The pallet's on_finalize asserts PendingAutoRenewals was drained, so
|
|
22
|
+
// the inherent must be included in every block, matching the pallet's
|
|
23
|
+
// unconditional create_inherent.
|
|
24
|
+
const inherent = new _types.GenericExtrinsic(meta.registry, meta.tx.dataRenewal.processPendingRenewals());
|
|
25
|
+
return [
|
|
26
|
+
inherent.toHex()
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { HexString } from '@polkadot/util/types';
|
|
2
2
|
import type { Block } from '../block.js';
|
|
3
3
|
import type { BuildBlockParams } from '../txpool.js';
|
|
4
|
+
import { ProcessPendingRenewals } from './data-renewal.js';
|
|
4
5
|
import { ParaInherentEnter } from './para-enter.js';
|
|
5
6
|
import { SetBabeRandomness } from './parachain/babe-randomness.js';
|
|
6
7
|
import { SetNimbusAuthorInherent } from './parachain/nimbus-author-inherent.js';
|
|
@@ -10,4 +11,4 @@ import { SetTransactionStorageProof } from './transaction-storage.js';
|
|
|
10
11
|
export interface InherentProvider {
|
|
11
12
|
createInherents(newBlock: Block, params: BuildBlockParams): Promise<HexString[]>;
|
|
12
13
|
}
|
|
13
|
-
export declare const inherentProviders: (ParaInherentEnter | SetBabeRandomness | SetNimbusAuthorInherent | SetValidationData | SetTimestamp | SetTransactionStorageProof)[];
|
|
14
|
+
export declare const inherentProviders: (ProcessPendingRenewals | ParaInherentEnter | SetBabeRandomness | SetNimbusAuthorInherent | SetValidationData | SetTimestamp | SetTransactionStorageProof)[];
|
|
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "inherentProviders", {
|
|
|
8
8
|
return inherentProviders;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
const _datarenewal = require("./data-renewal.js");
|
|
11
12
|
const _paraenter = require("./para-enter.js");
|
|
12
13
|
const _baberandomness = require("./parachain/babe-randomness.js");
|
|
13
14
|
const _nimbusauthorinherent = require("./parachain/nimbus-author-inherent.js");
|
|
@@ -20,5 +21,6 @@ const inherentProviders = [
|
|
|
20
21
|
new _paraenter.ParaInherentEnter(),
|
|
21
22
|
new _nimbusauthorinherent.SetNimbusAuthorInherent(),
|
|
22
23
|
new _baberandomness.SetBabeRandomness(),
|
|
23
|
-
new _transactionstorage.SetTransactionStorageProof()
|
|
24
|
+
new _transactionstorage.SetTransactionStorageProof(),
|
|
25
|
+
new _datarenewal.ProcessPendingRenewals()
|
|
24
26
|
];
|
|
@@ -172,9 +172,22 @@ class RemoteStorageLayer {
|
|
|
172
172
|
}, 'RemoteStorageLayer getKeysPaged');
|
|
173
173
|
const isChild = (0, _index.isPrefixedChildKey)(prefix);
|
|
174
174
|
const minPrefixLen = isChild ? _index.CHILD_PREFIX_LENGTH : _index.PREFIX_LENGTH;
|
|
175
|
-
// KeyCache groups by the first `minPrefixLen` chars; it cannot correctly answer queries
|
|
176
|
-
//
|
|
177
|
-
|
|
175
|
+
// KeyCache groups by the first `minPrefixLen` chars; it cannot correctly answer queries whose PREFIX is
|
|
176
|
+
// off that grouping width, so those are proxied directly to upstream (a longer prefix would otherwise match
|
|
177
|
+
// on the truncated head and return keys that do not start with the requested prefix — smoldot's
|
|
178
|
+
// `clear_prefix` asserts `key.starts_with(prefix)`).
|
|
179
|
+
//
|
|
180
|
+
// `startKey` is a different matter: every CONTINUATION of a scan carries a full-length storage key by
|
|
181
|
+
// construction, and serving those from the cache is precisely what the cache is for. Bailing out on a long
|
|
182
|
+
// `startKey` makes each continuation page an upstream round-trip.
|
|
183
|
+
//
|
|
184
|
+
// But a long `startKey` is only cache-safe when it belongs to the SAME group as `prefix`. `KeyCache.next()`
|
|
185
|
+
// derives its range from the first `minPrefixLen` chars of the `startKey` alone and never checks the result
|
|
186
|
+
// against `prefix`, so a `startKey` from a different `minPrefixLen`-char group would be answered from that
|
|
187
|
+
// other group's range — returning a key that does not start with `prefix`. `!startKey.startsWith(prefix)`
|
|
188
|
+
// proxies those cross-group requests to upstream; genuine continuations (`startKey.startsWith(prefix)` by
|
|
189
|
+
// construction) still hit the cache. (Reported by @xlc on #1055.)
|
|
190
|
+
if (prefix.length !== minPrefixLen || startKey.length < minPrefixLen || !startKey.startsWith(prefix)) {
|
|
178
191
|
return _class_private_field_get(this, _api).getKeysPaged(prefix, pageSize, startKey, _class_private_field_get(this, _at));
|
|
179
192
|
}
|
|
180
193
|
const startKeyEqualsPrefix = startKey === prefix;
|
|
@@ -281,7 +294,7 @@ class RemoteStorageLayer {
|
|
|
281
294
|
_class_private_field_set(this, _db, db);
|
|
282
295
|
}
|
|
283
296
|
}
|
|
284
|
-
var _store = /*#__PURE__*/ new WeakMap(), _keys = /*#__PURE__*/ new WeakMap(), _deletedPrefix = /*#__PURE__*/ new WeakMap(), _parent = /*#__PURE__*/ new WeakMap(), _addKey = /*#__PURE__*/ new WeakSet(), _removeKey = /*#__PURE__*/ new WeakSet();
|
|
297
|
+
var _store = /*#__PURE__*/ new WeakMap(), _keys = /*#__PURE__*/ new WeakMap(), _deletedPrefix = /*#__PURE__*/ new WeakMap(), _parent = /*#__PURE__*/ new WeakMap(), _addKey = /*#__PURE__*/ new WeakSet(), _removeKey = /*#__PURE__*/ new WeakSet(), _cacheParentValue = /*#__PURE__*/ new WeakSet();
|
|
285
298
|
class StorageLayer {
|
|
286
299
|
deleted(key) {
|
|
287
300
|
if (_class_private_field_get(this, _store).has(key)) {
|
|
@@ -303,9 +316,9 @@ class StorageLayer {
|
|
|
303
316
|
return "Deleted";
|
|
304
317
|
}
|
|
305
318
|
if (_class_private_field_get(this, _parent)) {
|
|
306
|
-
const val = _class_private_field_get(this, _parent).get(key, false);
|
|
319
|
+
const val = await _class_private_field_get(this, _parent).get(key, false);
|
|
307
320
|
if (cache) {
|
|
308
|
-
|
|
321
|
+
_class_private_method_get(this, _cacheParentValue, cacheParentValue).call(this, key, val);
|
|
309
322
|
}
|
|
310
323
|
return val;
|
|
311
324
|
}
|
|
@@ -314,9 +327,9 @@ class StorageLayer {
|
|
|
314
327
|
async getMany(keys, cache) {
|
|
315
328
|
const result = [];
|
|
316
329
|
const pending = [];
|
|
317
|
-
|
|
330
|
+
keys.forEach((key, idx)=>{
|
|
318
331
|
if (_class_private_field_get(this, _store).has(key)) {
|
|
319
|
-
result[idx] =
|
|
332
|
+
result[idx] = _class_private_field_get(this, _store).get(key);
|
|
320
333
|
} else if (_class_private_field_get(this, _deletedPrefix).some((dp)=>key.startsWith(dp))) {
|
|
321
334
|
result[idx] = "Deleted";
|
|
322
335
|
} else {
|
|
@@ -330,12 +343,11 @@ class StorageLayer {
|
|
|
330
343
|
const vals = await _class_private_field_get(this, _parent).getMany(pending.map((p)=>p.key), false);
|
|
331
344
|
vals.forEach((val, idx)=>{
|
|
332
345
|
if (cache) {
|
|
333
|
-
|
|
346
|
+
_class_private_method_get(this, _cacheParentValue, cacheParentValue).call(this, pending[idx].key, val);
|
|
334
347
|
}
|
|
335
348
|
result[pending[idx].idx] = val;
|
|
336
349
|
});
|
|
337
350
|
}
|
|
338
|
-
await Promise.all(preloadedPromises);
|
|
339
351
|
return result;
|
|
340
352
|
}
|
|
341
353
|
set(key, value) {
|
|
@@ -346,7 +358,7 @@ class StorageLayer {
|
|
|
346
358
|
break;
|
|
347
359
|
case "DeletedPrefix":
|
|
348
360
|
_class_private_field_get(this, _deletedPrefix).push(key);
|
|
349
|
-
for (const k of _class_private_field_get(this,
|
|
361
|
+
for (const k of _class_private_field_get(this, _store).keys()){
|
|
350
362
|
if (k.startsWith(key)) {
|
|
351
363
|
_class_private_field_get(this, _store).set(k, "Deleted");
|
|
352
364
|
_class_private_method_get(this, _removeKey, removeKey).call(this, k);
|
|
@@ -409,8 +421,7 @@ class StorageLayer {
|
|
|
409
421
|
/**
|
|
410
422
|
* Merge the storage layer into the given object, can be used to get sotrage diff.
|
|
411
423
|
*/ async mergeInto(into) {
|
|
412
|
-
for (const [key,
|
|
413
|
-
const value = await maybeValue;
|
|
424
|
+
for (const [key, value] of _class_private_field_get(this, _store)){
|
|
414
425
|
if (value === "Deleted") {
|
|
415
426
|
into[key] = null;
|
|
416
427
|
} else {
|
|
@@ -421,6 +432,7 @@ class StorageLayer {
|
|
|
421
432
|
constructor(parent){
|
|
422
433
|
_class_private_method_init(this, _addKey);
|
|
423
434
|
_class_private_method_init(this, _removeKey);
|
|
435
|
+
_class_private_method_init(this, _cacheParentValue);
|
|
424
436
|
_class_private_field_init(this, _store, {
|
|
425
437
|
writable: true,
|
|
426
438
|
value: new Map()
|
|
@@ -455,3 +467,8 @@ function removeKey(key) {
|
|
|
455
467
|
_class_private_field_get(this, _keys).splice(idx, 1);
|
|
456
468
|
}
|
|
457
469
|
}
|
|
470
|
+
function cacheParentValue(key, value) {
|
|
471
|
+
if (!_class_private_field_get(this, _store).has(key) && !_class_private_field_get(this, _deletedPrefix).some((dp)=>key.startsWith(dp))) {
|
|
472
|
+
_class_private_field_get(this, _store).set(key, value);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HexString } from '@polkadot/util/types';
|
|
2
|
+
import type { Block } from '../block.js';
|
|
3
|
+
import type { InherentProvider } from './index.js';
|
|
4
|
+
export declare class ProcessPendingRenewals implements InherentProvider {
|
|
5
|
+
createInherents(newBlock: Block): Promise<HexString[]>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { GenericExtrinsic } from '@polkadot/types';
|
|
2
|
+
export class ProcessPendingRenewals {
|
|
3
|
+
async createInherents(newBlock) {
|
|
4
|
+
const parent = await newBlock.parentBlock;
|
|
5
|
+
if (!parent) throw new Error('parent block not found');
|
|
6
|
+
const meta = await parent.meta;
|
|
7
|
+
if (!meta.tx.dataRenewal?.processPendingRenewals) {
|
|
8
|
+
return [];
|
|
9
|
+
}
|
|
10
|
+
// Bulletin's pallet-bulletin-data-renewal mandatory drain inherent.
|
|
11
|
+
// The pallet's on_finalize asserts PendingAutoRenewals was drained, so
|
|
12
|
+
// the inherent must be included in every block, matching the pallet's
|
|
13
|
+
// unconditional create_inherent.
|
|
14
|
+
const inherent = new GenericExtrinsic(meta.registry, meta.tx.dataRenewal.processPendingRenewals());
|
|
15
|
+
return [
|
|
16
|
+
inherent.toHex()
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { HexString } from '@polkadot/util/types';
|
|
2
2
|
import type { Block } from '../block.js';
|
|
3
3
|
import type { BuildBlockParams } from '../txpool.js';
|
|
4
|
+
import { ProcessPendingRenewals } from './data-renewal.js';
|
|
4
5
|
import { ParaInherentEnter } from './para-enter.js';
|
|
5
6
|
import { SetBabeRandomness } from './parachain/babe-randomness.js';
|
|
6
7
|
import { SetNimbusAuthorInherent } from './parachain/nimbus-author-inherent.js';
|
|
@@ -10,4 +11,4 @@ import { SetTransactionStorageProof } from './transaction-storage.js';
|
|
|
10
11
|
export interface InherentProvider {
|
|
11
12
|
createInherents(newBlock: Block, params: BuildBlockParams): Promise<HexString[]>;
|
|
12
13
|
}
|
|
13
|
-
export declare const inherentProviders: (ParaInherentEnter | SetBabeRandomness | SetNimbusAuthorInherent | SetValidationData | SetTimestamp | SetTransactionStorageProof)[];
|
|
14
|
+
export declare const inherentProviders: (ProcessPendingRenewals | ParaInherentEnter | SetBabeRandomness | SetNimbusAuthorInherent | SetValidationData | SetTimestamp | SetTransactionStorageProof)[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ProcessPendingRenewals } from './data-renewal.js';
|
|
1
2
|
import { ParaInherentEnter } from './para-enter.js';
|
|
2
3
|
import { SetBabeRandomness } from './parachain/babe-randomness.js';
|
|
3
4
|
import { SetNimbusAuthorInherent } from './parachain/nimbus-author-inherent.js';
|
|
@@ -10,5 +11,6 @@ export const inherentProviders = [
|
|
|
10
11
|
new ParaInherentEnter(),
|
|
11
12
|
new SetNimbusAuthorInherent(),
|
|
12
13
|
new SetBabeRandomness(),
|
|
13
|
-
new SetTransactionStorageProof()
|
|
14
|
+
new SetTransactionStorageProof(),
|
|
15
|
+
new ProcessPendingRenewals()
|
|
14
16
|
];
|
|
@@ -106,9 +106,22 @@ export class RemoteStorageLayer {
|
|
|
106
106
|
}, 'RemoteStorageLayer getKeysPaged');
|
|
107
107
|
const isChild = isPrefixedChildKey(prefix);
|
|
108
108
|
const minPrefixLen = isChild ? CHILD_PREFIX_LENGTH : PREFIX_LENGTH;
|
|
109
|
-
// KeyCache groups by the first `minPrefixLen` chars; it cannot correctly answer queries
|
|
110
|
-
//
|
|
111
|
-
|
|
109
|
+
// KeyCache groups by the first `minPrefixLen` chars; it cannot correctly answer queries whose PREFIX is
|
|
110
|
+
// off that grouping width, so those are proxied directly to upstream (a longer prefix would otherwise match
|
|
111
|
+
// on the truncated head and return keys that do not start with the requested prefix — smoldot's
|
|
112
|
+
// `clear_prefix` asserts `key.starts_with(prefix)`).
|
|
113
|
+
//
|
|
114
|
+
// `startKey` is a different matter: every CONTINUATION of a scan carries a full-length storage key by
|
|
115
|
+
// construction, and serving those from the cache is precisely what the cache is for. Bailing out on a long
|
|
116
|
+
// `startKey` makes each continuation page an upstream round-trip.
|
|
117
|
+
//
|
|
118
|
+
// But a long `startKey` is only cache-safe when it belongs to the SAME group as `prefix`. `KeyCache.next()`
|
|
119
|
+
// derives its range from the first `minPrefixLen` chars of the `startKey` alone and never checks the result
|
|
120
|
+
// against `prefix`, so a `startKey` from a different `minPrefixLen`-char group would be answered from that
|
|
121
|
+
// other group's range — returning a key that does not start with `prefix`. `!startKey.startsWith(prefix)`
|
|
122
|
+
// proxies those cross-group requests to upstream; genuine continuations (`startKey.startsWith(prefix)` by
|
|
123
|
+
// construction) still hit the cache. (Reported by @xlc on #1055.)
|
|
124
|
+
if (prefix.length !== minPrefixLen || startKey.length < minPrefixLen || !startKey.startsWith(prefix)) {
|
|
112
125
|
return this.#api.getKeysPaged(prefix, pageSize, startKey, this.#at);
|
|
113
126
|
}
|
|
114
127
|
const startKeyEqualsPrefix = startKey === prefix;
|
|
@@ -209,6 +222,11 @@ export class StorageLayer {
|
|
|
209
222
|
this.#keys.splice(idx, 1);
|
|
210
223
|
}
|
|
211
224
|
}
|
|
225
|
+
#cacheParentValue(key, value) {
|
|
226
|
+
if (!this.#store.has(key) && !this.#deletedPrefix.some((dp)=>key.startsWith(dp))) {
|
|
227
|
+
this.#store.set(key, value);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
212
230
|
deleted(key) {
|
|
213
231
|
if (this.#store.has(key)) {
|
|
214
232
|
return this.#store.get(key) === "Deleted";
|
|
@@ -229,9 +247,9 @@ export class StorageLayer {
|
|
|
229
247
|
return "Deleted";
|
|
230
248
|
}
|
|
231
249
|
if (this.#parent) {
|
|
232
|
-
const val = this.#parent.get(key, false);
|
|
250
|
+
const val = await this.#parent.get(key, false);
|
|
233
251
|
if (cache) {
|
|
234
|
-
this.#
|
|
252
|
+
this.#cacheParentValue(key, val);
|
|
235
253
|
}
|
|
236
254
|
return val;
|
|
237
255
|
}
|
|
@@ -240,9 +258,9 @@ export class StorageLayer {
|
|
|
240
258
|
async getMany(keys, cache) {
|
|
241
259
|
const result = [];
|
|
242
260
|
const pending = [];
|
|
243
|
-
|
|
261
|
+
keys.forEach((key, idx)=>{
|
|
244
262
|
if (this.#store.has(key)) {
|
|
245
|
-
result[idx] =
|
|
263
|
+
result[idx] = this.#store.get(key);
|
|
246
264
|
} else if (this.#deletedPrefix.some((dp)=>key.startsWith(dp))) {
|
|
247
265
|
result[idx] = "Deleted";
|
|
248
266
|
} else {
|
|
@@ -256,12 +274,11 @@ export class StorageLayer {
|
|
|
256
274
|
const vals = await this.#parent.getMany(pending.map((p)=>p.key), false);
|
|
257
275
|
vals.forEach((val, idx)=>{
|
|
258
276
|
if (cache) {
|
|
259
|
-
this.#
|
|
277
|
+
this.#cacheParentValue(pending[idx].key, val);
|
|
260
278
|
}
|
|
261
279
|
result[pending[idx].idx] = val;
|
|
262
280
|
});
|
|
263
281
|
}
|
|
264
|
-
await Promise.all(preloadedPromises);
|
|
265
282
|
return result;
|
|
266
283
|
}
|
|
267
284
|
set(key, value) {
|
|
@@ -272,7 +289,7 @@ export class StorageLayer {
|
|
|
272
289
|
break;
|
|
273
290
|
case "DeletedPrefix":
|
|
274
291
|
this.#deletedPrefix.push(key);
|
|
275
|
-
for (const k of this.#keys){
|
|
292
|
+
for (const k of this.#store.keys()){
|
|
276
293
|
if (k.startsWith(key)) {
|
|
277
294
|
this.#store.set(k, "Deleted");
|
|
278
295
|
this.#removeKey(k);
|
|
@@ -335,8 +352,7 @@ export class StorageLayer {
|
|
|
335
352
|
/**
|
|
336
353
|
* Merge the storage layer into the given object, can be used to get sotrage diff.
|
|
337
354
|
*/ async mergeInto(into) {
|
|
338
|
-
for (const [key,
|
|
339
|
-
const value = await maybeValue;
|
|
355
|
+
for (const [key, value] of this.#store){
|
|
340
356
|
if (value === "Deleted") {
|
|
341
357
|
into[key] = null;
|
|
342
358
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acala-network/chopsticks-core",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"author": "Acala Developers <hello@acala.network>",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"depcheck": "npx depcheck"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@acala-network/chopsticks-executor": "1.5.
|
|
17
|
+
"@acala-network/chopsticks-executor": "1.5.1",
|
|
18
18
|
"@polkadot/rpc-provider": "^16.4.1",
|
|
19
19
|
"@polkadot/types": "^16.4.1",
|
|
20
20
|
"@polkadot/types-codec": "^16.4.1",
|