@helia/utils 2.3.5 → 2.4.0-f058fba8
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/index.min.js +1 -11
- package/dist/index.min.js.map +4 -4
- package/dist/src/abstract-session.d.ts +10 -4
- package/dist/src/abstract-session.d.ts.map +1 -1
- package/dist/src/abstract-session.js +68 -41
- package/dist/src/abstract-session.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/utils/networked-storage.d.ts +7 -57
- package/dist/src/utils/networked-storage.d.ts.map +1 -1
- package/dist/src/utils/networked-storage.js +15 -372
- package/dist/src/utils/networked-storage.js.map +1 -1
- package/dist/src/utils/session-storage.d.ts +48 -0
- package/dist/src/utils/session-storage.d.ts.map +1 -0
- package/dist/src/utils/session-storage.js +148 -0
- package/dist/src/utils/session-storage.js.map +1 -0
- package/dist/src/utils/storage.d.ts +56 -0
- package/dist/src/utils/storage.d.ts.map +1 -0
- package/dist/src/utils/storage.js +225 -0
- package/dist/src/utils/storage.js.map +1 -0
- package/package.json +3 -3
- package/src/abstract-session.ts +98 -52
- package/src/index.ts +5 -6
- package/src/utils/networked-storage.ts +22 -461
- package/src/utils/session-storage.ts +175 -0
- package/src/utils/storage.ts +295 -0
- package/dist/typedoc-urls.json +0 -19
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { HasherLoader } from '@helia/interface';
|
|
2
|
+
import type { BlockBroker, Pair, DeleteManyBlocksProgressEvents, DeleteBlockProgressEvents, GetBlockProgressEvents, GetManyBlocksProgressEvents, PutManyBlocksProgressEvents, PutBlockProgressEvents, GetAllBlocksProgressEvents, GetOfflineOptions, BlockRetrievalOptions } from '@helia/interface/blocks';
|
|
3
|
+
import type { AbortOptions, ComponentLogger, Logger } from '@libp2p/interface';
|
|
4
|
+
import type { Blockstore, InputPair } from 'interface-blockstore';
|
|
5
|
+
import type { AwaitIterable } from 'interface-store';
|
|
6
|
+
import type { CID } from 'multiformats/cid';
|
|
7
|
+
import type { MultihashHasher } from 'multiformats/hashes/interface';
|
|
8
|
+
import type { ProgressEvent, ProgressOptions } from 'progress-events';
|
|
9
|
+
export interface StorageComponents<Broker extends BlockBroker<ProgressEvent<any, any>, ProgressEvent<any, any>>> {
|
|
10
|
+
blockstore: Blockstore;
|
|
11
|
+
logger: ComponentLogger;
|
|
12
|
+
blockBrokers: Broker[];
|
|
13
|
+
getHasher: HasherLoader;
|
|
14
|
+
}
|
|
15
|
+
export interface StorageInit {
|
|
16
|
+
maxIdentityHashDigestLength?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare class Storage<Broker extends BlockBroker<ProgressEvent<any, any>, ProgressEvent<any, any>>> implements Blockstore {
|
|
19
|
+
protected readonly child: Blockstore;
|
|
20
|
+
protected readonly getHasher: HasherLoader;
|
|
21
|
+
protected log: Logger;
|
|
22
|
+
protected readonly logger: ComponentLogger;
|
|
23
|
+
protected readonly blockBrokers: Broker[];
|
|
24
|
+
/**
|
|
25
|
+
* Create a new BlockStorage
|
|
26
|
+
*/
|
|
27
|
+
constructor(components: StorageComponents<Broker>, init?: StorageInit);
|
|
28
|
+
/**
|
|
29
|
+
* Put a block to the underlying datastore
|
|
30
|
+
*/
|
|
31
|
+
put(cid: CID, block: Uint8Array, options?: AbortOptions & ProgressOptions<PutBlockProgressEvents>): Promise<CID>;
|
|
32
|
+
/**
|
|
33
|
+
* Put a multiple blocks to the underlying datastore
|
|
34
|
+
*/
|
|
35
|
+
putMany(blocks: AwaitIterable<InputPair>, options?: AbortOptions & ProgressOptions<PutManyBlocksProgressEvents>): AsyncGenerator<CID>;
|
|
36
|
+
/**
|
|
37
|
+
* Get a block by cid
|
|
38
|
+
*/
|
|
39
|
+
get(cid: CID, options?: GetOfflineOptions & AbortOptions & ProgressOptions<GetBlockProgressEvents>): AsyncGenerator<Uint8Array>;
|
|
40
|
+
/**
|
|
41
|
+
* Get multiple blocks back from an (async) iterable of cids
|
|
42
|
+
*/
|
|
43
|
+
getMany(cids: AwaitIterable<CID>, options?: GetOfflineOptions & AbortOptions & ProgressOptions<GetManyBlocksProgressEvents>): AsyncGenerator<Pair>;
|
|
44
|
+
/**
|
|
45
|
+
* Delete a block from the blockstore
|
|
46
|
+
*/
|
|
47
|
+
delete(cid: CID, options?: AbortOptions & ProgressOptions<DeleteBlockProgressEvents>): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Delete multiple blocks from the blockstore
|
|
50
|
+
*/
|
|
51
|
+
deleteMany(cids: AwaitIterable<CID>, options?: AbortOptions & ProgressOptions<DeleteManyBlocksProgressEvents>): AsyncGenerator<CID>;
|
|
52
|
+
has(cid: CID, options?: AbortOptions): Promise<boolean>;
|
|
53
|
+
getAll(options?: AbortOptions & ProgressOptions<GetAllBlocksProgressEvents>): AsyncGenerator<Pair>;
|
|
54
|
+
}
|
|
55
|
+
export declare const getCidBlockVerifierFunction: (cid: CID, hasher: MultihashHasher) => Required<BlockRetrievalOptions>["validateFn"];
|
|
56
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/utils/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { InvalidMultihashError, InvalidParametersError, setMaxListeners } from '@libp2p/interface';
|
|
2
|
+
import { anySignal } from 'any-signal';
|
|
3
|
+
import { IdentityBlockstore } from 'blockstore-core/identity';
|
|
4
|
+
import filter from 'it-filter';
|
|
5
|
+
import forEach from 'it-foreach';
|
|
6
|
+
import { CustomProgressEvent } from 'progress-events';
|
|
7
|
+
import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
|
|
8
|
+
import { BlockNotFoundWhileOfflineError, InvalidConfigurationError, LoadBlockFailedError } from "../errors.js";
|
|
9
|
+
import { isPromise } from './is-promise.js';
|
|
10
|
+
const DEFAULT_MAX_IDENTITY_HASH_DIGEST_LENGTH = 128;
|
|
11
|
+
export class Storage {
|
|
12
|
+
child;
|
|
13
|
+
getHasher;
|
|
14
|
+
log;
|
|
15
|
+
logger;
|
|
16
|
+
blockBrokers;
|
|
17
|
+
/**
|
|
18
|
+
* Create a new BlockStorage
|
|
19
|
+
*/
|
|
20
|
+
constructor(components, init = {}) {
|
|
21
|
+
this.log = components.logger.forComponent('helia:networked-storage');
|
|
22
|
+
this.logger = components.logger;
|
|
23
|
+
this.blockBrokers = components.blockBrokers;
|
|
24
|
+
this.child = new IdentityBlockstore(components.blockstore, {
|
|
25
|
+
maxDigestLength: init.maxIdentityHashDigestLength ?? DEFAULT_MAX_IDENTITY_HASH_DIGEST_LENGTH
|
|
26
|
+
});
|
|
27
|
+
this.getHasher = components.getHasher;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Put a block to the underlying datastore
|
|
31
|
+
*/
|
|
32
|
+
async put(cid, block, options = {}) {
|
|
33
|
+
if (await this.child.has(cid, options)) {
|
|
34
|
+
options.onProgress?.(new CustomProgressEvent('blocks:put:duplicate', cid));
|
|
35
|
+
return cid;
|
|
36
|
+
}
|
|
37
|
+
options.onProgress?.(new CustomProgressEvent('blocks:put:providers:notify', cid));
|
|
38
|
+
await Promise.all(this.blockBrokers.map(async (broker) => broker.announce?.(cid, options)));
|
|
39
|
+
options.onProgress?.(new CustomProgressEvent('blocks:put:blockstore:put', cid));
|
|
40
|
+
return this.child.put(cid, block, options);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Put a multiple blocks to the underlying datastore
|
|
44
|
+
*/
|
|
45
|
+
async *putMany(blocks, options = {}) {
|
|
46
|
+
const missingBlocks = filter(blocks, async ({ cid }) => {
|
|
47
|
+
const has = await this.child.has(cid, options);
|
|
48
|
+
if (has) {
|
|
49
|
+
options.onProgress?.(new CustomProgressEvent('blocks:put-many:duplicate', cid));
|
|
50
|
+
}
|
|
51
|
+
return !has;
|
|
52
|
+
});
|
|
53
|
+
const notifyEach = forEach(missingBlocks, async ({ cid }) => {
|
|
54
|
+
options.onProgress?.(new CustomProgressEvent('blocks:put-many:providers:notify', cid));
|
|
55
|
+
await Promise.all(this.blockBrokers.map(async (broker) => broker.announce?.(cid, options)));
|
|
56
|
+
});
|
|
57
|
+
options.onProgress?.(new CustomProgressEvent('blocks:put-many:blockstore:put-many'));
|
|
58
|
+
yield* this.child.putMany(notifyEach, options);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get a block by cid
|
|
62
|
+
*/
|
|
63
|
+
async *get(cid, options = {}) {
|
|
64
|
+
const has = await this.child.has(cid, options);
|
|
65
|
+
const offline = options.offline === true;
|
|
66
|
+
if (!has) {
|
|
67
|
+
if (offline) {
|
|
68
|
+
throw new BlockNotFoundWhileOfflineError('The block was present in the blockstore and the node is running offline so cannot fetch it');
|
|
69
|
+
}
|
|
70
|
+
const hasher = await this.getHasher(cid.multihash.code);
|
|
71
|
+
options?.signal?.throwIfAborted();
|
|
72
|
+
// we do not have the block locally, get it from a block provider
|
|
73
|
+
options.onProgress?.(new CustomProgressEvent('blocks:get:providers:get', cid));
|
|
74
|
+
const block = await raceBlockRetrievers(cid, this.blockBrokers, hasher, {
|
|
75
|
+
...options,
|
|
76
|
+
log: this.log
|
|
77
|
+
});
|
|
78
|
+
options.onProgress?.(new CustomProgressEvent('blocks:get:blockstore:put', cid));
|
|
79
|
+
await this.child.put(cid, block, options);
|
|
80
|
+
// notify other block providers of the new block
|
|
81
|
+
options.onProgress?.(new CustomProgressEvent('blocks:get:providers:notify', cid));
|
|
82
|
+
await Promise.all(this.blockBrokers.map(async (broker) => broker.announce?.(cid, options)));
|
|
83
|
+
yield block;
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
options.onProgress?.(new CustomProgressEvent('blocks:get:blockstore:get', cid));
|
|
87
|
+
yield* this.child.get(cid, options);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get multiple blocks back from an (async) iterable of cids
|
|
91
|
+
*/
|
|
92
|
+
async *getMany(cids, options = {}) {
|
|
93
|
+
options.onProgress?.(new CustomProgressEvent('blocks:get-many:blockstore:get-many'));
|
|
94
|
+
yield* this.child.getMany(forEach(cids, async (cid) => {
|
|
95
|
+
const has = await this.child.has(cid, options);
|
|
96
|
+
const offline = options.offline === true;
|
|
97
|
+
if (!has) {
|
|
98
|
+
if (offline) {
|
|
99
|
+
throw new BlockNotFoundWhileOfflineError('The block was present in the blockstore and the node is running offline so cannot fetch it');
|
|
100
|
+
}
|
|
101
|
+
const hasher = await this.getHasher(cid.multihash.code);
|
|
102
|
+
options?.signal?.throwIfAborted();
|
|
103
|
+
// we do not have the block locally, get it from a block provider
|
|
104
|
+
options.onProgress?.(new CustomProgressEvent('blocks:get-many:providers:get', cid));
|
|
105
|
+
const block = await raceBlockRetrievers(cid, this.blockBrokers, hasher, {
|
|
106
|
+
...options,
|
|
107
|
+
log: this.log
|
|
108
|
+
});
|
|
109
|
+
options.onProgress?.(new CustomProgressEvent('blocks:get-many:blockstore:put', cid));
|
|
110
|
+
await this.child.put(cid, block, options);
|
|
111
|
+
// notify other block providers of the new block
|
|
112
|
+
options.onProgress?.(new CustomProgressEvent('blocks:get-many:providers:notify', cid));
|
|
113
|
+
await Promise.all(this.blockBrokers.map(async (broker) => broker.announce?.(cid, options)));
|
|
114
|
+
}
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Delete a block from the blockstore
|
|
119
|
+
*/
|
|
120
|
+
async delete(cid, options = {}) {
|
|
121
|
+
options.onProgress?.(new CustomProgressEvent('blocks:delete:blockstore:delete', cid));
|
|
122
|
+
await this.child.delete(cid, options);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Delete multiple blocks from the blockstore
|
|
126
|
+
*/
|
|
127
|
+
async *deleteMany(cids, options = {}) {
|
|
128
|
+
options.onProgress?.(new CustomProgressEvent('blocks:delete-many:blockstore:delete-many'));
|
|
129
|
+
yield* this.child.deleteMany((async function* () {
|
|
130
|
+
for await (const cid of cids) {
|
|
131
|
+
yield cid;
|
|
132
|
+
}
|
|
133
|
+
}()), options);
|
|
134
|
+
}
|
|
135
|
+
async has(cid, options = {}) {
|
|
136
|
+
return this.child.has(cid, options);
|
|
137
|
+
}
|
|
138
|
+
async *getAll(options = {}) {
|
|
139
|
+
options.onProgress?.(new CustomProgressEvent('blocks:get-all:blockstore:get-many'));
|
|
140
|
+
yield* this.child.getAll(options);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Race block providers cancelling any pending requests once the block has been
|
|
145
|
+
* found.
|
|
146
|
+
*/
|
|
147
|
+
async function raceBlockRetrievers(cid, blockBrokers, hasher, options) {
|
|
148
|
+
const validateFn = getCidBlockVerifierFunction(cid, hasher);
|
|
149
|
+
const controller = new AbortController();
|
|
150
|
+
const signal = anySignal([controller.signal, options.signal]);
|
|
151
|
+
setMaxListeners(Infinity, controller.signal, signal);
|
|
152
|
+
const retrievers = [];
|
|
153
|
+
for (const broker of blockBrokers) {
|
|
154
|
+
if (isRetrievingBlockBroker(broker)) {
|
|
155
|
+
retrievers.push(broker);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (retrievers.length === 0) {
|
|
159
|
+
throw new InvalidConfigurationError(`No block brokers capable of retrieving blocks are configured, the CID ${cid} cannot be fetched from the network`);
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
return await Promise.any(retrievers
|
|
163
|
+
.map(async (retriever) => {
|
|
164
|
+
try {
|
|
165
|
+
let blocksWereValidated = false;
|
|
166
|
+
const block = await retriever.retrieve(cid, {
|
|
167
|
+
...options,
|
|
168
|
+
signal,
|
|
169
|
+
validateFn: async (block) => {
|
|
170
|
+
await validateFn(block);
|
|
171
|
+
options.signal?.throwIfAborted();
|
|
172
|
+
blocksWereValidated = true;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
if (!blocksWereValidated) {
|
|
176
|
+
// the blockBroker either did not throw an error when attempting to validate the block
|
|
177
|
+
// or did not call the validateFn at all. We should validate the block ourselves
|
|
178
|
+
await validateFn(block);
|
|
179
|
+
options.signal?.throwIfAborted();
|
|
180
|
+
}
|
|
181
|
+
return block;
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
options.log.error('could not retrieve verified block for %c from %s - %e', cid, retriever.name, err);
|
|
185
|
+
throw err;
|
|
186
|
+
}
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
throw new LoadBlockFailedError(err.errors, `Failed to load block for ${cid}`);
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
// we have the block from the fastest block retriever, abort any still
|
|
194
|
+
// in-flight retrieve attempts
|
|
195
|
+
controller.abort();
|
|
196
|
+
signal.clear();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function isRetrievingBlockBroker(broker) {
|
|
200
|
+
return typeof broker.retrieve === 'function';
|
|
201
|
+
}
|
|
202
|
+
export const getCidBlockVerifierFunction = (cid, hasher) => {
|
|
203
|
+
if (hasher == null) {
|
|
204
|
+
throw new InvalidParametersError(`No hasher configured for multihash code 0x${cid.multihash.code.toString(16)}, please configure one. You can look up which hash this is at https://github.com/multiformats/multicodec/blob/master/table.csv`);
|
|
205
|
+
}
|
|
206
|
+
return async (block) => {
|
|
207
|
+
// verify block
|
|
208
|
+
let hash;
|
|
209
|
+
const res = hasher.digest(block, {
|
|
210
|
+
// support truncated hashes where they are truncated
|
|
211
|
+
truncate: cid.multihash.digest.byteLength
|
|
212
|
+
});
|
|
213
|
+
if (isPromise(res)) {
|
|
214
|
+
hash = await res;
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
hash = res;
|
|
218
|
+
}
|
|
219
|
+
if (!uint8ArrayEquals(hash.digest, cid.multihash.digest)) {
|
|
220
|
+
// if a hash mismatch occurs for a TrustlessGatewayBlockBroker, we should try another gateway
|
|
221
|
+
throw new InvalidMultihashError('Hash of downloaded block did not match multihash from passed CID');
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
};
|
|
225
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/utils/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAClG,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,MAAM,MAAM,WAAW,CAAA;AAC9B,OAAO,OAAO,MAAM,YAAY,CAAA;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAC9G,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAqB3C,MAAM,uCAAuC,GAAG,GAAG,CAAA;AAEnD,MAAM,OAAO,OAAO;IACC,KAAK,CAAY;IACjB,SAAS,CAAc;IAChC,GAAG,CAAQ;IACF,MAAM,CAAiB;IACvB,YAAY,CAAU;IAEzC;;OAEG;IACH,YAAa,UAAqC,EAAE,OAAoB,EAAE;QACxE,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,yBAAyB,CAAC,CAAA;QACpE,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAA;QAC/B,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,YAAY,CAAA;QAC3C,IAAI,CAAC,KAAK,GAAG,IAAI,kBAAkB,CAAC,UAAU,CAAC,UAAU,EAAE;YACzD,eAAe,EAAE,IAAI,CAAC,2BAA2B,IAAI,uCAAuC;SAC7F,CAAC,CAAA;QACF,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,SAAS,CAAA;IACvC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAE,GAAQ,EAAE,KAAiB,EAAE,UAAkE,EAAE;QAC1G,IAAI,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,sBAAsB,EAAE,GAAG,CAAC,CAAC,CAAA;YAC/E,OAAO,GAAG,CAAA;QACZ,CAAC;QAED,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,6BAA6B,EAAE,GAAG,CAAC,CAAC,CAAA;QAEtF,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CACvE,CAAA;QAED,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,2BAA2B,EAAE,GAAG,CAAC,CAAC,CAAA;QAEpF,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,CAAE,OAAO,CAAE,MAAgC,EAAE,UAAuE,EAAE;QAC1H,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,EAAoB,EAAE;YACvE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAE9C,IAAI,GAAG,EAAE,CAAC;gBACR,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,2BAA2B,EAAE,GAAG,CAAC,CAAC,CAAA;YACtF,CAAC;YAED,OAAO,CAAC,GAAG,CAAA;QACb,CAAC,CAAC,CAAA;QAEF,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,EAAiB,EAAE;YACzE,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,kCAAkC,EAAE,GAAG,CAAC,CAAC,CAAA;YAC3F,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CACvE,CAAA;QACH,CAAC,CAAC,CAAA;QAEF,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAC,qCAAqC,CAAC,CAAC,CAAA;QACpF,KAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IACjD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,CAAE,GAAG,CAAE,GAAQ,EAAE,UAAsF,EAAE;QAC7G,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,KAAK,IAAI,CAAA;QAExC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,IAAI,8BAA8B,CAAC,4FAA4F,CAAC,CAAA;YACxI,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YACvD,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;YAEjC,iEAAiE;YAEjE,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,0BAA0B,EAAE,GAAG,CAAC,CAAC,CAAA;YACnF,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE;gBACtE,GAAG,OAAO;gBACV,GAAG,EAAE,IAAI,CAAC,GAAG;aACd,CAAC,CAAA;YACF,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,2BAA2B,EAAE,GAAG,CAAC,CAAC,CAAA;YACpF,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;YAEzC,gDAAgD;YAChD,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,6BAA6B,EAAE,GAAG,CAAC,CAAC,CAAA;YACtF,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CACvE,CAAA;YAED,MAAM,KAAK,CAAA;YACX,OAAM;QACR,CAAC;QAED,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,2BAA2B,EAAE,GAAG,CAAC,CAAC,CAAA;QAEpF,KAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACtC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,CAAE,OAAO,CAAE,IAAwB,EAAE,UAA2F,EAAE;QACtI,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAC,qCAAqC,CAAC,CAAC,CAAA;QAEpF,KAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAiB,EAAE;YACpE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,KAAK,IAAI,CAAA;YAExC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,IAAI,8BAA8B,CAAC,4FAA4F,CAAC,CAAA;gBACxI,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;gBACvD,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;gBAEjC,iEAAiE;gBACjE,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,+BAA+B,EAAE,GAAG,CAAC,CAAC,CAAA;gBACxF,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE;oBACtE,GAAG,OAAO;oBACV,GAAG,EAAE,IAAI,CAAC,GAAG;iBACd,CAAC,CAAA;gBACF,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,gCAAgC,EAAE,GAAG,CAAC,CAAC,CAAA;gBACzF,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;gBAEzC,gDAAgD;gBAChD,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,kCAAkC,EAAE,GAAG,CAAC,CAAC,CAAA;gBAC3F,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CACvE,CAAA;YACH,CAAC;QACH,CAAC,CAAC,CAAC,CAAA;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAE,GAAQ,EAAE,UAAqE,EAAE;QAC7F,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAM,iCAAiC,EAAE,GAAG,CAAC,CAAC,CAAA;QAE1F,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACvC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,CAAE,UAAU,CAAE,IAAwB,EAAE,UAA0E,EAAE;QACxH,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAC,2CAA2C,CAAC,CAAC,CAAA;QAC1F,KAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,SAAU,CAAC;YAC7C,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBAC7B,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAA;IAChB,CAAC;IAED,KAAK,CAAC,GAAG,CAAE,GAAQ,EAAE,UAAwB,EAAE;QAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACrC,CAAC;IAED,KAAK,CAAC,CAAE,MAAM,CAAE,UAAsE,EAAE;QACtF,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,mBAAmB,CAAC,oCAAoC,CAAC,CAAC,CAAA;QACnF,KAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACpC,CAAC;CACF;AAED;;;GAGG;AACH,KAAK,UAAU,mBAAmB,CAAE,GAAQ,EAAE,YAA2B,EAAE,MAAuB,EAAE,OAAqC;IACvI,MAAM,UAAU,GAAG,2BAA2B,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;IAE3D,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;IACxC,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAC7D,eAAe,CAAC,QAAQ,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEpD,MAAM,UAAU,GAA4D,EAAE,CAAA;IAE9E,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;QAClC,IAAI,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACzB,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,yBAAyB,CAAC,yEAAyE,GAAG,qCAAqC,CAAC,CAAA;IACxJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,GAAG,CACtB,UAAU;aACP,GAAG,CAAC,KAAK,EAAC,SAAS,EAAC,EAAE;YACrB,IAAI,CAAC;gBACH,IAAI,mBAAmB,GAAG,KAAK,CAAA;gBAC/B,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE;oBAC1C,GAAG,OAAO;oBACV,MAAM;oBACN,UAAU,EAAE,KAAK,EAAE,KAAiB,EAAiB,EAAE;wBACrD,MAAM,UAAU,CAAC,KAAK,CAAC,CAAA;wBACvB,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,CAAA;wBAChC,mBAAmB,GAAG,IAAI,CAAA;oBAC5B,CAAC;iBACF,CAAC,CAAA;gBAEF,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBACzB,sFAAsF;oBACtF,gFAAgF;oBAChF,MAAM,UAAU,CAAC,KAAK,CAAC,CAAA;oBACvB,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,CAAA;gBAClC,CAAC;gBAED,OAAO,KAAK,CAAA;YACd,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,uDAAuD,EAAE,GAAG,EAAE,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;gBACpG,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC,CAAC,CACL,CAAA;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,oBAAoB,CAAC,GAAG,CAAC,MAAM,EAAE,4BAA4B,GAAG,EAAE,CAAC,CAAA;IAC/E,CAAC;YAAS,CAAC;QACT,sEAAsE;QACtE,8BAA8B;QAC9B,UAAU,CAAC,KAAK,EAAE,CAAA;QAClB,MAAM,CAAC,KAAK,EAAE,CAAA;IAChB,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAE,MAAmB;IACnD,OAAO,OAAO,MAAM,CAAC,QAAQ,KAAK,UAAU,CAAA;AAC9C,CAAC;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,GAAQ,EAAE,MAAuB,EAAiD,EAAE;IAC9H,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,sBAAsB,CAAC,6CAA6C,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,gIAAgI,CAAC,CAAA;IAChP,CAAC;IAED,OAAO,KAAK,EAAE,KAAiB,EAAiB,EAAE;QAChD,eAAe;QACf,IAAI,IAA6B,CAAA;QACjC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE;YAC/B,oDAAoD;YACpD,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU;SAC1C,CAAC,CAAA;QAEF,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,GAAG,MAAM,GAAG,CAAA;QAClB,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,GAAG,CAAA;QACZ,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,6FAA6F;YAC7F,MAAM,IAAI,qBAAqB,CAAC,kEAAkE,CAAC,CAAA;QACrG,CAAC;IACH,CAAC,CAAA;AACH,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helia/utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0-f058fba8",
|
|
4
4
|
"description": "Shared code that implements the Helia API",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/ipfs/helia/tree/main/packages/utils#readme",
|
|
@@ -47,13 +47,12 @@
|
|
|
47
47
|
"test:electron-main": "aegir test -t electron-main"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@helia/interface": "
|
|
50
|
+
"@helia/interface": "6.1.0-f058fba8",
|
|
51
51
|
"@ipld/dag-cbor": "^9.2.5",
|
|
52
52
|
"@ipld/dag-json": "^10.2.5",
|
|
53
53
|
"@ipld/dag-pb": "^4.1.5",
|
|
54
54
|
"@libp2p/interface": "^3.1.0",
|
|
55
55
|
"@libp2p/keychain": "^6.0.5",
|
|
56
|
-
"@libp2p/logger": "^6.0.5",
|
|
57
56
|
"@libp2p/utils": "^7.0.5",
|
|
58
57
|
"@multiformats/dns": "^1.0.9",
|
|
59
58
|
"@multiformats/multiaddr": "^13.0.1",
|
|
@@ -78,6 +77,7 @@
|
|
|
78
77
|
},
|
|
79
78
|
"devDependencies": {
|
|
80
79
|
"@libp2p/crypto": "^5.1.12",
|
|
80
|
+
"@libp2p/logger": "^6.0.5",
|
|
81
81
|
"@libp2p/peer-id": "^6.0.3",
|
|
82
82
|
"@types/sinon": "^21.0.0",
|
|
83
83
|
"aegir": "^47.0.22",
|
package/src/abstract-session.ts
CHANGED
|
@@ -27,12 +27,14 @@ export interface BlockstoreSessionEvents<Provider> {
|
|
|
27
27
|
interface Request {
|
|
28
28
|
promise: Promise<Uint8Array>
|
|
29
29
|
observers: number
|
|
30
|
+
queryFilter: Filter
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents extends ProgressEvent> extends TypedEventEmitter<BlockstoreSessionEvents<Provider>> implements BlockBroker<RetrieveBlockProgressEvents> {
|
|
34
|
+
public abstract name: string
|
|
33
35
|
private initialPeerSearchComplete?: Promise<void>
|
|
34
36
|
private readonly requests: Map<string, Request>
|
|
35
|
-
private readonly
|
|
37
|
+
private readonly logName: string
|
|
36
38
|
protected log: Logger
|
|
37
39
|
protected logger: ComponentLogger
|
|
38
40
|
private readonly minProviders: number
|
|
@@ -45,15 +47,15 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
45
47
|
super()
|
|
46
48
|
|
|
47
49
|
setMaxListeners(Infinity, this)
|
|
48
|
-
this.
|
|
50
|
+
this.logName = init.name
|
|
49
51
|
this.logger = components.logger
|
|
50
|
-
this.log = components.logger.forComponent(this.
|
|
52
|
+
this.log = components.logger.forComponent(this.logName)
|
|
51
53
|
this.requests = new Map()
|
|
52
54
|
this.minProviders = init.minProviders ?? DEFAULT_SESSION_MIN_PROVIDERS
|
|
53
55
|
this.maxProviders = init.maxProviders ?? DEFAULT_SESSION_MAX_PROVIDERS
|
|
54
56
|
this.providers = []
|
|
55
57
|
this.evictionFilter = createScalableCuckooFilter(this.maxProviders)
|
|
56
|
-
this.initialProviders = init.providers ?? []
|
|
58
|
+
this.initialProviders = [...(init.providers ?? [])]
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
async retrieve (cid: CID, options: BlockRetrievalOptions<RetrieveBlockProgressEvents> = {}): Promise<Uint8Array> {
|
|
@@ -70,41 +72,18 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
70
72
|
const deferred: DeferredPromise<Uint8Array> = pDefer()
|
|
71
73
|
const request = {
|
|
72
74
|
promise: deferred.promise,
|
|
73
|
-
observers: 1
|
|
75
|
+
observers: 1,
|
|
76
|
+
queryFilter: createScalableCuckooFilter(1024)
|
|
74
77
|
}
|
|
75
78
|
this.requests.set(cidStr, request)
|
|
76
79
|
|
|
77
|
-
if
|
|
78
|
-
|
|
80
|
+
// if this is the first time this session has been used
|
|
81
|
+
let first = false
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
try {
|
|
87
|
-
await raceSignal(this.initialPeerSearchComplete, options.signal)
|
|
88
|
-
|
|
89
|
-
if (first) {
|
|
90
|
-
this.log('found initial session peers for %c', cid)
|
|
91
|
-
}
|
|
92
|
-
} catch (err) {
|
|
93
|
-
if (first) {
|
|
94
|
-
this.log('failed to find initial session peers for %c - %e', cid, err)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
this.requests.delete(cidStr)
|
|
98
|
-
|
|
99
|
-
if (request.observers > 1) {
|
|
100
|
-
// only need to reject request if another context is now also waiting
|
|
101
|
-
// for the result - otherwise we can end up with an unhandled promise
|
|
102
|
-
// rejection
|
|
103
|
-
deferred.reject(err)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
throw err
|
|
107
|
-
}
|
|
83
|
+
if (this.initialPeerSearchComplete == null) {
|
|
84
|
+
first = true
|
|
85
|
+
this.log = this.logger.forComponent(`${this.logName}:${cid}`)
|
|
86
|
+
this.initialPeerSearchComplete = this.findProviders(cid, this.minProviders, options)
|
|
108
87
|
}
|
|
109
88
|
|
|
110
89
|
let foundBlock = false
|
|
@@ -166,6 +145,17 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
166
145
|
})
|
|
167
146
|
|
|
168
147
|
const peerAddedToSessionListener = (event: CustomEvent<Provider>): void => {
|
|
148
|
+
const filterKey = this.toFilterKey(event.detail)
|
|
149
|
+
|
|
150
|
+
if (request.queryFilter.has(filterKey)) {
|
|
151
|
+
return
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
request.queryFilter.add(filterKey)
|
|
155
|
+
|
|
156
|
+
// dispatch progress notification
|
|
157
|
+
this.emitFoundProviderProgressEvent(cid, event.detail, options)
|
|
158
|
+
|
|
169
159
|
queue.add(async () => {
|
|
170
160
|
return this.queryProvider(cid, event.detail, options)
|
|
171
161
|
}, {
|
|
@@ -185,14 +175,50 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
185
175
|
// add new session peers to query as they are discovered
|
|
186
176
|
this.addEventListener('provider', peerAddedToSessionListener)
|
|
187
177
|
|
|
178
|
+
if (first) {
|
|
179
|
+
try {
|
|
180
|
+
await raceSignal(this.initialPeerSearchComplete, options.signal)
|
|
181
|
+
|
|
182
|
+
if (first) {
|
|
183
|
+
this.log('found initial session peers for %c', cid)
|
|
184
|
+
}
|
|
185
|
+
} catch (err) {
|
|
186
|
+
if (first) {
|
|
187
|
+
this.log('failed to find initial session peers for %c - %e', cid, err)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
this.requests.delete(cidStr)
|
|
191
|
+
|
|
192
|
+
if (request.observers > 1) {
|
|
193
|
+
// only need to reject request if another context is now also waiting
|
|
194
|
+
// for the result - otherwise we can end up with an unhandled promise
|
|
195
|
+
// rejection
|
|
196
|
+
deferred.reject(err)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
throw err
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
188
203
|
// query each session peer directly
|
|
189
|
-
Promise.all(
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
204
|
+
Promise.all(
|
|
205
|
+
[...this.providers]
|
|
206
|
+
.filter(provider => {
|
|
207
|
+
const filterKey = this.toFilterKey(provider)
|
|
208
|
+
const has = request.queryFilter.has(filterKey)
|
|
209
|
+
|
|
210
|
+
if (!has) {
|
|
211
|
+
request.queryFilter.add(this.toFilterKey(provider))
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return !has
|
|
215
|
+
})
|
|
216
|
+
.map(async (provider) => {
|
|
217
|
+
return queue.add(async () => this.queryProvider(cid, provider, options), {
|
|
218
|
+
provider
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
)
|
|
196
222
|
.catch(err => {
|
|
197
223
|
if (options.signal?.aborted === true) {
|
|
198
224
|
// skip logging error if signal was aborted because abort can happen
|
|
@@ -221,7 +247,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
221
247
|
}
|
|
222
248
|
|
|
223
249
|
evict (provider: Provider): void {
|
|
224
|
-
this.evictionFilter.add(this.
|
|
250
|
+
this.evictionFilter.add(this.toFilterKey(provider))
|
|
225
251
|
const index = this.providers.findIndex(prov => this.equals(prov, provider))
|
|
226
252
|
|
|
227
253
|
if (index === -1) {
|
|
@@ -232,7 +258,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
232
258
|
}
|
|
233
259
|
|
|
234
260
|
isEvicted (provider: Provider): boolean {
|
|
235
|
-
return this.evictionFilter.has(this.
|
|
261
|
+
return this.evictionFilter.has(this.toFilterKey(provider))
|
|
236
262
|
}
|
|
237
263
|
|
|
238
264
|
hasProvider (provider: Provider): boolean {
|
|
@@ -249,7 +275,22 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
249
275
|
return false
|
|
250
276
|
}
|
|
251
277
|
|
|
252
|
-
|
|
278
|
+
async addPeer (peer: PeerId | Multiaddr | Multiaddr[], options?: AbortOptions): Promise<void> {
|
|
279
|
+
const provider = await this.convertToProvider(peer, 'manually-added', options)
|
|
280
|
+
|
|
281
|
+
if (provider == null || this.hasProvider(provider)) {
|
|
282
|
+
return
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
this.providers.push(provider)
|
|
286
|
+
|
|
287
|
+
// let the new peer join current queries
|
|
288
|
+
this.safeDispatchEvent('provider', {
|
|
289
|
+
detail: provider
|
|
290
|
+
})
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private async findProviders (cid: CID, count: number, options: BlockRetrievalOptions<RetrieveBlockProgressEvents>): Promise<void> {
|
|
253
294
|
const deferred: DeferredPromise<void> = pDefer()
|
|
254
295
|
let found = 0
|
|
255
296
|
|
|
@@ -257,7 +298,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
257
298
|
// found but continue util this.providers reaches this.maxProviders
|
|
258
299
|
void Promise.resolve()
|
|
259
300
|
.then(async () => {
|
|
260
|
-
this.log('finding %d-%d new provider(s) for %c', count, this.maxProviders, cid)
|
|
301
|
+
this.log('finding %d-%d new provider(s) for %c - %d initial providers', count, this.maxProviders, cid, this.initialProviders.length)
|
|
261
302
|
|
|
262
303
|
// process any specific providers for this session
|
|
263
304
|
if (this.initialProviders.length > 0) {
|
|
@@ -268,7 +309,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
268
309
|
break
|
|
269
310
|
}
|
|
270
311
|
|
|
271
|
-
const provider = await this.convertToProvider(prov, options)
|
|
312
|
+
const provider = await this.convertToProvider(prov, 'manual', options)
|
|
272
313
|
|
|
273
314
|
if (options.signal?.aborted === true) {
|
|
274
315
|
break
|
|
@@ -293,7 +334,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
293
334
|
found++
|
|
294
335
|
|
|
295
336
|
if (found === count) {
|
|
296
|
-
this.log('session is ready')
|
|
337
|
+
this.log('session is ready with %d peer(s), only initial peers present', count)
|
|
297
338
|
deferred.resolve()
|
|
298
339
|
// continue finding peers until we reach this.maxProviders
|
|
299
340
|
}
|
|
@@ -327,7 +368,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
327
368
|
found++
|
|
328
369
|
|
|
329
370
|
if (found === count) {
|
|
330
|
-
this.log('session is ready')
|
|
371
|
+
this.log('session is ready with %d peer(s), new peers present', count)
|
|
331
372
|
deferred.resolve()
|
|
332
373
|
// continue finding peers until we reach this.maxProviders
|
|
333
374
|
}
|
|
@@ -358,7 +399,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
358
399
|
* into the format required or return `undefined` if the provider is not
|
|
359
400
|
* compatible with this session implementation
|
|
360
401
|
*/
|
|
361
|
-
abstract convertToProvider (provider: PeerId | Multiaddr | Multiaddr[], options?: AbortOptions): Promise<Provider | undefined>
|
|
402
|
+
abstract convertToProvider (provider: PeerId | Multiaddr | Multiaddr[], routing: string, options?: AbortOptions): Promise<Provider | undefined>
|
|
362
403
|
|
|
363
404
|
/**
|
|
364
405
|
* This method should search for new providers and yield them.
|
|
@@ -376,12 +417,17 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
|
|
|
376
417
|
|
|
377
418
|
/**
|
|
378
419
|
* Turn a provider into a concise Uint8Array representation for use in a Bloom
|
|
379
|
-
* filter
|
|
420
|
+
* or Cuckoo filter
|
|
380
421
|
*/
|
|
381
|
-
abstract
|
|
422
|
+
abstract toFilterKey (provider: Provider): Uint8Array | string
|
|
382
423
|
|
|
383
424
|
/**
|
|
384
425
|
* Return `true` if we consider one provider to be the same as another
|
|
385
426
|
*/
|
|
386
427
|
abstract equals (providerA: Provider, providerB: Provider): boolean
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Invoke the progress handler with the session-specific found provider event
|
|
431
|
+
*/
|
|
432
|
+
abstract emitFoundProviderProgressEvent (cid: CID, provider: Provider, options: BlockRetrievalOptions<RetrieveBlockProgressEvents>): void
|
|
387
433
|
}
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { contentRoutingSymbol, peerRoutingSymbol, start, stop, TypedEventEmitter } from '@libp2p/interface'
|
|
9
|
-
import { defaultLogger } from '@libp2p/logger'
|
|
10
9
|
import { dns } from '@multiformats/dns'
|
|
11
10
|
import drain from 'it-drain'
|
|
12
11
|
import { CustomProgressEvent } from 'progress-events'
|
|
@@ -208,7 +207,7 @@ export class Helia<T extends Libp2p> implements HeliaInterface<T> {
|
|
|
208
207
|
private readonly log: Logger
|
|
209
208
|
|
|
210
209
|
constructor (init: Omit<HeliaInit, 'start' | 'libp2p'> & { libp2p: T }) {
|
|
211
|
-
this.logger = init.logger ??
|
|
210
|
+
this.logger = init.logger ?? init.libp2p.logger
|
|
212
211
|
this.log = this.logger.forComponent('helia')
|
|
213
212
|
this.getHasher = getHasher(init.hashers, init.loadHasher)
|
|
214
213
|
this.getCodec = getCodec(init.codecs, init.loadCodec)
|
|
@@ -259,16 +258,16 @@ export class Helia<T extends Libp2p> implements HeliaInterface<T> {
|
|
|
259
258
|
providerLookupConcurrency: init.providerLookupConcurrency
|
|
260
259
|
})
|
|
261
260
|
|
|
261
|
+
components.blockBrokers = init.blockBrokers.map((fn) => {
|
|
262
|
+
return fn(components)
|
|
263
|
+
})
|
|
264
|
+
|
|
262
265
|
const networkedStorage = new NetworkedStorage(components, init)
|
|
263
266
|
this.pins = new PinsImpl(init.datastore, networkedStorage, this.getCodec)
|
|
264
267
|
this.blockstore = new BlockStorage(networkedStorage, this.pins, {
|
|
265
268
|
holdGcLock: init.holdGcLock ?? true
|
|
266
269
|
})
|
|
267
270
|
this.datastore = init.datastore
|
|
268
|
-
|
|
269
|
-
components.blockBrokers = init.blockBrokers.map((fn) => {
|
|
270
|
-
return fn(components)
|
|
271
|
-
})
|
|
272
271
|
}
|
|
273
272
|
|
|
274
273
|
async start (): Promise<void> {
|