@peerbit/blocks 3.1.7 → 3.1.8-000e3f1

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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"}
@@ -1,6 +1,6 @@
1
1
  import { type GetOptions, type Blocks as IBlocks } from "@peerbit/blocks-interface";
2
2
  import { PublicSignKey } from "@peerbit/crypto";
3
- import type { PublishOptions } from "@peerbit/stream";
3
+ import { type PublishOptions } from "@peerbit/stream";
4
4
  import { type PeerRefs, type WaitForAnyOpts, type WaitForPeersFn, type WaitForPresentOpts } from "@peerbit/stream-interface";
5
5
  import { type Block } from "multiformats/block";
6
6
  import { AnyBlockStore } from "./any-blockstore.js";
@@ -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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"}
@@ -38,7 +38,8 @@ import { checkDecodeBlock, cidifyString, codecCodes, stringifyCid, } from "@peer
38
38
  import { Cache } from "@peerbit/cache";
39
39
  import { PublicSignKey } from "@peerbit/crypto";
40
40
  import { logger as loggerFn } from "@peerbit/logger";
41
- import { AnyWhere, SilentDelivery, } from "@peerbit/stream-interface";
41
+ import { dontThrowIfDeliveryError } from "@peerbit/stream";
42
+ import { SilentDelivery, } from "@peerbit/stream-interface";
42
43
  import { AbortError } from "@peerbit/time";
43
44
  import { CID } from "multiformats";
44
45
  import {} from "multiformats/block";
@@ -121,14 +122,19 @@ export class RemoteBlocks {
121
122
  _responseHandler;
122
123
  _resolvers;
123
124
  _blockCache;
125
+ _providerCache;
126
+ publicKeyHash;
127
+ maxProviderHintsPerCid;
128
+ maxRequeryOnReachable;
124
129
  _loadFetchQueue;
125
130
  _readFromPeersPromises;
126
131
  _open = false;
127
- _events;
128
- closeController;
132
+ _events = new TypedEventEmitter();
133
+ closeController = new AbortController();
129
134
  constructor(options) {
130
135
  this.options = options;
131
136
  const localTimeout = options?.localTimeout || 1000;
137
+ this.publicKeyHash = options.publicKey.hashcode();
132
138
  this._loadFetchQueue = new PQueue({
133
139
  concurrency: options?.messageProcessingConcurrency || 10,
134
140
  });
@@ -143,13 +149,38 @@ export class RemoteBlocks {
143
149
  ttl: 1e4,
144
150
  })
145
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;
146
165
  this._responseHandler = async (message, from) => {
147
166
  try {
148
167
  if (message instanceof BlockRequest && this.localStore) {
149
- this._loadFetchQueue.add(() => this.handleFetchRequest(message, localTimeout, from));
168
+ this._loadFetchQueue
169
+ .add(() => this.handleFetchRequest(message, localTimeout, from))
170
+ .catch((e) => {
171
+ try {
172
+ dontThrowIfDeliveryError(e);
173
+ }
174
+ catch (error) {
175
+ logger.error("Got error for libp2p block transport: ", error);
176
+ }
177
+ });
150
178
  }
151
179
  else if (message instanceof BlockResponse) {
152
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
+ }
153
184
  let resolver = this._resolvers.get(message.cid);
154
185
  if (!resolver) {
155
186
  if (options.eagerBlocks) {
@@ -158,7 +189,7 @@ export class RemoteBlocks {
158
189
  }
159
190
  }
160
191
  else {
161
- resolver(message.bytes);
192
+ await resolver(message.bytes);
162
193
  }
163
194
  }
164
195
  }
@@ -168,32 +199,109 @@ export class RemoteBlocks {
168
199
  }
169
200
  };
170
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
+ }
171
267
  async put(bytes) {
172
268
  if (!this.localStore) {
173
269
  throw new Error("Local store not set");
174
270
  }
175
- 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;
176
279
  }
177
280
  async has(cid) {
178
281
  return this.localStore.has(cid);
179
282
  }
180
283
  async get(cid, options) {
181
- const cidObject = cidifyString(cid);
182
284
  let value = this.localStore
183
285
  ? await this.localStore.get(cid, options)
184
286
  : undefined;
185
287
  if (!value) {
186
288
  // try to get it remotelly
187
- let remoteOptions = options?.remote === true ? {} : options?.remote;
289
+ const remoteOptions = options?.remote === true ? {} : options?.remote;
188
290
  if (remoteOptions) {
291
+ const cidObject = cidifyString(cid);
189
292
  value = await this._readFromPeers(cid, cidObject, remoteOptions);
190
293
  if (remoteOptions?.replicate && value) {
191
- await this.localStore.put(value);
294
+ await this.put(value);
192
295
  }
193
296
  }
194
297
  }
195
298
  return value;
196
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
+ }
197
305
  async rm(cid) {
198
306
  await this.localStore?.rm(cid);
199
307
  }
@@ -220,15 +328,51 @@ export class RemoteBlocks {
220
328
  return;
221
329
  }
222
330
  const cid = stringifyCid(request.cid);
223
- const bytes = await this.localStore.get(cid, {
331
+ let bytes = await this.localStore.get(cid, {
224
332
  remote: {
225
333
  timeout: localTimeout,
226
334
  },
227
335
  });
228
336
  if (!bytes) {
229
- 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
+ }
230
370
  }
231
- await this.options.publish(new BlockResponse(cid, bytes), { to: [from] });
371
+ if (!bytes)
372
+ return;
373
+ await this.options
374
+ .publish(new BlockResponse(cid, bytes), { to: [from] })
375
+ .catch(dontThrowIfDeliveryError);
232
376
  }
233
377
  async _readFromPeers(cidString, cidObject, options = {}) {
234
378
  const codec = codecCodes[cidObject.code];
@@ -252,52 +396,97 @@ export class RemoteBlocks {
252
396
  // ignore
253
397
  }
254
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
+ }
255
413
  let promise = this._readFromPeersPromises.get(cidString);
256
414
  if (!promise) {
257
415
  promise = new Promise((resolve, reject) => {
258
- const timeoutCallback = setTimeout(() => {
259
- resolve(undefined);
260
- }, options.timeout || 30 * 1000);
416
+ let timeoutCallback;
261
417
  const abortHandler = () => {
262
- clearTimeout(timeoutCallback);
418
+ cleanup();
419
+ reject(new AbortError());
420
+ };
421
+ const cleanup = () => {
422
+ if (timeoutCallback)
423
+ clearTimeout(timeoutCallback);
263
424
  this._resolvers.delete(cidString);
264
425
  this.closeController.signal.removeEventListener("abort", abortHandler);
265
426
  options?.signal?.removeEventListener("abort", abortHandler);
266
- reject(new AbortError());
267
427
  };
428
+ timeoutCallback = setTimeout(() => {
429
+ cleanup();
430
+ resolve(undefined);
431
+ }, options.timeout || 30 * 1000);
268
432
  this.closeController.signal.addEventListener("abort", abortHandler);
269
433
  options?.signal?.addEventListener("abort", abortHandler);
270
434
  this._resolvers.set(cidString, async (bytes) => {
271
435
  const value = await tryDecode(bytes);
272
- clearTimeout(timeoutCallback);
273
- this._resolvers.delete(cidString); // TODO concurrency might not work as expected here
274
- this.closeController.signal.removeEventListener("abort", abortHandler);
436
+ cleanup();
275
437
  resolve(value);
276
438
  });
277
439
  });
278
440
  this._readFromPeersPromises.set(cidString, promise);
279
- const publishOnNewPeers = (e) => {
280
- const to = e.detail.hashcode();
281
- if (!options?.from || options.from.includes(to)) {
282
- return this.options.publish(new BlockRequest(cidString), {
283
- // We dont sent explicitly to 'to' here because we want the message to propagate beyond the first peer
284
- to: [to],
285
- mode: new AnyWhere(),
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 }),
286
455
  });
456
+ requeryCount += 1;
287
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);
288
477
  };
289
478
  this._events.addEventListener("peer:reachable", publishOnNewPeers);
290
- await this.options.publish(new BlockRequest(cidString), {
291
- mode: options.from
292
- ? new SilentDelivery({ to: options.from, redundancy: 1 })
293
- : new AnyWhere(),
294
- });
295
- // we want to make sure that if some new peers join, we also try to ask them
296
- const result = await promise;
297
- this._readFromPeersPromises.delete(cidString);
298
- // stop asking new peers, because we already got an response
299
- this._events.removeEventListener("peer:reachable", publishOnNewPeers);
300
- 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
+ }
301
490
  }
302
491
  else {
303
492
  const result = await promise;
@@ -314,6 +503,7 @@ export class RemoteBlocks {
314
503
  this._readFromPeersPromises.clear();
315
504
  this._resolvers.clear();
316
505
  this._blockCache?.clear();
506
+ this._providerCache?.clear();
317
507
  this._open = false;
318
508
  // we dont cleanup subscription because we dont know if someone else is sbuscribing also
319
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.7",
3
+ "version": "3.1.8-000e3f1",
4
4
  "description": "Block store streaming",
5
5
  "type": "module",
6
6
  "types": "./dist/src/index.d.ts",
@@ -68,27 +68,27 @@
68
68
  "dao.xyz"
69
69
  ],
70
70
  "devDependencies": {
71
- "@peerbit/libp2p-test-utils": "2.2.0"
71
+ "@peerbit/libp2p-test-utils": "2.2.0-000e3f1"
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-000e3f1",
79
+ "@peerbit/any-store-interface": "1.1.0-000e3f1",
80
+ "@peerbit/cache": "2.2.0-000e3f1",
81
+ "@peerbit/logger": "2.0.0-000e3f1",
82
+ "@peerbit/stream": "4.6.0-000e3f1",
83
+ "@peerbit/stream-interface": "5.4.0-000e3f1",
84
+ "@peerbit/time": "2.3.0-000e3f1",
85
+ "@peerbit/blocks-interface": "1.5.2-000e3f1",
86
+ "@peerbit/crypto": "2.4.1-000e3f1",
78
87
  "@ipld/dag-cbor": "^9.2.1",
79
88
  "multiformats": "^13.4.1",
80
89
  "p-defer": "^4.0.0",
81
90
  "p-queue": "^8.0.1",
82
- "uint8arrays": "^5.1.0",
83
- "@peerbit/any-store": "2.2.4",
84
- "@peerbit/any-store-interface": "1.1.0",
85
- "@peerbit/cache": "2.2.0",
86
- "@peerbit/logger": "2.0.0",
87
- "@peerbit/stream": "4.6.0",
88
- "@peerbit/stream-interface": "5.4.0",
89
- "@peerbit/time": "2.3.0",
90
- "@peerbit/blocks-interface": "1.5.2",
91
- "@peerbit/crypto": "2.4.1"
91
+ "uint8arrays": "^5.1.0"
92
92
  },
93
93
  "scripts": {
94
94
  "clean": "aegir clean",
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
@@ -11,9 +11,8 @@ import {
11
11
  import { Cache } from "@peerbit/cache";
12
12
  import { PublicSignKey } from "@peerbit/crypto";
13
13
  import { logger as loggerFn } from "@peerbit/logger";
14
- import type { PublishOptions } from "@peerbit/stream";
14
+ import { type PublishOptions, dontThrowIfDeliveryError } from "@peerbit/stream";
15
15
  import {
16
- AnyWhere,
17
16
  type PeerRefs,
18
17
  SilentDelivery,
19
18
  type WaitForAnyOpts,
@@ -62,8 +61,12 @@ export class RemoteBlocks implements IBlocks {
62
61
  localStore: BlockStore;
63
62
 
64
63
  private _responseHandler?: (data: BlockMessage, from?: string) => any;
65
- private _resolvers: Map<string, (data: Uint8Array) => void>;
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,15 +147,43 @@ 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 {
112
172
  if (message instanceof BlockRequest && this.localStore) {
113
- this._loadFetchQueue.add(() =>
114
- this.handleFetchRequest(message, localTimeout, from),
115
- );
173
+ this._loadFetchQueue
174
+ .add(() => this.handleFetchRequest(message, localTimeout, from))
175
+ .catch((e) => {
176
+ try {
177
+ dontThrowIfDeliveryError(e);
178
+ } catch (error) {
179
+ logger.error("Got error for libp2p block transport: ", error);
180
+ }
181
+ });
116
182
  } else if (message instanceof BlockResponse) {
117
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
+ }
118
187
  let resolver = this._resolvers.get(message.cid);
119
188
  if (!resolver) {
120
189
  if (options.eagerBlocks) {
@@ -122,7 +191,7 @@ export class RemoteBlocks implements IBlocks {
122
191
  this._blockCache!.add(message.cid, message.bytes);
123
192
  }
124
193
  } else {
125
- resolver(message.bytes);
194
+ await resolver(message.bytes);
126
195
  }
127
196
  }
128
197
  } catch (error) {
@@ -132,40 +201,118 @@ export class RemoteBlocks implements IBlocks {
132
201
  };
133
202
  }
134
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
+
135
266
  async put(
136
267
  bytes: Uint8Array | { block: Block<any, any, any, any>; cid: string },
137
268
  ): Promise<string> {
138
269
  if (!this.localStore) {
139
270
  throw new Error("Local store not set");
140
271
  }
141
- 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;
142
279
  }
143
280
 
144
281
  async has(cid: string) {
145
282
  return this.localStore.has(cid);
146
283
  }
284
+
147
285
  async get(
148
286
  cid: string,
149
287
  options?: GetOptions | undefined,
150
288
  ): Promise<Uint8Array | undefined> {
151
- const cidObject = cidifyString(cid);
152
289
  let value = this.localStore
153
290
  ? await this.localStore.get(cid, options)
154
291
  : undefined;
155
292
 
156
293
  if (!value) {
157
294
  // try to get it remotelly
158
- let remoteOptions = options?.remote === true ? {} : options?.remote;
295
+ const remoteOptions = options?.remote === true ? {} : options?.remote;
159
296
  if (remoteOptions) {
297
+ const cidObject = cidifyString(cid);
160
298
  value = await this._readFromPeers(cid, cidObject, remoteOptions);
161
299
  if (remoteOptions?.replicate && value) {
162
- await this.localStore!.put(value);
300
+ await this.put(value);
163
301
  }
164
302
  }
165
303
  }
304
+
166
305
  return value;
167
306
  }
168
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
+
169
316
  async rm(cid: string) {
170
317
  await this.localStore?.rm(cid);
171
318
  }
@@ -202,16 +349,50 @@ export class RemoteBlocks implements IBlocks {
202
349
  return;
203
350
  }
204
351
  const cid = stringifyCid(request.cid);
205
- const bytes = await this.localStore.get(cid, {
352
+ let bytes = await this.localStore.get(cid, {
206
353
  remote: {
207
354
  timeout: localTimeout,
208
355
  },
209
356
  });
210
357
 
211
358
  if (!bytes) {
212
- 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
+ }
213
390
  }
214
- await this.options.publish(new BlockResponse(cid, bytes), { to: [from] });
391
+
392
+ if (!bytes) return;
393
+ await this.options
394
+ .publish(new BlockResponse(cid, bytes), { to: [from] })
395
+ .catch(dontThrowIfDeliveryError);
215
396
  }
216
397
 
217
398
  private async _readFromPeers(
@@ -247,38 +428,54 @@ export class RemoteBlocks implements IBlocks {
247
428
  }
248
429
  }
249
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
+
250
448
  let promise = this._readFromPeersPromises.get(cidString);
251
449
  if (!promise) {
252
450
  promise = new Promise<Block<any, any, any, 1> | undefined>(
253
451
  (resolve, reject) => {
254
- const timeoutCallback = setTimeout(
255
- () => {
256
- resolve(undefined);
257
- },
258
- options.timeout || 30 * 1000,
259
- );
452
+ let timeoutCallback: ReturnType<typeof setTimeout> | undefined;
260
453
  const abortHandler = () => {
261
- clearTimeout(timeoutCallback);
454
+ cleanup();
455
+ reject(new AbortError());
456
+ };
457
+
458
+ const cleanup = () => {
459
+ if (timeoutCallback) clearTimeout(timeoutCallback);
262
460
  this._resolvers.delete(cidString);
263
461
  this.closeController.signal.removeEventListener(
264
462
  "abort",
265
463
  abortHandler,
266
464
  );
267
465
  options?.signal?.removeEventListener("abort", abortHandler);
268
- reject(new AbortError());
269
466
  };
467
+
468
+ timeoutCallback = setTimeout(() => {
469
+ cleanup();
470
+ resolve(undefined);
471
+ }, options.timeout || 30 * 1000);
472
+
270
473
  this.closeController.signal.addEventListener("abort", abortHandler);
271
474
  options?.signal?.addEventListener("abort", abortHandler);
272
475
 
273
476
  this._resolvers.set(cidString, async (bytes: Uint8Array) => {
274
477
  const value = await tryDecode(bytes);
275
-
276
- clearTimeout(timeoutCallback);
277
- this._resolvers.delete(cidString); // TODO concurrency might not work as expected here
278
- this.closeController.signal.removeEventListener(
279
- "abort",
280
- abortHandler,
281
- );
478
+ cleanup();
282
479
  resolve(value);
283
480
  });
284
481
  },
@@ -286,31 +483,50 @@ export class RemoteBlocks implements IBlocks {
286
483
 
287
484
  this._readFromPeersPromises.set(cidString, promise);
288
485
 
289
- const publishOnNewPeers = (e: CustomEvent<PublicSignKey>) => {
290
- const to = e.detail.hashcode();
291
- if (!options?.from || options.from.includes(to)) {
292
- return this.options.publish(new BlockRequest(cidString), {
293
- // We dont sent explicitly to 'to' here because we want the message to propagate beyond the first peer
294
- to: [to],
295
- mode: new AnyWhere(),
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,
296
492
  });
297
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);
502
+ }
298
503
  };
299
504
 
300
- this._events.addEventListener("peer:reachable", publishOnNewPeers);
301
- await this.options.publish(new BlockRequest(cidString), {
302
- mode: options.from
303
- ? new SilentDelivery({ to: options.from, redundancy: 1 })
304
- : new AnyWhere(),
305
- });
306
- // 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
+ };
307
511
 
308
- const result = await promise;
309
- 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
+ };
310
518
 
311
- // stop asking new peers, because we already got an response
312
- this._events.removeEventListener("peer:reachable", publishOnNewPeers);
313
- 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
+ }
314
530
  } else {
315
531
  const result = await promise;
316
532
  return result?.bytes;
@@ -328,6 +544,7 @@ export class RemoteBlocks implements IBlocks {
328
544
  this._readFromPeersPromises.clear();
329
545
  this._resolvers.clear();
330
546
  this._blockCache?.clear();
547
+ this._providerCache?.clear();
331
548
  this._open = false;
332
549
  // we dont cleanup subscription because we dont know if someone else is sbuscribing also
333
550
  }