@dedot/api 0.18.4 → 0.18.6
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/cjs/extrinsic/submittable/BaseSubmittableExtrinsic.js +5 -1
- package/cjs/json-rpc/group/ChainHead/ChainHead.js +34 -11
- package/extrinsic/submittable/BaseSubmittableExtrinsic.js +5 -1
- package/json-rpc/group/ChainHead/ChainHead.d.ts +0 -1
- package/json-rpc/group/ChainHead/ChainHead.js +33 -10
- package/package.json +9 -9
|
@@ -96,7 +96,11 @@ class BaseSubmittableExtrinsic extends codecs_1.Extrinsic {
|
|
|
96
96
|
deferFinalized()?.reject(e);
|
|
97
97
|
});
|
|
98
98
|
})
|
|
99
|
-
.catch(
|
|
99
|
+
.catch((e) => {
|
|
100
|
+
deferBestChainBlockIncluded()?.reject(e);
|
|
101
|
+
deferFinalized()?.reject(e);
|
|
102
|
+
deferTx.reject(e);
|
|
103
|
+
});
|
|
100
104
|
return deferTx.promise;
|
|
101
105
|
}
|
|
102
106
|
#normalizeOptions(partialOptions, callback) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ChainHead =
|
|
3
|
+
exports.ChainHead = void 0;
|
|
4
4
|
const codecs_1 = require("@dedot/codecs");
|
|
5
5
|
const utils_1 = require("@dedot/utils");
|
|
6
6
|
const JsonRpcGroup_js_1 = require("../JsonRpcGroup.js");
|
|
7
7
|
const BlockUsage_js_1 = require("./BlockUsage.js");
|
|
8
8
|
const error_js_1 = require("./error.js");
|
|
9
|
-
|
|
9
|
+
const MIN_FINALIZED_QUEUE_SIZE = 16; // finalized queue size
|
|
10
10
|
const CHAINHEAD_CACHE_CAPACITY = 256;
|
|
11
11
|
const CHAINHEAD_CACHE_TTL = 30_000; // 30 seconds
|
|
12
12
|
class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
@@ -25,6 +25,7 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
25
25
|
#blockUsage;
|
|
26
26
|
#cache;
|
|
27
27
|
#operationQueue;
|
|
28
|
+
#minQueueSize;
|
|
28
29
|
/**
|
|
29
30
|
* Archive instance used as fallback when ChainHead blocks are not pinned.
|
|
30
31
|
*
|
|
@@ -48,6 +49,7 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
48
49
|
this.#cache = new utils_1.LRUCache(CHAINHEAD_CACHE_CAPACITY, CHAINHEAD_CACHE_TTL);
|
|
49
50
|
// This helps us to not accidentally putting too much stress on the JSON-RPC server, especially smoldot/light-client
|
|
50
51
|
this.#operationQueue = new utils_1.ThrottleQueue(this.#__unsafe__isSmoldot() ? 25 : 250);
|
|
52
|
+
this.#minQueueSize = MIN_FINALIZED_QUEUE_SIZE;
|
|
51
53
|
}
|
|
52
54
|
/**
|
|
53
55
|
* Attach an Archive instance as fallback for operations that fail due to unpinned blocks.
|
|
@@ -140,6 +142,9 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
140
142
|
finalizedBlockHashes.push(finalizedBlockHash);
|
|
141
143
|
this.#subscriptionId = subscription.subscriptionId;
|
|
142
144
|
this.#finalizedQueue = finalizedBlockHashes;
|
|
145
|
+
if (finalizedBlockHashes.length > MIN_FINALIZED_QUEUE_SIZE) {
|
|
146
|
+
this.#minQueueSize = finalizedBlockHashes.length;
|
|
147
|
+
}
|
|
143
148
|
this.#finalizedRuntime = this.#extractRuntime(finalizedBlockRuntime);
|
|
144
149
|
(0, utils_1.assert)(this.#finalizedRuntime, 'Invalid finalized runtime');
|
|
145
150
|
this.#bestHash = this.#finalizedHash = finalizedBlockHashes.at(-1);
|
|
@@ -224,9 +229,9 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
224
229
|
const pinnedHashes = Object.keys(this.#pinnedBlocks);
|
|
225
230
|
const hashesToUnpin = new Set(prunedBlockHashes.filter((hash) => pinnedHashes.includes(hash)));
|
|
226
231
|
// Unpin the oldest finalized pinned blocks to maintain the queue size
|
|
227
|
-
if (this.#finalizedQueue.length >
|
|
232
|
+
if (this.#finalizedQueue.length > this.#minQueueSize) {
|
|
228
233
|
const finalizedQueue = this.#finalizedQueue.slice();
|
|
229
|
-
const numOfItemsToUnpin = finalizedQueue.length -
|
|
234
|
+
const numOfItemsToUnpin = finalizedQueue.length - this.#minQueueSize;
|
|
230
235
|
const queuedHashesToUnpin = finalizedQueue.splice(0, numOfItemsToUnpin);
|
|
231
236
|
queuedHashesToUnpin.forEach((hash) => {
|
|
232
237
|
// if the block is being used, we'll keep it pinned
|
|
@@ -553,9 +558,15 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
553
558
|
const resp = await this.send('body', this.#subscriptionId, hash);
|
|
554
559
|
return this.#awaitOperation(resp, hash);
|
|
555
560
|
};
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
561
|
+
try {
|
|
562
|
+
this.#blockUsage.use(atHash);
|
|
563
|
+
const resp = await this.#operationQueue.add(() => this.#performOperationWithRetry(bodyOperation, atHash));
|
|
564
|
+
this.#cache.set(cacheKey, resp);
|
|
565
|
+
return resp;
|
|
566
|
+
}
|
|
567
|
+
finally {
|
|
568
|
+
this.#blockUsage.release(atHash);
|
|
569
|
+
}
|
|
559
570
|
};
|
|
560
571
|
const fallback = async (archive, hash) => {
|
|
561
572
|
const result = await archive.body(hash);
|
|
@@ -593,9 +604,15 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
593
604
|
const resp = await this.send('call', this.#subscriptionId, hash, func, params);
|
|
594
605
|
return this.#awaitOperation(resp, hash);
|
|
595
606
|
};
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
607
|
+
try {
|
|
608
|
+
this.#blockUsage.use(atHash);
|
|
609
|
+
const resp = await this.#operationQueue.add(() => this.#performOperationWithRetry(callOperation, atHash));
|
|
610
|
+
this.#cache.set(cacheKey, resp);
|
|
611
|
+
return resp;
|
|
612
|
+
}
|
|
613
|
+
finally {
|
|
614
|
+
this.#blockUsage.release(atHash);
|
|
615
|
+
}
|
|
599
616
|
};
|
|
600
617
|
const fallback = (archive, hash) => archive.call(func, params, hash);
|
|
601
618
|
try {
|
|
@@ -687,7 +704,13 @@ class ChainHead extends JsonRpcGroup_js_1.JsonRpcGroup {
|
|
|
687
704
|
}
|
|
688
705
|
async #getStorage(items, childTrie, at) {
|
|
689
706
|
const operation = () => this.#getStorageOperation(items, childTrie, this.#ensurePinnedHash(at));
|
|
690
|
-
|
|
707
|
+
try {
|
|
708
|
+
this.#blockUsage.use(at);
|
|
709
|
+
return await this.#operationQueue.add(() => this.#performOperationWithRetry(operation, at));
|
|
710
|
+
}
|
|
711
|
+
finally {
|
|
712
|
+
this.#blockUsage.release(at);
|
|
713
|
+
}
|
|
691
714
|
}
|
|
692
715
|
async #getStorageOperation(items, childTrie, at) {
|
|
693
716
|
await this.#ensureFollowed();
|
|
@@ -93,7 +93,11 @@ export class BaseSubmittableExtrinsic extends Extrinsic {
|
|
|
93
93
|
deferFinalized()?.reject(e);
|
|
94
94
|
});
|
|
95
95
|
})
|
|
96
|
-
.catch(
|
|
96
|
+
.catch((e) => {
|
|
97
|
+
deferBestChainBlockIncluded()?.reject(e);
|
|
98
|
+
deferFinalized()?.reject(e);
|
|
99
|
+
deferTx.reject(e);
|
|
100
|
+
});
|
|
97
101
|
return deferTx.promise;
|
|
98
102
|
}
|
|
99
103
|
#normalizeOptions(partialOptions, callback) {
|
|
@@ -17,7 +17,6 @@ export type PinnedBlock = {
|
|
|
17
17
|
runtime?: ChainHeadRuntimeVersion;
|
|
18
18
|
};
|
|
19
19
|
export type ChainHeadEvent = 'newBlock' | 'bestBlock' | 'finalizedBlock' | 'bestChainChanged';
|
|
20
|
-
export declare const MIN_FINALIZED_QUEUE_SIZE = 10;
|
|
21
20
|
export declare class ChainHead extends JsonRpcGroup<ChainHeadEvent> {
|
|
22
21
|
#private;
|
|
23
22
|
constructor(client: IJsonRpcClient, options?: Partial<JsonRpcGroupOptions>);
|
|
@@ -3,7 +3,7 @@ import { assert, AsyncQueue, deferred, ensurePresence, noop, ThrottleQueue, wait
|
|
|
3
3
|
import { JsonRpcGroup } from '../JsonRpcGroup.js';
|
|
4
4
|
import { BlockUsage } from './BlockUsage.js';
|
|
5
5
|
import { ChainHeadBlockNotPinnedError, ChainHeadBlockPrunedError, ChainHeadError, ChainHeadLimitReachedError, ChainHeadOperationError, ChainHeadOperationInaccessibleError, ChainHeadStopError, RetryStrategy, } from './error.js';
|
|
6
|
-
|
|
6
|
+
const MIN_FINALIZED_QUEUE_SIZE = 16; // finalized queue size
|
|
7
7
|
const CHAINHEAD_CACHE_CAPACITY = 256;
|
|
8
8
|
const CHAINHEAD_CACHE_TTL = 30_000; // 30 seconds
|
|
9
9
|
export class ChainHead extends JsonRpcGroup {
|
|
@@ -22,6 +22,7 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
22
22
|
#blockUsage;
|
|
23
23
|
#cache;
|
|
24
24
|
#operationQueue;
|
|
25
|
+
#minQueueSize;
|
|
25
26
|
/**
|
|
26
27
|
* Archive instance used as fallback when ChainHead blocks are not pinned.
|
|
27
28
|
*
|
|
@@ -45,6 +46,7 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
45
46
|
this.#cache = new LRUCache(CHAINHEAD_CACHE_CAPACITY, CHAINHEAD_CACHE_TTL);
|
|
46
47
|
// This helps us to not accidentally putting too much stress on the JSON-RPC server, especially smoldot/light-client
|
|
47
48
|
this.#operationQueue = new ThrottleQueue(this.#__unsafe__isSmoldot() ? 25 : 250);
|
|
49
|
+
this.#minQueueSize = MIN_FINALIZED_QUEUE_SIZE;
|
|
48
50
|
}
|
|
49
51
|
/**
|
|
50
52
|
* Attach an Archive instance as fallback for operations that fail due to unpinned blocks.
|
|
@@ -137,6 +139,9 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
137
139
|
finalizedBlockHashes.push(finalizedBlockHash);
|
|
138
140
|
this.#subscriptionId = subscription.subscriptionId;
|
|
139
141
|
this.#finalizedQueue = finalizedBlockHashes;
|
|
142
|
+
if (finalizedBlockHashes.length > MIN_FINALIZED_QUEUE_SIZE) {
|
|
143
|
+
this.#minQueueSize = finalizedBlockHashes.length;
|
|
144
|
+
}
|
|
140
145
|
this.#finalizedRuntime = this.#extractRuntime(finalizedBlockRuntime);
|
|
141
146
|
assert(this.#finalizedRuntime, 'Invalid finalized runtime');
|
|
142
147
|
this.#bestHash = this.#finalizedHash = finalizedBlockHashes.at(-1);
|
|
@@ -221,9 +226,9 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
221
226
|
const pinnedHashes = Object.keys(this.#pinnedBlocks);
|
|
222
227
|
const hashesToUnpin = new Set(prunedBlockHashes.filter((hash) => pinnedHashes.includes(hash)));
|
|
223
228
|
// Unpin the oldest finalized pinned blocks to maintain the queue size
|
|
224
|
-
if (this.#finalizedQueue.length >
|
|
229
|
+
if (this.#finalizedQueue.length > this.#minQueueSize) {
|
|
225
230
|
const finalizedQueue = this.#finalizedQueue.slice();
|
|
226
|
-
const numOfItemsToUnpin = finalizedQueue.length -
|
|
231
|
+
const numOfItemsToUnpin = finalizedQueue.length - this.#minQueueSize;
|
|
227
232
|
const queuedHashesToUnpin = finalizedQueue.splice(0, numOfItemsToUnpin);
|
|
228
233
|
queuedHashesToUnpin.forEach((hash) => {
|
|
229
234
|
// if the block is being used, we'll keep it pinned
|
|
@@ -550,9 +555,15 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
550
555
|
const resp = await this.send('body', this.#subscriptionId, hash);
|
|
551
556
|
return this.#awaitOperation(resp, hash);
|
|
552
557
|
};
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
558
|
+
try {
|
|
559
|
+
this.#blockUsage.use(atHash);
|
|
560
|
+
const resp = await this.#operationQueue.add(() => this.#performOperationWithRetry(bodyOperation, atHash));
|
|
561
|
+
this.#cache.set(cacheKey, resp);
|
|
562
|
+
return resp;
|
|
563
|
+
}
|
|
564
|
+
finally {
|
|
565
|
+
this.#blockUsage.release(atHash);
|
|
566
|
+
}
|
|
556
567
|
};
|
|
557
568
|
const fallback = async (archive, hash) => {
|
|
558
569
|
const result = await archive.body(hash);
|
|
@@ -590,9 +601,15 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
590
601
|
const resp = await this.send('call', this.#subscriptionId, hash, func, params);
|
|
591
602
|
return this.#awaitOperation(resp, hash);
|
|
592
603
|
};
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
604
|
+
try {
|
|
605
|
+
this.#blockUsage.use(atHash);
|
|
606
|
+
const resp = await this.#operationQueue.add(() => this.#performOperationWithRetry(callOperation, atHash));
|
|
607
|
+
this.#cache.set(cacheKey, resp);
|
|
608
|
+
return resp;
|
|
609
|
+
}
|
|
610
|
+
finally {
|
|
611
|
+
this.#blockUsage.release(atHash);
|
|
612
|
+
}
|
|
596
613
|
};
|
|
597
614
|
const fallback = (archive, hash) => archive.call(func, params, hash);
|
|
598
615
|
try {
|
|
@@ -684,7 +701,13 @@ export class ChainHead extends JsonRpcGroup {
|
|
|
684
701
|
}
|
|
685
702
|
async #getStorage(items, childTrie, at) {
|
|
686
703
|
const operation = () => this.#getStorageOperation(items, childTrie, this.#ensurePinnedHash(at));
|
|
687
|
-
|
|
704
|
+
try {
|
|
705
|
+
this.#blockUsage.use(at);
|
|
706
|
+
return await this.#operationQueue.add(() => this.#performOperationWithRetry(operation, at));
|
|
707
|
+
}
|
|
708
|
+
finally {
|
|
709
|
+
this.#blockUsage.release(at);
|
|
710
|
+
}
|
|
688
711
|
}
|
|
689
712
|
async #getStorageOperation(items, childTrie, at) {
|
|
690
713
|
await this.#ensureFollowed();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dedot/api",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.6",
|
|
4
4
|
"description": "A delightful JavaScript/TypeScript client for Polkadot & Substrate",
|
|
5
5
|
"author": "Thang X. Vu <thang@dedot.dev>",
|
|
6
6
|
"homepage": "https://dedot.dev",
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"sideEffects": false,
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@dedot/codecs": "0.18.
|
|
17
|
-
"@dedot/providers": "0.18.
|
|
18
|
-
"@dedot/runtime-specs": "0.18.
|
|
19
|
-
"@dedot/shape": "0.18.
|
|
20
|
-
"@dedot/storage": "0.18.
|
|
21
|
-
"@dedot/types": "0.18.
|
|
22
|
-
"@dedot/utils": "0.18.
|
|
16
|
+
"@dedot/codecs": "0.18.6",
|
|
17
|
+
"@dedot/providers": "0.18.6",
|
|
18
|
+
"@dedot/runtime-specs": "0.18.6",
|
|
19
|
+
"@dedot/shape": "0.18.6",
|
|
20
|
+
"@dedot/storage": "0.18.6",
|
|
21
|
+
"@dedot/types": "0.18.6",
|
|
22
|
+
"@dedot/utils": "0.18.6"
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"build": "tsc --project tsconfig.build.json && tsc --project tsconfig.build.cjs.json",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"node": ">=18"
|
|
49
49
|
},
|
|
50
50
|
"license": "Apache-2.0",
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "2ff0200696aa2e42505d30369fe84b2416838791",
|
|
52
52
|
"module": "./index.js",
|
|
53
53
|
"types": "./index.d.ts"
|
|
54
54
|
}
|