@peerbit/pubsub 5.4.4 → 5.4.5

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.
@@ -166,6 +166,7 @@ export declare class TopicControlPlane extends DirectStream<PubSubEvents> implem
166
166
  private hostOwnedShardRootsInFlight?;
167
167
  private hostOwnedShardRootsDirty;
168
168
  private readonly signedTopicRootCandidateClaims;
169
+ private readonly suppressedDepartedTopicRootCandidateClaims;
169
170
  private readonly topicRootCandidateClaimReplayFloors;
170
171
  private localSignedTopicRootCandidateClaim?;
171
172
  private topicRootCandidateClaimMaintenanceTimer?;
@@ -211,6 +212,7 @@ export declare class TopicControlPlane extends DirectStream<PubSubEvents> implem
211
212
  private pruneExpiredTopicRootCandidateClaims;
212
213
  private rebuildAutoTopicRootCandidatesFromClaims;
213
214
  private retainSignedTopicRootCandidateClaim;
215
+ private isDepartedTopicRootCandidateClaimSuppressed;
214
216
  private canAdvanceTopicRootCandidateClaimReplayFloor;
215
217
  private canRetainTopicRootCandidateClaimOrigin;
216
218
  private consumeTopicRootCandidateClaimVerifyBudget;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EACN,aAAa,EAGb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAIN,KAAK,MAAM,EAEX,KAAK,YAAY,EAIjB,gBAAgB,EAehB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACN,YAAY,EACZ,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAEhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEN,mBAAmB,EAEnB,WAAW,EAEX,KAAK,gBAAgB,EACrB,KAAK,SAAS,EAGd,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,SAAS,EACd,cAAc,EACd,KAAK,gBAAgB,EAOrB,MAAM,2BAA2B,CAAC;AAUnC,OAAO,KAAK,EACX,UAAU,EACV,wBAAwB,EAExB,qBAAqB,EACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,qBAAqB,EACrB,KAAK,0BAA0B,EAC/B,MAAM,+BAA+B,CAAC;AAEvC,cAAc,kBAAkB,CAAC;AAIjC,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,mBAAmB,MAAM,iCAAiC,CAAC;AACvE,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,eAAO,MAAM,MAAM,oCAAoD,CAAC;AAsKxE,MAAM,MAAM,wBAAwB,GAAG,mBAAmB,GAAG;IAC5D,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;IAC9C;;OAEG;IACH,MAAM,EAAE,UAAU,CAAC;IACnB;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC,CAAC;IAChE;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC,CAAC;IACpE;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC,CAAC;IACpE;;OAEG;IACH,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,8BAA8B,CAAC,EAAE,OAAO,CAAC;IACzC;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC;;;;OAIG;IACH,iCAAiC,CAAC,EAAE,MAAM,CAAC;IAC3C;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACnC,CAAC;AAUF,MAAM,MAAM,2BAA2B,GAAG,sBAAsB,CAAC;AAEjE,MAAM,MAAM,MAAM,GAAG,YAAY,GAAG,aAAa,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CAAC;IACvD,MAAM,EAAE,QAAQ,CAAC;QAChB,IAAI,EAAE,QAAQ,CAAC;YAAE,cAAc,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC3C,IAAI,EAAE,QAAQ,CAAC;YAAE,cAAc,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC3C,CAAC,CAAC;CACH,CAAC,CAAC;AAWH;;GAEG;AACH,qBAAa,iBACZ,SAAQ,YAAY,CAAC,YAAY,CACjC,YAAW,MAAM;IAGV,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAEnD,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAEtC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEvD,OAAO,CAAC,oBAAoB,CAAc;IAC1C;;;;;;OAMG;IACH,OAAO,CAAC,0BAA0B,CAOpB;IACP,wBAAwB,EAAE,GAAG,CACnC,MAAM,EACN,GAAG,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CACnD,CAAa;IACP,0BAA0B,EAAE,OAAO,CAAC;IAC3C,SAAgB,qBAAqB,EAAE,qBAAqB,CAAC;IAC7D,SAAgB,yBAAyB,EAAE,MAAM,CAAC;IAClD,SAAgB,MAAM,EAAE,UAAU,CAAC;IAOnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAmB;IAEvD,OAAO,CAAC,2BAA2B,CAAiC;IACpE,OAAO,CAAC,6BAA6B,CAAiC;IAEtE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAa;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAG3B;IACJ,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA6B;IAC7D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAElD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAGvC;IACF,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAGvC;IACF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAwB;IAC3D,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAU;IACzD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAClD,OAAO,CAAC,QAAQ,CAAC,iCAAiC,CAAS;IAK3D,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,yBAAyB,CAAC,CAAc;IAChD,OAAO,CAAC,8BAA8B,CAAC,CAAW;IAClD,OAAO,CAAC,iCAAiC,CAAC,CAAgC;IAC1E,OAAO,CAAC,8BAA8B,CAAC,CAAgB;IACvD,OAAO,CAAC,2BAA2B,CAAS;IAC5C,OAAO,CAAC,yBAAyB,CAAS;IAC1C,OAAO,CAAC,kCAAkC,CAAK;IAC/C,OAAO,CAAC,kCAAkC,CAAyB;IACnE,OAAO,CAAC,sCAAsC,CAAC,CAAS;IACxD,OAAO,CAAC,2CAA2C,CAAyB;IAC5E,OAAO,CAAC,2BAA2B,CAAC,CAAgB;IACpD,OAAO,CAAC,wBAAwB,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAG3C;IAMJ,OAAO,CAAC,QAAQ,CAAC,0CAA0C,CAGvD;IAIJ,OAAO,CAAC,QAAQ,CAAC,mCAAmC,CAGhD;IACJ,OAAO,CAAC,kCAAkC,CAAC,CAAgC;IAC3E,OAAO,CAAC,uCAAuC,CAAC,CAE9C;IACF,OAAO,CAAC,uCAAuC,CAAC,CAAS;IACzD,OAAO,CAAC,iDAAiD,CAAC,CAAgB;IAC1E,OAAO,CAAC,QAAQ,CAAC,oCAAoC,CAGjD;IACJ,OAAO,CAAC,yCAAyC,CAG/C;IACF,OAAO,CAAC,wBAAwB,CAAC,CAEvB;IAEV,OAAO,CAAC,cAAc,CAYlB;IACJ,OAAO,CAAC,2BAA2B,CAS/B;IACJ,OAAO,CAAC,uBAAuB,CAQ3B;IACJ,OAAO,CAAC,oBAAoB,CAAK;gBAGhC,UAAU,EAAE,2BAA2B,EACvC,KAAK,CAAC,EAAE,wBAAwB;IAwHjC;;OAEG;IACI,kBAAkB,IAAI,gCAAgC;IAmB7D;;;;;;;;;;;OAWG;IACI,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE;IAmB5B,KAAK;IAiDL,IAAI;IA6EV,OAAO,CACtB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACZ,WAAW;cA2CW,WAAW,CAAC,SAAS,EAAE,aAAa;IAyC7D,OAAO,CAAC,yDAAyD;IA4BjE,OAAO,CAAC,iCAAiC;IAOzC,OAAO,CAAC,kCAAkC;IAe1C,OAAO,CAAC,kCAAkC;IAY1C,OAAO,CAAC,yCAAyC;YAgBnC,mCAAmC;IAiEjD,OAAO,CAAC,0CAA0C;IA2FlD,OAAO,CAAC,8CAA8C;IA+DtD,OAAO,CAAC,oCAAoC;IAsB5C,OAAO,CAAC,wCAAwC;IAqChD,OAAO,CAAC,mCAAmC;IA2C3C,OAAO,CAAC,2CAA2C;IAYnD,OAAO,CAAC,4CAA4C;IAWpD,OAAO,CAAC,sCAAsC;IAe9C,OAAO,CAAC,0CAA0C;YA+CpC,mCAAmC;YAwHnC,kCAAkC;YAsClC,2BAA2B;IAoCzC,OAAO,CAAC,iCAAiC;IAqCzC,OAAO,CAAC,4BAA4B;IAQpC,OAAO,CAAC,4CAA4C;IAUpD,OAAO,CAAC,wCAAwC;IAuBhD,OAAO,CAAC,yCAAyC;IAQjD,OAAO,CAAC,2BAA2B;IAyBnC,OAAO,CAAC,8BAA8B;YA+CxB,sBAAsB;IAoCpC,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,sBAAsB;IAyB9B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,4BAA4B;IAwBpC,OAAO,CAAC,yBAAyB;IAejC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA+C3B;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAsD3B,OAAO,CAAC,+BAA+B;IAOvC,OAAO,CAAC,6BAA6B;IAWrC,OAAO,CAAC,sCAAsC;YAiBhC,gCAAgC;IA2C9C,OAAO,CAAC,2BAA2B;YAiBrB,qBAAqB;IAgGtB,gBAAgB,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,0BAA0B,GAClC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;YAYhB,qBAAqB;IAwDnC,OAAO,CAAC,6BAA6B;IAYrC,OAAO,CAAC,2BAA2B;YAYrB,wBAAwB;IAyBtC,OAAO,CAAC,4BAA4B;YAkBtB,sBAAsB;YAoFtB,sBAAsB;YAsCtB,yBAAyB;YAmDzB,4BAA4B;YAwF5B,mBAAmB;YA6GnB,uBAAuB;YA8QvB,kBAAkB;IAgCnB,iBAAiB,CAAC,OAAO,CAAC,EAAE,0BAA0B;IAqF7D,SAAS,CAAC,KAAK,EAAE,MAAM;YAQf,UAAU;IAqDlB,WAAW,CAChB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,IAAI,CAAC,EAAE,UAAU,CAAC;KAClB;YA4CY,oBAAoB;YAqDpB,uBAAuB;YAgEvB,8BAA8B;IA4B5C,OAAO,CAAC,uBAAuB;IAS/B,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,GAAG,SAAS;IAa1D;;;;OAIG;IACH,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE;IA4B9D,kBAAkB,CACvB,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EACxB,EAAE,CAAC,EAAE,aAAa,GAChB,OAAO,CAAC,IAAI,CAAC;IA0DV,OAAO,CACZ,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,OAAO,CAAC,EAAE;QACT,MAAM,EAAE,MAAM,EAAE,CAAC;KACjB,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QACzB,IAAI,CAAC,EAAE,cAAc,GAAG,mBAAmB,CAAC;KAC5C,GAAG,eAAe,GAClB,uBAAuB,GACvB,gBAAgB,GAChB,SAAS,GACT,gBAAgB,GAAG;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IA8HlC;;;;;;;;;;OAUG;IACG,qBAAqB,CAC1B,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE;QACX,MAAM,EAAE,MAAM,EAAE,CAAC;KACjB,EACD,OAAO,EAAE;QACR,IAAI,EAAE,cAAc,GAAG,mBAAmB,CAAC;KAC3C,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,eAAe,GACxC,uBAAuB,GACvB,gBAAgB,GAChB,SAAS,GACT,gBAAgB,GAAG;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IA+C3B,aAAa,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAWhD,iBAAiB,CAAC,aAAa,EAAE,MAAM;IA2BvD,OAAO,CAAC,wBAAwB;IA8BhC,OAAO,CAAC,gCAAgC;IAoCxC,OAAO,CAAC,mBAAmB;IA8B3B,OAAO,CAAC,yBAAyB;IA0DjC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAa9B,OAAO,CAAC,2BAA2B;IAcnC;;;;;;;OAOG;IACH,OAAO,CAAC,uBAAuB;YAiCjB,wBAAwB;YA+BxB,4BAA4B;YA+B5B,0BAA0B;YAiL1B,yBAAyB;IAgNjB,aAAa,CAClC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM;CAsFnB;AAED,eAAO,MAAM,kBAAkB,GAC9B,QAAQ;IAAE,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACxC,aACG,MAAM,GACN,MAAM,EAAE,GACR;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,EAAE,GAC1B,MAAM,GACN,MAAM,EAAE,EACX,OAAO,MAAM,EACb,UAAU;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,kBAiKpD,CAAC"}
package/dist/src/index.js CHANGED
@@ -134,9 +134,15 @@ const TOPIC_ROOT_CANDIDATE_CLAIM_VERIFY_REFILL_MS = 60_000;
134
134
  const TOPIC_ROOT_CANDIDATE_CLAIM_VERIFY_PEERS_MAX = 4_096;
135
135
  const sameCandidates = (left, right) => left.length === right.length &&
136
136
  left.every((candidate, index) => candidate === right[index]);
137
- // Topic-root queries may need to wait for the responder to finish opening an
138
- // outbound stream back to the requester after an inbound-only dial.
137
+ // Retain the previous 12 second allowance as one deadline for the complete
138
+ // peer-query phase. It must not multiply by peer count or retry count.
139
139
  const DEFAULT_TOPIC_ROOT_QUERY_TIMEOUT_MS = 12_000;
140
+ // A responder may need to open an outbound stream after an inbound-only dial.
141
+ // Bounded rounds leave enough time for that setup while still allowing a lost
142
+ // request or a newly-ready stream to be retried within the phase deadline.
143
+ const TOPIC_ROOT_QUERY_ROUND_TIMEOUT_MS = 3_000;
144
+ const TOPIC_ROOT_HOST_SCAN_TIMEOUT_MS = DEFAULT_TOPIC_ROOT_QUERY_TIMEOUT_MS;
145
+ const TOPIC_ROOT_HOST_SCAN_CONCURRENCY = 8;
140
146
  const DIRECT_SHARD_ROOT_CONFIRM_TIMEOUT_MS = 2_000;
141
147
  const DEFAULT_PUBSUB_FANOUT_CHANNEL_OPTIONS = {
142
148
  msgRate: 30,
@@ -218,6 +224,12 @@ export class TopicControlPlane extends DirectStream {
218
224
  hostOwnedShardRootsInFlight;
219
225
  hostOwnedShardRootsDirty = false;
220
226
  signedTopicRootCandidateClaims = new Map();
227
+ // A directly observed departure makes only that origin's current lease
228
+ // ineffective locally. This is not a component-wide withdrawal: claims learned
229
+ // only through relays keep their existing lease semantics. Keeping the verified
230
+ // bytes + replay floor prevents a relay from resurrecting the departed lease;
231
+ // the map is bounded by the same retained-origin cap as the claim map.
232
+ suppressedDepartedTopicRootCandidateClaims = new Map();
221
233
  // Active claims expire, but their per-origin timestamp floors survive for the
222
234
  // auto-mode lifecycle so a frozen wall clock cannot renew a replayed lease.
223
235
  // Retaining only the deterministic lowest origins keeps this state hard-bounded.
@@ -494,12 +506,28 @@ export class TopicControlPlane extends DirectStream {
494
506
  const protocol = this.peers.get(hash)?.protocol;
495
507
  const hadSignedPeer = [...this.peers.values()].some((peer) => peer.protocol === TOPIC_CONTROL_PLANE_PROTOCOL_V2_1);
496
508
  const removed = await super._removePeer(publicKey);
509
+ let suppressedDepartedOrigin = false;
510
+ if (removed &&
511
+ this.autoTopicRootCandidates &&
512
+ protocol === TOPIC_CONTROL_PLANE_PROTOCOL_V2_1 &&
513
+ this.signedTopicRootCandidateClaims.has(hash)) {
514
+ const claim = this.signedTopicRootCandidateClaims.get(hash);
515
+ const suppressed = this.suppressedDepartedTopicRootCandidateClaims.get(hash);
516
+ suppressedDepartedOrigin =
517
+ !suppressed ||
518
+ suppressed.timestamp !== claim.timestamp ||
519
+ !bytesEqual(suppressed.bytes, claim.bytes);
520
+ this.suppressedDepartedTopicRootCandidateClaims.set(hash, {
521
+ bytes: claim.bytes,
522
+ timestamp: claim.timestamp,
523
+ });
524
+ }
497
525
  if (this.autoTopicRootCandidates &&
498
526
  (protocol === TOPIC_CONTROL_PLANE_PROTOCOL_V2_0 ||
499
527
  protocol === TOPIC_CONTROL_PLANE_PROTOCOL_V2_1)) {
500
528
  const hasSignedPeer = [...this.peers.values()].some((peer) => peer.protocol === TOPIC_CONTROL_PLANE_PROTOCOL_V2_1);
501
529
  this.rebuildAutoTopicRootCandidatesFromClaims(BigInt(Date.now()), {
502
- immediate: hadSignedPeer !== hasSignedPeer,
530
+ immediate: suppressedDepartedOrigin || hadSignedPeer !== hasSignedPeer,
503
531
  });
504
532
  }
505
533
  return removed;
@@ -538,6 +566,7 @@ export class TopicControlPlane extends DirectStream {
538
566
  clearSignedTopicRootCandidateState() {
539
567
  this.clearTopicRootCandidateClaimTimer();
540
568
  this.signedTopicRootCandidateClaims.clear();
569
+ this.suppressedDepartedTopicRootCandidateClaims.clear();
541
570
  this.topicRootCandidateClaimReplayFloors.clear();
542
571
  this.localSignedTopicRootCandidateClaim = undefined;
543
572
  this.topicRootCandidateClaimRefreshNotBefore = undefined;
@@ -749,6 +778,7 @@ export class TopicControlPlane extends DirectStream {
749
778
  for (const [origin, claim] of this.signedTopicRootCandidateClaims) {
750
779
  if (claim.expires <= now || claim.acceptUntil <= monotonicNow) {
751
780
  this.signedTopicRootCandidateClaims.delete(origin);
781
+ this.suppressedDepartedTopicRootCandidateClaims.delete(origin);
752
782
  changed = true;
753
783
  }
754
784
  }
@@ -768,7 +798,9 @@ export class TopicControlPlane extends DirectStream {
768
798
  ? []
769
799
  : [this.publicKeyHash]),
770
800
  ...legacyDirectCandidates,
771
- ...this.signedTopicRootCandidateClaims.keys(),
801
+ ...[...this.signedTopicRootCandidateClaims.entries()]
802
+ .filter(([origin, claim]) => !this.isDepartedTopicRootCandidateClaimSuppressed(origin, claim))
803
+ .map(([origin]) => origin),
772
804
  ]),
773
805
  ]
774
806
  .filter(isCanonicalTopicRootCandidate)
@@ -802,6 +834,7 @@ export class TopicControlPlane extends DirectStream {
802
834
  // because the retained maximum only decreases, it cannot re-enter.
803
835
  this.topicRootCandidateClaimReplayFloors.delete(highest);
804
836
  this.signedTopicRootCandidateClaims.delete(highest);
837
+ this.suppressedDepartedTopicRootCandidateClaims.delete(highest);
805
838
  if (highest === this.publicKeyHash) {
806
839
  this.localSignedTopicRootCandidateClaim = undefined;
807
840
  }
@@ -809,8 +842,14 @@ export class TopicControlPlane extends DirectStream {
809
842
  }
810
843
  this.topicRootCandidateClaimReplayFloors.set(origin, claim.timestamp);
811
844
  this.signedTopicRootCandidateClaims.set(origin, claim);
845
+ this.suppressedDepartedTopicRootCandidateClaims.delete(origin);
812
846
  return true;
813
847
  }
848
+ isDepartedTopicRootCandidateClaimSuppressed(origin, claim) {
849
+ const suppressed = this.suppressedDepartedTopicRootCandidateClaims.get(origin);
850
+ return (suppressed?.timestamp === claim.timestamp &&
851
+ bytesEqual(suppressed.bytes, claim.bytes));
852
+ }
814
853
  canAdvanceTopicRootCandidateClaimReplayFloor(origin, timestamp) {
815
854
  const floor = this.topicRootCandidateClaimReplayFloors.get(origin);
816
855
  if (floor !== undefined) {
@@ -871,7 +910,7 @@ export class TopicControlPlane extends DirectStream {
871
910
  this.topicRootCandidateClaimGlobalVerifyBudget.remaining -= 1;
872
911
  return true;
873
912
  }
874
- async importSignedTopicRootCandidateClaim(rawClaim, outerPeerHash) {
913
+ async importSignedTopicRootCandidateClaim(rawClaim, outerPeerHash, expectedPeer) {
875
914
  const lifecycleRevision = this.topicControlPlaneLifecycleRevision;
876
915
  if (rawClaim.byteLength === 0 ||
877
916
  rawClaim.byteLength > TOPIC_ROOT_CANDIDATE_CLAIM_MAX_BYTES) {
@@ -910,10 +949,30 @@ export class TopicControlPlane extends DirectStream {
910
949
  if (acceptanceDeadline === undefined) {
911
950
  return false;
912
951
  }
952
+ this.rebuildAutoTopicRootCandidatesFromClaims(now);
953
+ const retained = this.signedTopicRootCandidateClaims.get(origin);
954
+ if (outerPeerHash === origin &&
955
+ expectedPeer !== undefined &&
956
+ expectedPeer.protocol === TOPIC_CONTROL_PLANE_PROTOCOL_V2_1 &&
957
+ this.peers.get(outerPeerHash) === expectedPeer &&
958
+ lifecycleRevision === this.topicControlPlaneLifecycleRevision &&
959
+ this.autoTopicRootCandidates &&
960
+ this.started &&
961
+ !this.stopping &&
962
+ !this.topicControlPlaneStopping &&
963
+ retained?.timestamp === timestamp &&
964
+ bytesEqual(retained.bytes, rawClaim) &&
965
+ this.isDepartedTopicRootCandidateClaimSuppressed(origin, retained)) {
966
+ // These exact bytes were already verified and remain under the original
967
+ // monotonic acceptance deadline. A current authenticated origin stream is
968
+ // sufficient liveness evidence; do not advance the floor or lease.
969
+ this.suppressedDepartedTopicRootCandidateClaims.delete(origin);
970
+ this.rebuildAutoTopicRootCandidatesFromClaims(now, { immediate: true });
971
+ return false;
972
+ }
913
973
  if (!this.canAdvanceTopicRootCandidateClaimReplayFloor(origin, timestamp)) {
914
974
  return false;
915
975
  }
916
- this.rebuildAutoTopicRootCandidatesFromClaims(now);
917
976
  if (!this.consumeTopicRootCandidateClaimVerifyBudget(outerPeerHash)) {
918
977
  return false;
919
978
  }
@@ -933,7 +992,9 @@ export class TopicControlPlane extends DirectStream {
933
992
  !this.autoTopicRootCandidates ||
934
993
  !this.started ||
935
994
  this.stopping ||
936
- this.topicControlPlaneStopping) {
995
+ this.topicControlPlaneStopping ||
996
+ (expectedPeer !== undefined &&
997
+ this.peers.get(outerPeerHash) !== expectedPeer)) {
937
998
  return false;
938
999
  }
939
1000
  if (!this.retainSignedTopicRootCandidateClaim(origin, {
@@ -985,6 +1046,7 @@ export class TopicControlPlane extends DirectStream {
985
1046
  }
986
1047
  }
987
1048
  const claims = [...this.signedTopicRootCandidateClaims.entries()]
1049
+ .filter(([origin, claim]) => !this.isDepartedTopicRootCandidateClaimSuppressed(origin, claim))
988
1050
  .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
989
1051
  .map(([, claim]) => claim.bytes);
990
1052
  await this.sendSignedTopicRootCandidateClaims(claims, signedStreams);
@@ -1483,27 +1545,68 @@ export class TopicControlPlane extends DirectStream {
1483
1545
  if (tracked) {
1484
1546
  return { root: tracked, authoritative: true };
1485
1547
  }
1486
- const resolvedThroughPeers = await this.resolveTopicRootThroughPeers(topic, options);
1487
- if (resolvedThroughPeers) {
1488
- // Unconfigured peer-query replies cannot override the locally
1489
- // deterministic root for internal shards in auto mode. Roots, resolvers,
1490
- // and trackers explicitly configured on this control plane are resolved
1491
- // above and remain authoritative. A leaf relying on a queried gateway for
1492
- // shard roots must first disable auto mode with setTopicRootCandidates([]).
1493
- return this.normalizePeerTopicRootState(topic, resolvedThroughPeers);
1548
+ if (options?.queryConnectedPeers === false) {
1549
+ return {
1550
+ root: this.topicRootControlPlane.resolveDeterministicTopicRoot(topic),
1551
+ authoritative: false,
1552
+ };
1494
1553
  }
1495
- const deterministic = this.topicRootControlPlane.resolveDeterministicTopicRoot(topic);
1496
- if (deterministic === this.publicKeyHash &&
1497
- this.autoTopicRootCandidates &&
1498
- this.getConnectedTopicRootTrackers().length > 0) {
1499
- for (let attempt = 0; attempt < 8; attempt++) {
1500
- await withAbort(delay(150 * (attempt < 4 ? 1 : 2), options), options?.signal);
1501
- const retried = await this.resolveTopicRootThroughPeers(topic, options);
1502
- if (retried) {
1503
- return this.normalizePeerTopicRootState(topic, retried);
1554
+ const deadlineController = new AbortController();
1555
+ const deadlineTimer = setTimeout(() => deadlineController.abort(new AbortError("topic root peer-query deadline reached")), DEFAULT_TOPIC_ROOT_QUERY_TIMEOUT_MS);
1556
+ deadlineTimer.unref?.();
1557
+ const querySignals = linkAbortSignals([
1558
+ options?.signal,
1559
+ deadlineController.signal,
1560
+ ]);
1561
+ try {
1562
+ let attempt = 0;
1563
+ for (;;) {
1564
+ throwIfAborted(querySignals.signal);
1565
+ // Preserve the immediate deterministic fallback when no queryable stream
1566
+ // exists at entry. Once a peer was queryable, keep the bounded readiness
1567
+ // window alive: later rounds re-snapshot streams that can become writable
1568
+ // after an inbound-only dial.
1569
+ if (attempt === 0 &&
1570
+ this.getConnectedTopicRootTrackers().length === 0) {
1571
+ break;
1572
+ }
1573
+ if (attempt > 0) {
1574
+ await withAbort(delay(150 * Math.min(attempt, 2), {
1575
+ signal: querySignals.signal,
1576
+ }), querySignals.signal);
1577
+ }
1578
+ attempt += 1;
1579
+ const resolvedThroughPeers = await this.resolveTopicRootThroughPeers(topic, {
1580
+ signal: querySignals.signal,
1581
+ timeoutMs: TOPIC_ROOT_QUERY_ROUND_TIMEOUT_MS,
1582
+ });
1583
+ if (resolvedThroughPeers !== undefined) {
1584
+ // Unconfigured peer-query replies cannot override the locally
1585
+ // deterministic root for internal shards in auto mode. Roots,
1586
+ // resolvers, and trackers explicitly configured on this control
1587
+ // plane are resolved above and remain authoritative. A leaf relying
1588
+ // on a queried gateway for shard roots must first disable auto mode
1589
+ // with setTopicRootCandidates([]).
1590
+ return this.normalizePeerTopicRootState(topic, resolvedThroughPeers);
1504
1591
  }
1505
1592
  }
1506
1593
  }
1594
+ catch (error) {
1595
+ // Candidate, lifecycle, and caller cancellation are terminal to this
1596
+ // invocation and must retain their exact reason. Only the private phase
1597
+ // deadline falls through to the same deterministic result as exhausted
1598
+ // peer queries.
1599
+ if (options?.signal?.aborted) {
1600
+ throw options.signal.reason ?? error;
1601
+ }
1602
+ if (!deadlineController.signal.aborted) {
1603
+ throw error;
1604
+ }
1605
+ }
1606
+ finally {
1607
+ clearTimeout(deadlineTimer);
1608
+ querySignals.clear();
1609
+ }
1507
1610
  return {
1508
1611
  root: this.topicRootControlPlane.resolveDeterministicTopicRoot(topic),
1509
1612
  authoritative: false,
@@ -1527,8 +1630,13 @@ export class TopicControlPlane extends DirectStream {
1527
1630
  this.maybeDisableAutoTopicRootCandidatesIfExternallyConfigured();
1528
1631
  }
1529
1632
  const candidateGeneration = this.getTopicRootCandidateGeneration();
1530
- const hasConnectedTrackers = this.getConnectedTopicRootTrackers().length > 0;
1531
- const cached = this.shardRootCache.get(shardTopic);
1633
+ const hasConnectedTrackers = options?.queryConnectedPeers !== false &&
1634
+ this.getConnectedTopicRootTrackers().length > 0;
1635
+ // A proactive local scan must not inherit an authoritative cache entry that
1636
+ // originated from a connected-peer reply under the same candidate generation.
1637
+ const cached = options?.queryConnectedPeers === false
1638
+ ? undefined
1639
+ : this.shardRootCache.get(shardTopic);
1532
1640
  if (cached && (cached.authoritative || !hasConnectedTrackers)) {
1533
1641
  return { root: cached.root, candidateGeneration };
1534
1642
  }
@@ -1569,7 +1677,7 @@ export class TopicControlPlane extends DirectStream {
1569
1677
  requestId = this.nextTopicRootQueryId >>> 0;
1570
1678
  } while (true);
1571
1679
  }
1572
- async sendDirectControlMessage(peer, pubsubMessage) {
1680
+ async sendDirectControlMessage(peer, pubsubMessage, signal) {
1573
1681
  const embedded = await this.createMessage(this.encodePubSubMessage(pubsubMessage), {
1574
1682
  mode: new SilentDelivery({
1575
1683
  to: [peer.publicKey.hashcode()],
@@ -1578,7 +1686,7 @@ export class TopicControlPlane extends DirectStream {
1578
1686
  priority: 1,
1579
1687
  skipRecipientValidation: true,
1580
1688
  });
1581
- await this.publishMessage(this.publicKey, embedded, [peer]);
1689
+ await this.publishMessage(this.publicKey, embedded, [peer], undefined, signal);
1582
1690
  }
1583
1691
  resolvePendingTopicRootQuery(message, responderPeerHash) {
1584
1692
  const pending = this.pendingTopicRootQueries.get(message.requestId);
@@ -1598,6 +1706,9 @@ export class TopicControlPlane extends DirectStream {
1598
1706
  return undefined;
1599
1707
  const expectedPeerHash = peer.publicKey.hashcode();
1600
1708
  const requestId = this.nextTopicRootRequestIdValue();
1709
+ const queryController = new AbortController();
1710
+ const querySignals = linkAbortSignals([signal, queryController.signal]);
1711
+ let timedOut = false;
1601
1712
  const responsePromise = new Promise((resolve) => {
1602
1713
  let settled = false;
1603
1714
  const settle = (root) => {
@@ -1609,13 +1720,15 @@ export class TopicControlPlane extends DirectStream {
1609
1720
  this.pendingTopicRootQueries.delete(requestId);
1610
1721
  }
1611
1722
  clearTimeout(timer);
1612
- if (signal && onAbort) {
1613
- signal.removeEventListener("abort", onAbort);
1614
- }
1723
+ querySignals.signal.removeEventListener("abort", onAbort);
1615
1724
  resolve(root);
1616
1725
  };
1617
- const onAbort = signal ? () => settle(undefined) : undefined;
1618
- const timer = setTimeout(() => settle(undefined), Math.max(1, Math.floor(timeoutMs)));
1726
+ const onAbort = () => settle(undefined);
1727
+ const timer = setTimeout(() => {
1728
+ timedOut = true;
1729
+ settle(undefined);
1730
+ queryController.abort(new AbortError("topic root query timed out"));
1731
+ }, Math.max(1, Math.floor(timeoutMs)));
1619
1732
  timer.unref?.();
1620
1733
  this.pendingTopicRootQueries.set(requestId, {
1621
1734
  expectedPeerHash,
@@ -1623,26 +1736,39 @@ export class TopicControlPlane extends DirectStream {
1623
1736
  resolve: settle,
1624
1737
  timer,
1625
1738
  });
1626
- if (signal && onAbort) {
1627
- signal.addEventListener("abort", onAbort, { once: true });
1628
- if (signal.aborted)
1629
- onAbort();
1630
- }
1739
+ querySignals.signal.addEventListener("abort", onAbort, { once: true });
1740
+ if (querySignals.signal.aborted)
1741
+ onAbort();
1631
1742
  });
1632
1743
  try {
1633
- await withAbort(this.sendDirectControlMessage(peer, new TopicRootQuery({ requestId, topic })), signal);
1634
- }
1635
- catch (error) {
1636
- const pending = this.pendingTopicRootQueries.get(requestId);
1637
- if (pending) {
1638
- this.pendingTopicRootQueries.delete(requestId);
1639
- clearTimeout(pending.timer);
1640
- pending.resolve(undefined);
1744
+ try {
1745
+ const sending = withAbort(this.sendDirectControlMessage(peer, new TopicRootQuery({ requestId, topic }), querySignals.signal), querySignals.signal);
1746
+ // A write can finish after the request is already on the wire (or stall
1747
+ // while opening the reverse stream). Let either a response or the same
1748
+ // query timeout release this await instead of extending the timeout around
1749
+ // the outbound send.
1750
+ await Promise.race([
1751
+ sending,
1752
+ responsePromise.then(() => undefined),
1753
+ ]);
1641
1754
  }
1642
- if (signal?.aborted)
1643
- throw error;
1755
+ catch (error) {
1756
+ const pending = this.pendingTopicRootQueries.get(requestId);
1757
+ if (pending && !timedOut) {
1758
+ this.pendingTopicRootQueries.delete(requestId);
1759
+ clearTimeout(pending.timer);
1760
+ pending.resolve(undefined);
1761
+ }
1762
+ if (signal?.aborted) {
1763
+ throw signal.reason ?? error;
1764
+ }
1765
+ }
1766
+ return await withAbort(responsePromise, signal);
1767
+ }
1768
+ finally {
1769
+ queryController.abort(new AbortError("topic root query settled"));
1770
+ querySignals.clear();
1644
1771
  }
1645
- return withAbort(responsePromise, signal);
1646
1772
  }
1647
1773
  async confirmDirectShardRoot(shardTopic, root, candidateGeneration, lifecycleRevision, signal) {
1648
1774
  this.assertTopicControlPlaneActive(lifecycleRevision);
@@ -1712,18 +1838,69 @@ export class TopicControlPlane extends DirectStream {
1712
1838
  if (peers.length === 0) {
1713
1839
  return undefined;
1714
1840
  }
1715
- for (let attempt = 0; attempt < 3; attempt++) {
1716
- for (const peer of peers) {
1717
- const resolved = await this.queryTopicRootFromPeer(peer, topic, DEFAULT_TOPIC_ROOT_QUERY_TIMEOUT_MS, options?.signal);
1718
- if (resolved) {
1719
- return resolved;
1841
+ const roundController = new AbortController();
1842
+ const roundTimeoutMs = Math.max(1, Math.floor(options?.timeoutMs ?? DEFAULT_TOPIC_ROOT_QUERY_TIMEOUT_MS));
1843
+ let roundTimedOut = false;
1844
+ const roundTimer = setTimeout(() => {
1845
+ roundTimedOut = true;
1846
+ roundController.abort(new AbortError("topic root query round timed out"));
1847
+ }, roundTimeoutMs);
1848
+ roundTimer.unref?.();
1849
+ const roundSignals = linkAbortSignals([
1850
+ options?.signal,
1851
+ roundController.signal,
1852
+ ]);
1853
+ const queries = peers.map((peer) => this.queryTopicRootFromPeer(peer, topic, roundTimeoutMs, roundSignals.signal));
1854
+ const unresolved = Symbol("unresolved topic root query");
1855
+ const results = peers.map(() => unresolved);
1856
+ // All requests start together, but the stable peer ordering remains the
1857
+ // conflict-resolution policy: a later answer is usable only after every
1858
+ // earlier peer has answered undefined or reached its round timeout.
1859
+ const prioritizedResult = new Promise((resolve, reject) => {
1860
+ let settled = false;
1861
+ const resolveInPeerOrder = () => {
1862
+ for (const result of results) {
1863
+ if (result === unresolved)
1864
+ return;
1865
+ if (result !== undefined) {
1866
+ settled = true;
1867
+ resolve(result);
1868
+ return;
1869
+ }
1720
1870
  }
1721
- }
1722
- if (attempt < 2) {
1723
- await withAbort(delay(150 * (attempt + 1), options), options?.signal);
1724
- }
1871
+ settled = true;
1872
+ resolve(undefined);
1873
+ };
1874
+ queries.forEach((query, index) => {
1875
+ query.then((root) => {
1876
+ if (settled)
1877
+ return;
1878
+ results[index] = root;
1879
+ resolveInPeerOrder();
1880
+ }, (error) => {
1881
+ if (settled)
1882
+ return;
1883
+ if (roundTimedOut && !options?.signal?.aborted) {
1884
+ results[index] = undefined;
1885
+ resolveInPeerOrder();
1886
+ return;
1887
+ }
1888
+ settled = true;
1889
+ reject(error);
1890
+ });
1891
+ });
1892
+ });
1893
+ try {
1894
+ return await prioritizedResult;
1895
+ }
1896
+ finally {
1897
+ clearTimeout(roundTimer);
1898
+ // Cancel response timers and in-flight sends for every losing query before
1899
+ // the winning root (or an abort) can leave this round.
1900
+ roundController.abort(new AbortError("topic root query round settled"));
1901
+ await Promise.allSettled(queries);
1902
+ roundSignals.clear();
1725
1903
  }
1726
- return undefined;
1727
1904
  }
1728
1905
  async ensureFanoutChannel(shardTopic, options) {
1729
1906
  const topic = shardTopic.toString();
@@ -2107,26 +2284,71 @@ export class TopicControlPlane extends DirectStream {
2107
2284
  if (!this.started)
2108
2285
  throw new NotStartedError();
2109
2286
  const lifecycleSignal = this.topicRootResolutionAbortController.signal;
2110
- return this.withTopicRootCandidateResolution(async ({ candidateGeneration, signal }) => {
2287
+ return this.withTopicRootCandidateResolution(async ({ signal }) => {
2111
2288
  const joins = [];
2289
+ const scanController = new AbortController();
2290
+ const scanTimer = setTimeout(() => {
2291
+ scanController.abort(new AbortError(`topic root host scan timed out after ${TOPIC_ROOT_HOST_SCAN_TIMEOUT_MS}ms`));
2292
+ }, TOPIC_ROOT_HOST_SCAN_TIMEOUT_MS);
2293
+ scanTimer.unref?.();
2294
+ const scanSignals = linkAbortSignals([signal, scanController.signal]);
2295
+ let nextShard = 0;
2296
+ let scanFailure;
2297
+ const scanWorker = async () => {
2298
+ try {
2299
+ for (;;) {
2300
+ if (scanFailure)
2301
+ return;
2302
+ throwIfAborted(scanSignals.signal);
2303
+ const shard = nextShard++;
2304
+ if (shard >= this.shardCount)
2305
+ return;
2306
+ const shardTopic = `${this.shardTopicPrefix}${shard}`;
2307
+ const resolved = await this.resolveShardRootState(shardTopic, {
2308
+ signal: scanSignals.signal,
2309
+ // Proactive hosting follows the generation-bound local control
2310
+ // plane. Connected-peer queries remain on the lazy open path;
2311
+ // asking every peer for every shard multiplies one stale-peer
2312
+ // timeout by the complete shard count.
2313
+ queryConnectedPeers: false,
2314
+ });
2315
+ throwIfAborted(scanSignals.signal);
2316
+ if (scanFailure || resolved.root !== this.publicKeyHash)
2317
+ continue;
2318
+ const joining = this.ensureFanoutChannel(shardTopic, {
2319
+ pin: true,
2320
+ root: resolved.root,
2321
+ rootCandidateGeneration: resolved.candidateGeneration,
2322
+ // The shared deadline bounds root discovery only. Preserve the
2323
+ // existing contract that joins already started are drained.
2324
+ signal,
2325
+ });
2326
+ void joining.catch(() => { });
2327
+ joins.push(joining);
2328
+ }
2329
+ }
2330
+ catch (error) {
2331
+ if (!scanFailure) {
2332
+ scanFailure = { error };
2333
+ // Do not make a sibling resolver consume the rest of the shared
2334
+ // deadline after this scan already has a terminal failure. Joins use
2335
+ // the outer signal and are intentionally drained below.
2336
+ scanController.abort(error);
2337
+ }
2338
+ }
2339
+ };
2112
2340
  try {
2113
- for (let i = 0; i < this.shardCount; i++) {
2114
- throwIfAborted(signal);
2115
- const shardTopic = `${this.shardTopicPrefix}${i}`;
2116
- const resolved = await this.resolveShardRootState(shardTopic, {
2117
- signal,
2118
- });
2119
- if (resolved.root !== this.publicKeyHash)
2120
- continue;
2121
- const joining = this.ensureFanoutChannel(shardTopic, {
2122
- pin: true,
2123
- root: resolved.root,
2124
- rootCandidateGeneration: resolved.candidateGeneration,
2125
- signal,
2126
- });
2127
- void joining.catch(() => { });
2128
- joins.push(joining);
2341
+ try {
2342
+ await Promise.all(Array.from({
2343
+ length: Math.min(TOPIC_ROOT_HOST_SCAN_CONCURRENCY, this.shardCount),
2344
+ }, () => scanWorker()));
2345
+ }
2346
+ finally {
2347
+ clearTimeout(scanTimer);
2348
+ scanSignals.clear();
2129
2349
  }
2350
+ if (scanFailure)
2351
+ throw scanFailure.error;
2130
2352
  await Promise.all(joins);
2131
2353
  }
2132
2354
  catch (error) {
@@ -2856,7 +3078,7 @@ export class TopicControlPlane extends DirectStream {
2856
3078
  const imported = [];
2857
3079
  const outerPeerHash = stream.publicKey.hashcode();
2858
3080
  for (const claim of pubsubMessage.claims) {
2859
- if (await this.importSignedTopicRootCandidateClaim(claim, outerPeerHash)) {
3081
+ if (await this.importSignedTopicRootCandidateClaim(claim, outerPeerHash, stream)) {
2860
3082
  imported.push(claim);
2861
3083
  }
2862
3084
  }