@peerbit/blocks 3.1.8-bbf27fa → 3.1.8-c485a73

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.
@@ -14,10 +14,21 @@ export declare class DirectBlock extends DirectStream implements IBlocks {
14
14
  eagerBlocks?: boolean | {
15
15
  cacheSize?: number;
16
16
  };
17
+ resolveProviders?: (cid: string, options?: {
18
+ signal?: AbortSignal;
19
+ }) => Promise<string[] | undefined> | string[] | undefined;
20
+ onPut?: (cid: string) => Promise<void> | void;
21
+ providerCache?: boolean | {
22
+ maxEntries?: number;
23
+ ttlMs?: number;
24
+ maxProvidersPerCid?: number;
25
+ };
26
+ requeryOnReachable?: number;
17
27
  });
18
28
  put(bytes: Uint8Array): Promise<string>;
19
29
  has(cid: string): Promise<boolean>;
20
30
  get(cid: string, options?: GetOptions | undefined): Promise<Uint8Array | undefined>;
31
+ hintProviders(cid: string, providers: string[]): void;
21
32
  rm(cid: string): Promise<void>;
22
33
  iterator(): AsyncGenerator<[string, Uint8Array], void, void>;
23
34
  start(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"libp2p.d.ts","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAQ9D,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAE3D,qBAAa,WAAY,SAAQ,YAAa,YAAW,OAAO;IAC/D,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,iBAAiB,CAAM;gBAG9B,UAAU,EAAE,qBAAqB,EACjC,OAAO,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,4BAA4B,CAAC,EAAE,MAAM,CAAC;QACtC,WAAW,CAAC,EAAE,OAAO,GAAG;YAAE,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/C;IAgCI,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvC,GAAG,CAAC,GAAG,EAAE,MAAM;IAGf,GAAG,CACR,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,UAAU,GAAG,SAAS,GAC9B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAI5B,EAAE,CAAC,GAAG,EAAE,MAAM;IAIb,QAAQ,IAAI,cAAc,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC;IAM7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOrB,IAAI;IAGV,IAAI,MAAM,mDAET;IAED,SAAS,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAGvC"}
1
+ {"version":3,"file":"libp2p.d.ts","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAE/E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAQ9D,MAAM,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAE3D,qBAAa,WAAY,SAAQ,YAAa,YAAW,OAAO;IAC/D,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,iBAAiB,CAAM;gBAG9B,UAAU,EAAE,qBAAqB,EACjC,OAAO,CAAC,EAAE;QACT,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,4BAA4B,CAAC,EAAE,MAAM,CAAC;QACtC,WAAW,CAAC,EAAE,OAAO,GAAG;YAAE,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAC/C,gBAAgB,CAAC,EAAE,CAClB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE,WAAW,CAAA;SAAE,KAC9B,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;QAC1D,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAC9C,aAAa,CAAC,EACX,OAAO,GACP;YACA,UAAU,CAAC,EAAE,MAAM,CAAC;YACpB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;SAC3B,CAAC;QACL,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC5B;IAmEI,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAIvC,GAAG,CAAC,GAAG,EAAE,MAAM;IAGf,GAAG,CACR,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,UAAU,GAAG,SAAS,GAC9B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAIlC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE;IAIxC,EAAE,CAAC,GAAG,EAAE,MAAM;IAIb,QAAQ,IAAI,cAAc,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC;IAM7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOrB,IAAI;IAGV,IAAI,MAAM,mDAET;IAED,SAAS,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CAGvC"}
@@ -1,6 +1,6 @@
1
1
  import { deserialize, serialize } from "@dao-xyz/borsh";
2
2
  import { createStore } from "@peerbit/any-store";
3
- import {} from "@peerbit/crypto";
3
+ import { getPublicKeyFromPeerId } from "@peerbit/crypto";
4
4
  import { DirectStream } from "@peerbit/stream";
5
5
  import {} from "@peerbit/stream";
6
6
  import {} from "@peerbit/stream-interface";
@@ -11,7 +11,7 @@ export class DirectBlock extends DirectStream {
11
11
  onDataFn;
12
12
  onPeerConnectedFn;
13
13
  constructor(components, options) {
14
- super(components, ["/lazyblock/0.0.0"], {
14
+ super(components, ["/peerbit/direct-block/1.0.0"], {
15
15
  messageProcessingConcurrency: options?.messageProcessingConcurrency || 10,
16
16
  canRelayMessage: options?.canRelayMessage ?? true,
17
17
  connectionManager: {
@@ -19,6 +19,39 @@ export class DirectBlock extends DirectStream {
19
19
  pruner: false,
20
20
  },
21
21
  });
22
+ const defaultResolveProviders = () => {
23
+ const out = [];
24
+ const push = (hash) => {
25
+ if (!hash)
26
+ return;
27
+ if (hash === this.publicKeyHash)
28
+ return;
29
+ // Small bounded list; avoid Set allocations on hot paths.
30
+ if (out.includes(hash))
31
+ return;
32
+ out.push(hash);
33
+ };
34
+ // Prefer peers we've already negotiated streams with for this protocol.
35
+ for (const h of this.peers.keys()) {
36
+ push(h);
37
+ if (out.length >= 32)
38
+ return out;
39
+ }
40
+ // Fall back to currently connected libp2p peers (even if we haven't opened
41
+ // a `/peerbit/direct-block` stream yet). This makes "join by hash" flows work
42
+ // without requiring an explicit `remote.from` list.
43
+ for (const conn of this.components.connectionManager.getConnections()) {
44
+ try {
45
+ push(getPublicKeyFromPeerId(conn.remotePeer).hashcode());
46
+ }
47
+ catch {
48
+ // ignore unexpected key types
49
+ }
50
+ if (out.length >= 32)
51
+ break;
52
+ }
53
+ return out;
54
+ };
22
55
  this.remoteBlocks = new RemoteBlocks({
23
56
  local: new AnyBlockStore(createStore(options?.directory)),
24
57
  publish: (message, options) => this.publish(serialize(message), options),
@@ -27,6 +60,10 @@ export class DirectBlock extends DirectStream {
27
60
  waitFor: this.waitFor.bind(this),
28
61
  publicKey: this.publicKey,
29
62
  eagerBlocks: options?.eagerBlocks,
63
+ resolveProviders: options?.resolveProviders ?? defaultResolveProviders,
64
+ onPut: options?.onPut,
65
+ providerCache: options?.providerCache,
66
+ requeryOnReachable: options?.requeryOnReachable,
30
67
  });
31
68
  this.onDataFn = (data) => {
32
69
  data.detail?.data?.length &&
@@ -44,6 +81,9 @@ export class DirectBlock extends DirectStream {
44
81
  async get(cid, options) {
45
82
  return this.remoteBlocks.get(cid, options);
46
83
  }
84
+ hintProviders(cid, providers) {
85
+ this.remoteBlocks.hintProviders(cid, providers);
86
+ }
47
87
  async rm(cid) {
48
88
  return this.remoteBlocks.rm(cid);
49
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"libp2p.js","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"libp2p.js","sourceRoot":"","sources":["../../src/libp2p.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,39 @@ export declare class RemoteBlocks implements IBlocks {
26
26
  eagerBlocks?: boolean | {
27
27
  cacheSize?: number;
28
28
  };
29
+ /**
30
+ * Optional provider resolver used when `remote: true` is used without `remote.from`.
31
+ *
32
+ * This is intentionally best-effort and must be bounded; returning large lists is
33
+ * counterproductive at scale.
34
+ */
35
+ resolveProviders?: (cid: string, options?: {
36
+ signal?: AbortSignal;
37
+ }) => Promise<string[] | undefined> | string[] | undefined;
38
+ /**
39
+ * Optional hook called after a block is stored locally (best-effort).
40
+ *
41
+ * Intended for wiring in discovery/provider announcements without coupling
42
+ * this transport to a specific directory implementation.
43
+ */
44
+ onPut?: (cid: string) => Promise<void> | void;
45
+ /**
46
+ * Cache of learned/suggested providers per CID to reduce repeated lookups and avoid
47
+ * expensive "search" behaviors.
48
+ */
49
+ providerCache?: boolean | {
50
+ /** Max distinct CIDs kept in memory. */
51
+ maxEntries?: number;
52
+ /** Entry TTL in milliseconds. */
53
+ ttlMs?: number;
54
+ /** Max provider hashes stored per CID. */
55
+ maxProvidersPerCid?: number;
56
+ };
57
+ /**
58
+ * When a request is in-flight and new peers become reachable, re-issue the request
59
+ * a limited number of times (helps "get before connect" workflows).
60
+ */
61
+ requeryOnReachable?: number;
29
62
  publish: (data: BlockRequest | BlockResponse, options: PublishOptions) => Promise<Uint8Array | undefined | void>;
30
63
  waitFor: WaitForPeersFn;
31
64
  };
@@ -33,6 +66,10 @@ export declare class RemoteBlocks implements IBlocks {
33
66
  private _responseHandler?;
34
67
  private _resolvers;
35
68
  private _blockCache?;
69
+ private _providerCache?;
70
+ private readonly publicKeyHash;
71
+ private readonly maxProviderHintsPerCid;
72
+ private readonly maxRequeryOnReachable;
36
73
  private _loadFetchQueue;
37
74
  private _readFromPeersPromises;
38
75
  _open: boolean;
@@ -46,15 +83,53 @@ export declare class RemoteBlocks implements IBlocks {
46
83
  eagerBlocks?: boolean | {
47
84
  cacheSize?: number;
48
85
  };
86
+ /**
87
+ * Optional provider resolver used when `remote: true` is used without `remote.from`.
88
+ *
89
+ * This is intentionally best-effort and must be bounded; returning large lists is
90
+ * counterproductive at scale.
91
+ */
92
+ resolveProviders?: (cid: string, options?: {
93
+ signal?: AbortSignal;
94
+ }) => Promise<string[] | undefined> | string[] | undefined;
95
+ /**
96
+ * Optional hook called after a block is stored locally (best-effort).
97
+ *
98
+ * Intended for wiring in discovery/provider announcements without coupling
99
+ * this transport to a specific directory implementation.
100
+ */
101
+ onPut?: (cid: string) => Promise<void> | void;
102
+ /**
103
+ * Cache of learned/suggested providers per CID to reduce repeated lookups and avoid
104
+ * expensive "search" behaviors.
105
+ */
106
+ providerCache?: boolean | {
107
+ /** Max distinct CIDs kept in memory. */
108
+ maxEntries?: number;
109
+ /** Entry TTL in milliseconds. */
110
+ ttlMs?: number;
111
+ /** Max provider hashes stored per CID. */
112
+ maxProvidersPerCid?: number;
113
+ };
114
+ /**
115
+ * When a request is in-flight and new peers become reachable, re-issue the request
116
+ * a limited number of times (helps "get before connect" workflows).
117
+ */
118
+ requeryOnReachable?: number;
49
119
  publish: (data: BlockRequest | BlockResponse, options: PublishOptions) => Promise<Uint8Array | undefined | void>;
50
120
  waitFor: WaitForPeersFn;
51
121
  });
122
+ private normalizeProviderHints;
123
+ private rememberProvider;
124
+ private rememberProviderHints;
125
+ private resolveRemoteProviders;
52
126
  put(bytes: Uint8Array | {
53
127
  block: Block<any, any, any, any>;
54
128
  cid: string;
55
129
  }): Promise<string>;
56
130
  has(cid: string): Promise<boolean>;
57
131
  get(cid: string, options?: GetOptions | undefined): Promise<Uint8Array | undefined>;
132
+ hintProviders(cid: string, providers: string[]): void;
58
133
  rm(cid: string): Promise<void>;
59
134
  iterator(): AsyncGenerator<[string, Uint8Array], void, void>;
60
135
  start(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"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"}
@@ -39,7 +39,7 @@ import { Cache } from "@peerbit/cache";
39
39
  import { PublicSignKey } from "@peerbit/crypto";
40
40
  import { logger as loggerFn } from "@peerbit/logger";
41
41
  import { dontThrowIfDeliveryError } from "@peerbit/stream";
42
- import { AnyWhere, SilentDelivery, } from "@peerbit/stream-interface";
42
+ import { SilentDelivery, } from "@peerbit/stream-interface";
43
43
  import { AbortError } from "@peerbit/time";
44
44
  import { CID } from "multiformats";
45
45
  import {} from "multiformats/block";
@@ -122,14 +122,19 @@ export class RemoteBlocks {
122
122
  _responseHandler;
123
123
  _resolvers;
124
124
  _blockCache;
125
+ _providerCache;
126
+ publicKeyHash;
127
+ maxProviderHintsPerCid;
128
+ maxRequeryOnReachable;
125
129
  _loadFetchQueue;
126
130
  _readFromPeersPromises;
127
131
  _open = false;
128
- _events;
129
- closeController;
132
+ _events = new TypedEventEmitter();
133
+ closeController = new AbortController();
130
134
  constructor(options) {
131
135
  this.options = options;
132
136
  const localTimeout = options?.localTimeout || 1000;
137
+ this.publicKeyHash = options.publicKey.hashcode();
133
138
  this._loadFetchQueue = new PQueue({
134
139
  concurrency: options?.messageProcessingConcurrency || 10,
135
140
  });
@@ -144,6 +149,19 @@ export class RemoteBlocks {
144
149
  ttl: 1e4,
145
150
  })
146
151
  : undefined;
152
+ const providerCache = options.providerCache === false
153
+ ? undefined
154
+ : typeof options.providerCache === "object"
155
+ ? options.providerCache
156
+ : {};
157
+ this._providerCache = providerCache
158
+ ? new Cache({
159
+ max: providerCache.maxEntries ?? 2048,
160
+ ttl: providerCache.ttlMs ?? 10 * 60 * 1000,
161
+ })
162
+ : undefined;
163
+ this.maxProviderHintsPerCid = providerCache?.maxProvidersPerCid ?? 8;
164
+ this.maxRequeryOnReachable = options.requeryOnReachable ?? 4;
147
165
  this._responseHandler = async (message, from) => {
148
166
  try {
149
167
  if (message instanceof BlockRequest && this.localStore) {
@@ -160,6 +178,9 @@ export class RemoteBlocks {
160
178
  }
161
179
  else if (message instanceof BlockResponse) {
162
180
  // TODO make sure we are not storing too much bytes in ram (like filter large blocks)
181
+ if (from) {
182
+ this.rememberProvider(message.cid, from);
183
+ }
163
184
  let resolver = this._resolvers.get(message.cid);
164
185
  if (!resolver) {
165
186
  if (options.eagerBlocks) {
@@ -178,32 +199,109 @@ export class RemoteBlocks {
178
199
  }
179
200
  };
180
201
  }
202
+ normalizeProviderHints(providers, limit = this.maxProviderHintsPerCid || 8) {
203
+ if (!providers || providers.length === 0)
204
+ return [];
205
+ const out = [];
206
+ for (const p of providers) {
207
+ if (!p)
208
+ continue;
209
+ if (p === this.publicKeyHash)
210
+ continue;
211
+ // Small bounded list; avoid Set allocations on hot paths.
212
+ if (out.includes(p))
213
+ continue;
214
+ out.push(p);
215
+ if (out.length >= limit)
216
+ break;
217
+ }
218
+ return out;
219
+ }
220
+ rememberProvider(cidString, providerHash) {
221
+ if (!this._providerCache)
222
+ return;
223
+ if (!providerHash || providerHash === this.publicKeyHash)
224
+ return;
225
+ const current = this._providerCache.get(cidString) ?? [];
226
+ const next = [providerHash];
227
+ for (const p of current) {
228
+ if (p === providerHash)
229
+ continue;
230
+ if (!p || p === this.publicKeyHash)
231
+ continue;
232
+ next.push(p);
233
+ if (next.length >= this.maxProviderHintsPerCid)
234
+ break;
235
+ }
236
+ this._providerCache.add(cidString, next);
237
+ }
238
+ rememberProviderHints(cidString, providers) {
239
+ if (!this._providerCache)
240
+ return;
241
+ const normalized = this.normalizeProviderHints(providers);
242
+ if (normalized.length === 0)
243
+ return;
244
+ this._providerCache.add(cidString, normalized);
245
+ }
246
+ async resolveRemoteProviders(cidString, options) {
247
+ // Priority:
248
+ // 1. cached providers (from previous reads)
249
+ // 2. resolveProviders hook (e.g. program-level replicators, DHT, tracker)
250
+ const cached = this.normalizeProviderHints(this._providerCache?.get(cidString) ?? undefined);
251
+ if (cached.length > 0)
252
+ return cached;
253
+ if (!this.options.resolveProviders)
254
+ return [];
255
+ try {
256
+ const resolved = await this.options.resolveProviders(cidString, options);
257
+ const normalized = this.normalizeProviderHints(resolved);
258
+ if (normalized.length > 0) {
259
+ this.rememberProviderHints(cidString, normalized);
260
+ }
261
+ return normalized;
262
+ }
263
+ catch {
264
+ return [];
265
+ }
266
+ }
181
267
  async put(bytes) {
182
268
  if (!this.localStore) {
183
269
  throw new Error("Local store not set");
184
270
  }
185
- return this.localStore.put(bytes);
271
+ const cid = await this.localStore.put(bytes);
272
+ try {
273
+ await this.options.onPut?.(cid);
274
+ }
275
+ catch {
276
+ // ignore best-effort hooks
277
+ }
278
+ return cid;
186
279
  }
187
280
  async has(cid) {
188
281
  return this.localStore.has(cid);
189
282
  }
190
283
  async get(cid, options) {
191
- const cidObject = cidifyString(cid);
192
284
  let value = this.localStore
193
285
  ? await this.localStore.get(cid, options)
194
286
  : undefined;
195
287
  if (!value) {
196
288
  // try to get it remotelly
197
- let remoteOptions = options?.remote === true ? {} : options?.remote;
289
+ const remoteOptions = options?.remote === true ? {} : options?.remote;
198
290
  if (remoteOptions) {
291
+ const cidObject = cidifyString(cid);
199
292
  value = await this._readFromPeers(cid, cidObject, remoteOptions);
200
293
  if (remoteOptions?.replicate && value) {
201
- await this.localStore.put(value);
294
+ await this.put(value);
202
295
  }
203
296
  }
204
297
  }
205
298
  return value;
206
299
  }
300
+ hintProviders(cid, providers) {
301
+ const cidString = stringifyCid(cid);
302
+ this.rememberProviderHints(cidString, providers);
303
+ this._events.dispatchEvent(new CustomEvent("providers:hints", { detail: { cid: cidString } }));
304
+ }
207
305
  async rm(cid) {
208
306
  await this.localStore?.rm(cid);
209
307
  }
@@ -230,14 +328,48 @@ export class RemoteBlocks {
230
328
  return;
231
329
  }
232
330
  const cid = stringifyCid(request.cid);
233
- const bytes = await this.localStore.get(cid, {
331
+ let bytes = await this.localStore.get(cid, {
234
332
  remote: {
235
333
  timeout: localTimeout,
236
334
  },
237
335
  });
238
336
  if (!bytes) {
239
- return;
337
+ // Best-effort relay/proxy: if we don't have the block locally, try to fetch it
338
+ // from other reachable peers and then respond to the requester.
339
+ //
340
+ // This keeps multi-hop topologies working (e.g. A <-> relay <-> B) without
341
+ // requiring the requester to know an explicit `remote.from` provider set.
342
+ try {
343
+ const cidObject = cidifyString(cid);
344
+ const proxyTimeoutMs = Math.max(1_000, Math.floor(localTimeout) || 0);
345
+ const controller = new AbortController();
346
+ const timer = setTimeout(() => controller.abort(), proxyTimeoutMs);
347
+ try {
348
+ const candidates = await this.resolveRemoteProviders(cid, {
349
+ signal: controller.signal,
350
+ });
351
+ // Never bounce the request back to the requester; keep the fanout bounded.
352
+ const providers = candidates
353
+ .filter((p) => p && p !== from)
354
+ .slice(0, this.maxProviderHintsPerCid);
355
+ if (providers.length > 0) {
356
+ bytes = await this._readFromPeers(cid, cidObject, {
357
+ signal: controller.signal,
358
+ timeout: proxyTimeoutMs,
359
+ from: providers,
360
+ });
361
+ }
362
+ }
363
+ finally {
364
+ clearTimeout(timer);
365
+ }
366
+ }
367
+ catch {
368
+ // ignore proxy failures
369
+ }
240
370
  }
371
+ if (!bytes)
372
+ return;
241
373
  await this.options
242
374
  .publish(new BlockResponse(cid, bytes), { to: [from] })
243
375
  .catch(dontThrowIfDeliveryError);
@@ -264,54 +396,97 @@ export class RemoteBlocks {
264
396
  // ignore
265
397
  }
266
398
  }
399
+ const explicitFrom = this.normalizeProviderHints(options.from);
400
+ let providers = explicitFrom.length > 0
401
+ ? explicitFrom
402
+ : await this.resolveRemoteProviders(cidString, { signal: options.signal });
403
+ const canResolveLater = explicitFrom.length === 0 && typeof this.options.resolveProviders === "function";
404
+ if (providers.length === 0 && !canResolveLater) {
405
+ // Without an explicit provider set (or a resolver), we intentionally do not
406
+ // fall back to network-wide flooding. Scalable deployments must provide a
407
+ // discovery mechanism (program-level hints, DHT/tracker, etc).
408
+ return undefined;
409
+ }
410
+ if (explicitFrom.length > 0 && providers.length > 0) {
411
+ this.rememberProviderHints(cidString, providers);
412
+ }
267
413
  let promise = this._readFromPeersPromises.get(cidString);
268
414
  if (!promise) {
269
415
  promise = new Promise((resolve, reject) => {
270
- const timeoutCallback = setTimeout(() => {
271
- resolve(undefined);
272
- }, options.timeout || 30 * 1000);
416
+ let timeoutCallback;
273
417
  const abortHandler = () => {
274
- clearTimeout(timeoutCallback);
418
+ cleanup();
419
+ reject(new AbortError());
420
+ };
421
+ const cleanup = () => {
422
+ if (timeoutCallback)
423
+ clearTimeout(timeoutCallback);
275
424
  this._resolvers.delete(cidString);
276
425
  this.closeController.signal.removeEventListener("abort", abortHandler);
277
426
  options?.signal?.removeEventListener("abort", abortHandler);
278
- reject(new AbortError());
279
427
  };
428
+ timeoutCallback = setTimeout(() => {
429
+ cleanup();
430
+ resolve(undefined);
431
+ }, options.timeout || 30 * 1000);
280
432
  this.closeController.signal.addEventListener("abort", abortHandler);
281
433
  options?.signal?.addEventListener("abort", abortHandler);
282
434
  this._resolvers.set(cidString, async (bytes) => {
283
435
  const value = await tryDecode(bytes);
284
- clearTimeout(timeoutCallback);
285
- this._resolvers.delete(cidString); // TODO concurrency might not work as expected here
286
- this.closeController.signal.removeEventListener("abort", abortHandler);
436
+ cleanup();
287
437
  resolve(value);
288
438
  });
289
439
  });
290
440
  this._readFromPeersPromises.set(cidString, promise);
291
- const publishOnNewPeers = (e) => {
292
- const to = e.detail.hashcode();
293
- if (!options?.from || options.from.includes(to)) {
294
- this.options
295
- .publish(new BlockRequest(cidString), {
296
- // We dont sent explicitly to 'to' here because we want the message to propagate beyond the first peer
297
- to: [to],
298
- mode: new AnyWhere(),
299
- })
300
- .catch(dontThrowIfDeliveryError);
441
+ let requeryCount = 0;
442
+ const tryPublishRequest = async () => {
443
+ if (requeryCount >= this.maxRequeryOnReachable)
444
+ return;
445
+ if (providers.length === 0) {
446
+ providers = await this.resolveRemoteProviders(cidString, {
447
+ signal: options.signal,
448
+ });
449
+ }
450
+ if (providers.length === 0)
451
+ return;
452
+ try {
453
+ await this.options.publish(new BlockRequest(cidString), {
454
+ mode: new SilentDelivery({ to: providers, redundancy: 1 }),
455
+ });
456
+ requeryCount += 1;
301
457
  }
458
+ catch (e) {
459
+ dontThrowIfDeliveryError(e);
460
+ }
461
+ };
462
+ const publishOnNewPeers = () => {
463
+ // Re-issue when reachability changes to handle "get before connect".
464
+ // Bounded to avoid accidental amplification at large scale.
465
+ if (requeryCount >= this.maxRequeryOnReachable)
466
+ return;
467
+ tryPublishRequest().catch(dontThrowIfDeliveryError);
468
+ };
469
+ const publishOnProviderHints = (ev) => {
470
+ if (requeryCount >= this.maxRequeryOnReachable)
471
+ return;
472
+ if (!ev?.detail?.cid)
473
+ return;
474
+ if (ev.detail.cid !== cidString)
475
+ return;
476
+ tryPublishRequest().catch(dontThrowIfDeliveryError);
302
477
  };
303
478
  this._events.addEventListener("peer:reachable", publishOnNewPeers);
304
- await this.options.publish(new BlockRequest(cidString), {
305
- mode: options.from
306
- ? new SilentDelivery({ to: options.from, redundancy: 1 })
307
- : new AnyWhere(),
308
- });
309
- // we want to make sure that if some new peers join, we also try to ask them
310
- const result = await promise;
311
- this._readFromPeersPromises.delete(cidString);
312
- // stop asking new peers, because we already got an response
313
- this._events.removeEventListener("peer:reachable", publishOnNewPeers);
314
- return result?.bytes;
479
+ this._events.addEventListener("providers:hints", publishOnProviderHints);
480
+ try {
481
+ await tryPublishRequest();
482
+ const result = await promise;
483
+ return result?.bytes;
484
+ }
485
+ finally {
486
+ this._readFromPeersPromises.delete(cidString);
487
+ this._events.removeEventListener("peer:reachable", publishOnNewPeers);
488
+ this._events.removeEventListener("providers:hints", publishOnProviderHints);
489
+ }
315
490
  }
316
491
  else {
317
492
  const result = await promise;
@@ -328,6 +503,7 @@ export class RemoteBlocks {
328
503
  this._readFromPeersPromises.clear();
329
504
  this._resolvers.clear();
330
505
  this._blockCache?.clear();
506
+ this._providerCache?.clear();
331
507
  this._open = false;
332
508
  // we dont cleanup subscription because we dont know if someone else is sbuscribing also
333
509
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remote.js","sourceRoot":"","sources":["../../src/remote.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/blocks",
3
- "version": "3.1.8-bbf27fa",
3
+ "version": "3.1.8-c485a73",
4
4
  "description": "Block store streaming",
5
5
  "type": "module",
6
6
  "types": "./dist/src/index.d.ts",
@@ -68,22 +68,22 @@
68
68
  "dao.xyz"
69
69
  ],
70
70
  "devDependencies": {
71
- "@peerbit/libp2p-test-utils": "2.2.0-bbf27fa"
71
+ "@peerbit/libp2p-test-utils": "2.2.0-c485a73"
72
72
  },
73
73
  "dependencies": {
74
74
  "@dao-xyz/borsh": "^6.0.0",
75
75
  "@libp2p/interface": "^3.1.0",
76
76
  "@libp2p/tcp": "^11.0.2",
77
77
  "@libp2p/websockets": "^10.1.0",
78
- "@peerbit/any-store": "2.2.4-bbf27fa",
79
- "@peerbit/any-store-interface": "1.1.0-bbf27fa",
80
- "@peerbit/cache": "2.2.0-bbf27fa",
81
- "@peerbit/logger": "2.0.0-bbf27fa",
82
- "@peerbit/stream": "4.6.0-bbf27fa",
83
- "@peerbit/stream-interface": "5.4.0-bbf27fa",
84
- "@peerbit/time": "2.3.0-bbf27fa",
85
- "@peerbit/blocks-interface": "1.5.2-bbf27fa",
86
- "@peerbit/crypto": "2.4.1-bbf27fa",
78
+ "@peerbit/any-store": "2.2.4-c485a73",
79
+ "@peerbit/any-store-interface": "1.1.0-c485a73",
80
+ "@peerbit/cache": "2.2.0-c485a73",
81
+ "@peerbit/logger": "2.0.0-c485a73",
82
+ "@peerbit/stream": "4.6.0-c485a73",
83
+ "@peerbit/stream-interface": "5.4.0-c485a73",
84
+ "@peerbit/time": "2.3.0-c485a73",
85
+ "@peerbit/blocks-interface": "1.5.2-c485a73",
86
+ "@peerbit/crypto": "2.4.1-c485a73",
87
87
  "@ipld/dag-cbor": "^9.2.1",
88
88
  "multiformats": "^13.4.1",
89
89
  "p-defer": "^4.0.0",
package/src/libp2p.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { deserialize, serialize } from "@dao-xyz/borsh";
2
2
  import { createStore } from "@peerbit/any-store";
3
3
  import type { GetOptions, Blocks as IBlocks } from "@peerbit/blocks-interface";
4
- import { type PublicSignKey } from "@peerbit/crypto";
4
+ import { getPublicKeyFromPeerId, type PublicSignKey } from "@peerbit/crypto";
5
5
  import { DirectStream } from "@peerbit/stream";
6
6
  import { type DirectStreamComponents } from "@peerbit/stream";
7
7
  import {
@@ -26,9 +26,22 @@ export class DirectBlock extends DirectStream implements IBlocks {
26
26
  localTimeout?: number;
27
27
  messageProcessingConcurrency?: number;
28
28
  eagerBlocks?: boolean | { cacheSize?: number };
29
+ resolveProviders?: (
30
+ cid: string,
31
+ options?: { signal?: AbortSignal },
32
+ ) => Promise<string[] | undefined> | string[] | undefined;
33
+ onPut?: (cid: string) => Promise<void> | void;
34
+ providerCache?:
35
+ | boolean
36
+ | {
37
+ maxEntries?: number;
38
+ ttlMs?: number;
39
+ maxProvidersPerCid?: number;
40
+ };
41
+ requeryOnReachable?: number;
29
42
  },
30
43
  ) {
31
- super(components, ["/lazyblock/0.0.0"], {
44
+ super(components, ["/peerbit/direct-block/1.0.0"], {
32
45
  messageProcessingConcurrency: options?.messageProcessingConcurrency || 10,
33
46
  canRelayMessage: options?.canRelayMessage ?? true,
34
47
  connectionManager: {
@@ -36,6 +49,37 @@ export class DirectBlock extends DirectStream implements IBlocks {
36
49
  pruner: false,
37
50
  },
38
51
  });
52
+
53
+ const defaultResolveProviders = () => {
54
+ const out: string[] = [];
55
+ const push = (hash?: string) => {
56
+ if (!hash) return;
57
+ if (hash === this.publicKeyHash) return;
58
+ // Small bounded list; avoid Set allocations on hot paths.
59
+ if (out.includes(hash)) return;
60
+ out.push(hash);
61
+ };
62
+
63
+ // Prefer peers we've already negotiated streams with for this protocol.
64
+ for (const h of this.peers.keys()) {
65
+ push(h);
66
+ if (out.length >= 32) return out;
67
+ }
68
+
69
+ // Fall back to currently connected libp2p peers (even if we haven't opened
70
+ // a `/peerbit/direct-block` stream yet). This makes "join by hash" flows work
71
+ // without requiring an explicit `remote.from` list.
72
+ for (const conn of this.components.connectionManager.getConnections()) {
73
+ try {
74
+ push(getPublicKeyFromPeerId(conn.remotePeer).hashcode());
75
+ } catch {
76
+ // ignore unexpected key types
77
+ }
78
+ if (out.length >= 32) break;
79
+ }
80
+
81
+ return out;
82
+ };
39
83
  this.remoteBlocks = new RemoteBlocks({
40
84
  local: new AnyBlockStore(createStore(options?.directory)),
41
85
  publish: (message, options) => this.publish(serialize(message), options),
@@ -44,6 +88,10 @@ export class DirectBlock extends DirectStream implements IBlocks {
44
88
  waitFor: this.waitFor.bind(this) as WaitForPeersFn,
45
89
  publicKey: this.publicKey,
46
90
  eagerBlocks: options?.eagerBlocks,
91
+ resolveProviders: options?.resolveProviders ?? defaultResolveProviders,
92
+ onPut: options?.onPut,
93
+ providerCache: options?.providerCache,
94
+ requeryOnReachable: options?.requeryOnReachable,
47
95
  });
48
96
 
49
97
  this.onDataFn = (data: CustomEvent<DataMessage>) => {
@@ -72,6 +120,10 @@ export class DirectBlock extends DirectStream implements IBlocks {
72
120
  return this.remoteBlocks.get(cid, options);
73
121
  }
74
122
 
123
+ hintProviders(cid: string, providers: string[]) {
124
+ this.remoteBlocks.hintProviders(cid, providers);
125
+ }
126
+
75
127
  async rm(cid: string) {
76
128
  return this.remoteBlocks.rm(cid);
77
129
  }
package/src/remote.ts CHANGED
@@ -13,7 +13,6 @@ import { PublicSignKey } from "@peerbit/crypto";
13
13
  import { logger as loggerFn } from "@peerbit/logger";
14
14
  import { type PublishOptions, dontThrowIfDeliveryError } from "@peerbit/stream";
15
15
  import {
16
- AnyWhere,
17
16
  type PeerRefs,
18
17
  SilentDelivery,
19
18
  type WaitForAnyOpts,
@@ -64,6 +63,10 @@ export class RemoteBlocks implements IBlocks {
64
63
  private _responseHandler?: (data: BlockMessage, from?: string) => any;
65
64
  private _resolvers: Map<string, (data: Uint8Array) => Promise<void>>;
66
65
  private _blockCache?: Cache<Uint8Array>;
66
+ private _providerCache?: Cache<string[]>;
67
+ private readonly publicKeyHash: string;
68
+ private readonly maxProviderHintsPerCid: number;
69
+ private readonly maxRequeryOnReachable: number;
67
70
 
68
71
  private _loadFetchQueue: PQueue;
69
72
  private _readFromPeersPromises: Map<
@@ -73,8 +76,9 @@ export class RemoteBlocks implements IBlocks {
73
76
  _open = false;
74
77
  private _events: TypedEventEmitter<{
75
78
  "peer:reachable": CustomEvent<PublicSignKey>;
76
- }>;
77
- private closeController: AbortController;
79
+ "providers:hints": CustomEvent<{ cid: string }>;
80
+ }> = new TypedEventEmitter();
81
+ private closeController: AbortController = new AbortController();
78
82
 
79
83
  constructor(
80
84
  readonly options: {
@@ -83,6 +87,42 @@ export class RemoteBlocks implements IBlocks {
83
87
  messageProcessingConcurrency?: number;
84
88
  publicKey: PublicSignKey;
85
89
  eagerBlocks?: boolean | { cacheSize?: number };
90
+ /**
91
+ * Optional provider resolver used when `remote: true` is used without `remote.from`.
92
+ *
93
+ * This is intentionally best-effort and must be bounded; returning large lists is
94
+ * counterproductive at scale.
95
+ */
96
+ resolveProviders?: (
97
+ cid: string,
98
+ options?: { signal?: AbortSignal },
99
+ ) => Promise<string[] | undefined> | string[] | undefined;
100
+ /**
101
+ * Optional hook called after a block is stored locally (best-effort).
102
+ *
103
+ * Intended for wiring in discovery/provider announcements without coupling
104
+ * this transport to a specific directory implementation.
105
+ */
106
+ onPut?: (cid: string) => Promise<void> | void;
107
+ /**
108
+ * Cache of learned/suggested providers per CID to reduce repeated lookups and avoid
109
+ * expensive "search" behaviors.
110
+ */
111
+ providerCache?:
112
+ | boolean
113
+ | {
114
+ /** Max distinct CIDs kept in memory. */
115
+ maxEntries?: number;
116
+ /** Entry TTL in milliseconds. */
117
+ ttlMs?: number;
118
+ /** Max provider hashes stored per CID. */
119
+ maxProvidersPerCid?: number;
120
+ };
121
+ /**
122
+ * When a request is in-flight and new peers become reachable, re-issue the request
123
+ * a limited number of times (helps "get before connect" workflows).
124
+ */
125
+ requeryOnReachable?: number;
86
126
  publish: (
87
127
  data: BlockRequest | BlockResponse,
88
128
  options: PublishOptions,
@@ -91,6 +131,7 @@ export class RemoteBlocks implements IBlocks {
91
131
  },
92
132
  ) {
93
133
  const localTimeout = options?.localTimeout || 1000;
134
+ this.publicKeyHash = options.publicKey.hashcode();
94
135
  this._loadFetchQueue = new PQueue({
95
136
  concurrency: options?.messageProcessingConcurrency || 10,
96
137
  });
@@ -106,6 +147,25 @@ export class RemoteBlocks implements IBlocks {
106
147
  ttl: 1e4,
107
148
  })
108
149
  : undefined;
150
+ type ProviderCacheOptions = {
151
+ maxEntries?: number;
152
+ ttlMs?: number;
153
+ maxProvidersPerCid?: number;
154
+ };
155
+ const providerCache: ProviderCacheOptions | undefined =
156
+ options.providerCache === false
157
+ ? undefined
158
+ : typeof options.providerCache === "object"
159
+ ? options.providerCache
160
+ : {};
161
+ this._providerCache = providerCache
162
+ ? new Cache<string[]>({
163
+ max: providerCache.maxEntries ?? 2048,
164
+ ttl: providerCache.ttlMs ?? 10 * 60 * 1000,
165
+ })
166
+ : undefined;
167
+ this.maxProviderHintsPerCid = providerCache?.maxProvidersPerCid ?? 8;
168
+ this.maxRequeryOnReachable = options.requeryOnReachable ?? 4;
109
169
 
110
170
  this._responseHandler = async (message: BlockMessage, from?: string) => {
111
171
  try {
@@ -121,6 +181,9 @@ export class RemoteBlocks implements IBlocks {
121
181
  });
122
182
  } else if (message instanceof BlockResponse) {
123
183
  // TODO make sure we are not storing too much bytes in ram (like filter large blocks)
184
+ if (from) {
185
+ this.rememberProvider(message.cid, from);
186
+ }
124
187
  let resolver = this._resolvers.get(message.cid);
125
188
  if (!resolver) {
126
189
  if (options.eagerBlocks) {
@@ -138,40 +201,118 @@ export class RemoteBlocks implements IBlocks {
138
201
  };
139
202
  }
140
203
 
204
+ private normalizeProviderHints(
205
+ providers: string[] | undefined,
206
+ limit = this.maxProviderHintsPerCid || 8,
207
+ ): string[] {
208
+ if (!providers || providers.length === 0) return [];
209
+ const out: string[] = [];
210
+ for (const p of providers) {
211
+ if (!p) continue;
212
+ if (p === this.publicKeyHash) continue;
213
+ // Small bounded list; avoid Set allocations on hot paths.
214
+ if (out.includes(p)) continue;
215
+ out.push(p);
216
+ if (out.length >= limit) break;
217
+ }
218
+ return out;
219
+ }
220
+
221
+ private rememberProvider(cidString: string, providerHash: string) {
222
+ if (!this._providerCache) return;
223
+ if (!providerHash || providerHash === this.publicKeyHash) return;
224
+ const current = this._providerCache.get(cidString) ?? [];
225
+ const next: string[] = [providerHash];
226
+ for (const p of current) {
227
+ if (p === providerHash) continue;
228
+ if (!p || p === this.publicKeyHash) continue;
229
+ next.push(p);
230
+ if (next.length >= this.maxProviderHintsPerCid) break;
231
+ }
232
+ this._providerCache.add(cidString, next);
233
+ }
234
+
235
+ private rememberProviderHints(cidString: string, providers: string[]) {
236
+ if (!this._providerCache) return;
237
+ const normalized = this.normalizeProviderHints(providers);
238
+ if (normalized.length === 0) return;
239
+ this._providerCache.add(cidString, normalized);
240
+ }
241
+
242
+ private async resolveRemoteProviders(
243
+ cidString: string,
244
+ options?: { signal?: AbortSignal },
245
+ ): Promise<string[]> {
246
+ // Priority:
247
+ // 1. cached providers (from previous reads)
248
+ // 2. resolveProviders hook (e.g. program-level replicators, DHT, tracker)
249
+ const cached = this.normalizeProviderHints(
250
+ this._providerCache?.get(cidString) ?? undefined,
251
+ );
252
+ if (cached.length > 0) return cached;
253
+ if (!this.options.resolveProviders) return [];
254
+ try {
255
+ const resolved = await this.options.resolveProviders(cidString, options);
256
+ const normalized = this.normalizeProviderHints(resolved);
257
+ if (normalized.length > 0) {
258
+ this.rememberProviderHints(cidString, normalized);
259
+ }
260
+ return normalized;
261
+ } catch {
262
+ return [];
263
+ }
264
+ }
265
+
141
266
  async put(
142
267
  bytes: Uint8Array | { block: Block<any, any, any, any>; cid: string },
143
268
  ): Promise<string> {
144
269
  if (!this.localStore) {
145
270
  throw new Error("Local store not set");
146
271
  }
147
- return this.localStore!.put(bytes);
272
+ const cid = await this.localStore!.put(bytes);
273
+ try {
274
+ await this.options.onPut?.(cid);
275
+ } catch {
276
+ // ignore best-effort hooks
277
+ }
278
+ return cid;
148
279
  }
149
280
 
150
281
  async has(cid: string) {
151
282
  return this.localStore.has(cid);
152
283
  }
284
+
153
285
  async get(
154
286
  cid: string,
155
287
  options?: GetOptions | undefined,
156
288
  ): Promise<Uint8Array | undefined> {
157
- const cidObject = cidifyString(cid);
158
289
  let value = this.localStore
159
290
  ? await this.localStore.get(cid, options)
160
291
  : undefined;
161
292
 
162
293
  if (!value) {
163
294
  // try to get it remotelly
164
- let remoteOptions = options?.remote === true ? {} : options?.remote;
295
+ const remoteOptions = options?.remote === true ? {} : options?.remote;
165
296
  if (remoteOptions) {
297
+ const cidObject = cidifyString(cid);
166
298
  value = await this._readFromPeers(cid, cidObject, remoteOptions);
167
299
  if (remoteOptions?.replicate && value) {
168
- await this.localStore!.put(value);
300
+ await this.put(value);
169
301
  }
170
302
  }
171
303
  }
304
+
172
305
  return value;
173
306
  }
174
307
 
308
+ hintProviders(cid: string, providers: string[]) {
309
+ const cidString = stringifyCid(cid);
310
+ this.rememberProviderHints(cidString, providers);
311
+ this._events.dispatchEvent(
312
+ new CustomEvent("providers:hints", { detail: { cid: cidString } }),
313
+ );
314
+ }
315
+
175
316
  async rm(cid: string) {
176
317
  await this.localStore?.rm(cid);
177
318
  }
@@ -208,15 +349,47 @@ export class RemoteBlocks implements IBlocks {
208
349
  return;
209
350
  }
210
351
  const cid = stringifyCid(request.cid);
211
- const bytes = await this.localStore.get(cid, {
352
+ let bytes = await this.localStore.get(cid, {
212
353
  remote: {
213
354
  timeout: localTimeout,
214
355
  },
215
356
  });
216
357
 
217
358
  if (!bytes) {
218
- return;
359
+ // Best-effort relay/proxy: if we don't have the block locally, try to fetch it
360
+ // from other reachable peers and then respond to the requester.
361
+ //
362
+ // This keeps multi-hop topologies working (e.g. A <-> relay <-> B) without
363
+ // requiring the requester to know an explicit `remote.from` provider set.
364
+ try {
365
+ const cidObject = cidifyString(cid);
366
+ const proxyTimeoutMs = Math.max(1_000, Math.floor(localTimeout) || 0);
367
+ const controller = new AbortController();
368
+ const timer = setTimeout(() => controller.abort(), proxyTimeoutMs);
369
+ try {
370
+ const candidates = await this.resolveRemoteProviders(cid, {
371
+ signal: controller.signal,
372
+ });
373
+ // Never bounce the request back to the requester; keep the fanout bounded.
374
+ const providers = candidates
375
+ .filter((p) => p && p !== from)
376
+ .slice(0, this.maxProviderHintsPerCid);
377
+ if (providers.length > 0) {
378
+ bytes = await this._readFromPeers(cid, cidObject, {
379
+ signal: controller.signal,
380
+ timeout: proxyTimeoutMs,
381
+ from: providers,
382
+ });
383
+ }
384
+ } finally {
385
+ clearTimeout(timer);
386
+ }
387
+ } catch {
388
+ // ignore proxy failures
389
+ }
219
390
  }
391
+
392
+ if (!bytes) return;
220
393
  await this.options
221
394
  .publish(new BlockResponse(cid, bytes), { to: [from] })
222
395
  .catch(dontThrowIfDeliveryError);
@@ -255,38 +428,54 @@ export class RemoteBlocks implements IBlocks {
255
428
  }
256
429
  }
257
430
 
431
+ const explicitFrom = this.normalizeProviderHints(options.from);
432
+ let providers =
433
+ explicitFrom.length > 0
434
+ ? explicitFrom
435
+ : await this.resolveRemoteProviders(cidString, { signal: options.signal });
436
+ const canResolveLater =
437
+ explicitFrom.length === 0 && typeof this.options.resolveProviders === "function";
438
+ if (providers.length === 0 && !canResolveLater) {
439
+ // Without an explicit provider set (or a resolver), we intentionally do not
440
+ // fall back to network-wide flooding. Scalable deployments must provide a
441
+ // discovery mechanism (program-level hints, DHT/tracker, etc).
442
+ return undefined;
443
+ }
444
+ if (explicitFrom.length > 0 && providers.length > 0) {
445
+ this.rememberProviderHints(cidString, providers);
446
+ }
447
+
258
448
  let promise = this._readFromPeersPromises.get(cidString);
259
449
  if (!promise) {
260
450
  promise = new Promise<Block<any, any, any, 1> | undefined>(
261
451
  (resolve, reject) => {
262
- const timeoutCallback = setTimeout(
263
- () => {
264
- resolve(undefined);
265
- },
266
- options.timeout || 30 * 1000,
267
- );
452
+ let timeoutCallback: ReturnType<typeof setTimeout> | undefined;
268
453
  const abortHandler = () => {
269
- clearTimeout(timeoutCallback);
454
+ cleanup();
455
+ reject(new AbortError());
456
+ };
457
+
458
+ const cleanup = () => {
459
+ if (timeoutCallback) clearTimeout(timeoutCallback);
270
460
  this._resolvers.delete(cidString);
271
461
  this.closeController.signal.removeEventListener(
272
462
  "abort",
273
463
  abortHandler,
274
464
  );
275
465
  options?.signal?.removeEventListener("abort", abortHandler);
276
- reject(new AbortError());
277
466
  };
467
+
468
+ timeoutCallback = setTimeout(() => {
469
+ cleanup();
470
+ resolve(undefined);
471
+ }, options.timeout || 30 * 1000);
472
+
278
473
  this.closeController.signal.addEventListener("abort", abortHandler);
279
474
  options?.signal?.addEventListener("abort", abortHandler);
280
475
 
281
476
  this._resolvers.set(cidString, async (bytes: Uint8Array) => {
282
477
  const value = await tryDecode(bytes);
283
-
284
- clearTimeout(timeoutCallback);
285
- this._resolvers.delete(cidString); // TODO concurrency might not work as expected here
286
- this.closeController.signal.removeEventListener(
287
- "abort",
288
- abortHandler,
289
- );
478
+ cleanup();
290
479
  resolve(value);
291
480
  });
292
481
  },
@@ -294,33 +483,50 @@ export class RemoteBlocks implements IBlocks {
294
483
 
295
484
  this._readFromPeersPromises.set(cidString, promise);
296
485
 
297
- const publishOnNewPeers = (e: CustomEvent<PublicSignKey>) => {
298
- const to = e.detail.hashcode();
299
- if (!options?.from || options.from.includes(to)) {
300
- this.options
301
- .publish(new BlockRequest(cidString), {
302
- // We dont sent explicitly to 'to' here because we want the message to propagate beyond the first peer
303
- to: [to],
304
- mode: new AnyWhere(),
305
- })
306
- .catch(dontThrowIfDeliveryError);
486
+ let requeryCount = 0;
487
+ const tryPublishRequest = async () => {
488
+ if (requeryCount >= this.maxRequeryOnReachable) return;
489
+ if (providers.length === 0) {
490
+ providers = await this.resolveRemoteProviders(cidString, {
491
+ signal: options.signal,
492
+ });
493
+ }
494
+ if (providers.length === 0) return;
495
+ try {
496
+ await this.options.publish(new BlockRequest(cidString), {
497
+ mode: new SilentDelivery({ to: providers, redundancy: 1 }),
498
+ });
499
+ requeryCount += 1;
500
+ } catch (e) {
501
+ dontThrowIfDeliveryError(e);
307
502
  }
308
503
  };
309
504
 
310
- this._events.addEventListener("peer:reachable", publishOnNewPeers);
311
- await this.options.publish(new BlockRequest(cidString), {
312
- mode: options.from
313
- ? new SilentDelivery({ to: options.from, redundancy: 1 })
314
- : new AnyWhere(),
315
- });
316
- // we want to make sure that if some new peers join, we also try to ask them
505
+ const publishOnNewPeers = () => {
506
+ // Re-issue when reachability changes to handle "get before connect".
507
+ // Bounded to avoid accidental amplification at large scale.
508
+ if (requeryCount >= this.maxRequeryOnReachable) return;
509
+ tryPublishRequest().catch(dontThrowIfDeliveryError);
510
+ };
317
511
 
318
- const result = await promise;
319
- this._readFromPeersPromises.delete(cidString);
512
+ const publishOnProviderHints = (ev: CustomEvent<{ cid: string }>) => {
513
+ if (requeryCount >= this.maxRequeryOnReachable) return;
514
+ if (!ev?.detail?.cid) return;
515
+ if (ev.detail.cid !== cidString) return;
516
+ tryPublishRequest().catch(dontThrowIfDeliveryError);
517
+ };
320
518
 
321
- // stop asking new peers, because we already got an response
322
- this._events.removeEventListener("peer:reachable", publishOnNewPeers);
323
- return result?.bytes;
519
+ this._events.addEventListener("peer:reachable", publishOnNewPeers);
520
+ this._events.addEventListener("providers:hints", publishOnProviderHints);
521
+ try {
522
+ await tryPublishRequest();
523
+ const result = await promise;
524
+ return result?.bytes;
525
+ } finally {
526
+ this._readFromPeersPromises.delete(cidString);
527
+ this._events.removeEventListener("peer:reachable", publishOnNewPeers);
528
+ this._events.removeEventListener("providers:hints", publishOnProviderHints);
529
+ }
324
530
  } else {
325
531
  const result = await promise;
326
532
  return result?.bytes;
@@ -338,6 +544,7 @@ export class RemoteBlocks implements IBlocks {
338
544
  this._readFromPeersPromises.clear();
339
545
  this._resolvers.clear();
340
546
  this._blockCache?.clear();
547
+ this._providerCache?.clear();
341
548
  this._open = false;
342
549
  // we dont cleanup subscription because we dont know if someone else is sbuscribing also
343
550
  }