@peerbit/shared-log 15.0.0 → 16.0.0

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.
@@ -23,7 +23,6 @@ const REQUIRED_SENDER_CAPABILITIES =
23
23
  const DEFAULT_REQUEST_RETRY_MS = 1_000;
24
24
  const DEFAULT_MAX_REQUEST_RETRY_MS = 30_000;
25
25
  const DEFAULT_REQUEST_MAX_ATTEMPTS = 7;
26
- const DEFAULT_LEGACY_FALLBACK_DELAY_MS = 5_000;
27
26
  const MAX_U64 = (1n << 64n) - 1n;
28
27
  const MAX_BACKOFF_EXPONENT = 20;
29
28
 
@@ -39,13 +38,12 @@ const bytesEqual = (left: Uint8Array, right: Uint8Array): boolean => {
39
38
  return true;
40
39
  };
41
40
 
42
- type LegacyReplicationInfoMessage =
43
- | AllReplicatingSegmentsMessage
44
- | AddedReplicationSegmentMessage
45
- | StoppedReplicating;
46
-
41
+ // Q4 (B12): fingerprints keep constructing the legacy-class canonical forms.
42
+ // They are byte-stable local-only hash inputs, never sent; these are the only
43
+ // sanctioned legacy-frame construction sites in src (see the no-legacy-
44
+ // machinery source ratchet's narrowed whitelist).
47
45
  const replicationInfoPayloadFingerprint = (
48
- message: ReplicationInfoV2Message | LegacyReplicationInfoMessage,
46
+ message: ReplicationInfoV2Message,
49
47
  ): Uint8Array => {
50
48
  const canonical =
51
49
  message instanceof FullReplicationInfoV2Message
@@ -86,6 +84,11 @@ type LocalCapabilityReadyProperties = {
86
84
 
87
85
  export type ReplicationInfoV2LocalCapabilityAdvertisementHandle = {
88
86
  firstAttempt: Promise<void>;
87
+ /**
88
+ * B12: the two-phase legacy barrier is retired — an ACKed advert promotes
89
+ * readiness immediately. Retained as a no-op so the handle shape (and the
90
+ * tests that drive it) stay stable.
91
+ */
89
92
  releaseLegacyBarrier(): void;
90
93
  };
91
94
 
@@ -93,7 +96,6 @@ export type ReplicationInfoV2LocalCapabilityContext = {
93
96
  peerHash: string;
94
97
  target: PublicSignKey;
95
98
  lifecycleSignal: AbortSignal;
96
- legacyBarrierReleased: boolean;
97
99
  };
98
100
 
99
101
  export type ReplicationInfoV2LocalCapabilityAdvertisement = {
@@ -141,18 +143,6 @@ export type ReplicationInfoV2ReceiveState = {
141
143
  requestsSinceCapabilityRefresh: number;
142
144
  requestParked: boolean;
143
145
  capabilityRefreshRequired: boolean;
144
- legacyFallbackTimer?: ReturnType<typeof setTimeout>;
145
- legacyFallbackFingerprint?: Uint8Array;
146
- legacyFallbackTimestamp?: bigint;
147
- legacyFallbackAmbiguous: boolean;
148
- lastCommittedTransportTimestamp?: bigint;
149
- recentCommittedPayloads: Array<{
150
- fingerprint: Uint8Array;
151
- transportTimestamp: bigint;
152
- }>;
153
- lastLegacyObservationTimestamp?: bigint;
154
- lastLegacyObservationFingerprint?: Uint8Array;
155
- lastLegacyObservationAmbiguous: boolean;
156
146
  reservedAdmission?: ReplicationInfoV2ReceiveAdmission;
157
147
  };
158
148
 
@@ -204,7 +194,6 @@ export type ReplicationInfoV2ReceiveDeps = {
204
194
  requestRetryMs?: number;
205
195
  maxRequestRetryMs?: number;
206
196
  requestMaxAttempts?: number;
207
- legacyFallbackDelayMs?: number;
208
197
  };
209
198
 
210
199
  /**
@@ -230,7 +219,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
230
219
  private readonly requestRetryMs: number;
231
220
  private readonly maxRequestRetryMs: number;
232
221
  private readonly requestMaxAttempts: number;
233
- private readonly legacyFallbackDelayMs: number;
234
222
 
235
223
  constructor(private readonly deps: ReplicationInfoV2ReceiveDeps) {
236
224
  this.now = deps.now ?? Date.now;
@@ -246,10 +234,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
246
234
  1,
247
235
  Math.floor(deps.requestMaxAttempts ?? DEFAULT_REQUEST_MAX_ATTEMPTS),
248
236
  );
249
- this.legacyFallbackDelayMs = Math.max(
250
- this.requestRetryMs,
251
- deps.legacyFallbackDelayMs ?? DEFAULT_LEGACY_FALLBACK_DELAY_MS,
252
- );
253
237
  this._receiveStates = new Map();
254
238
  this._cutoverPeerSessions = new WeakSet();
255
239
  this._localCapabilityReadyBySession = new WeakMap();
@@ -324,10 +308,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
324
308
  clearTimeout(state.requestTimer);
325
309
  state.requestTimer = undefined;
326
310
  }
327
- if (state.legacyFallbackTimer) {
328
- clearTimeout(state.legacyFallbackTimer);
329
- state.legacyFallbackTimer = undefined;
330
- }
331
311
  state.controller.abort();
332
312
  state.version++;
333
313
  if (this._receiveStates.get(state.peerHash) === state) {
@@ -422,9 +402,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
422
402
  if (state.timer || state.inFlight || state.ready) {
423
403
  return;
424
404
  }
425
- if (state.acknowledgedReady && !state.context.legacyBarrierReleased) {
426
- return;
427
- }
428
405
  if (!this.isLocalCapabilityAdvertisementOwnerCurrent(state)) {
429
406
  this.clearLocalCapabilityAdvertisement(state);
430
407
  return;
@@ -468,9 +445,7 @@ export class ReplicationInfoV2ReceiveCoordinator {
468
445
  return;
469
446
  }
470
447
  if (state.acknowledgedReady) {
471
- if (state.context.legacyBarrierReleased) {
472
- this.promoteLocalCapabilityAdvertisement(state);
473
- }
448
+ this.promoteLocalCapabilityAdvertisement(state);
474
449
  return;
475
450
  }
476
451
  if (!this.isLocalCapabilityAdvertisementReadyOpen(state)) {
@@ -528,9 +503,7 @@ export class ReplicationInfoV2ReceiveCoordinator {
528
503
  this.isLocalCapabilityAdvertisementGenerationCurrent(state) &&
529
504
  !state.ready
530
505
  ) {
531
- if (!state.acknowledgedReady || state.context.legacyBarrierReleased) {
532
- this.armLocalCapabilityAdvertisement(state);
533
- }
506
+ this.armLocalCapabilityAdvertisement(state);
534
507
  }
535
508
  });
536
509
  state.inFlight = operation;
@@ -538,10 +511,9 @@ export class ReplicationInfoV2ReceiveCoordinator {
538
511
  }
539
512
 
540
513
  /**
541
- * Start local authenticated-apply advertisement independently of the legacy
542
- * join path. ACK and legacy publication are a two-phase barrier: the first
543
- * attempt always settles independently, while readiness is promoted only
544
- * after the host releases the legacy barrier. Failed attempts leave one
514
+ * Start local authenticated-apply advertisement. Readiness is promoted as
515
+ * soon as the ACK lands (B12: the legacy publication this once ordered
516
+ * behind a two-phase barrier is retired). Failed attempts leave one
545
517
  * exact-session worker retrying with capped exponential backoff.
546
518
  */
547
519
  advertiseLocalCapability(properties: {
@@ -581,7 +553,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
581
553
  peerHash,
582
554
  target: properties.target,
583
555
  lifecycleSignal: properties.signal,
584
- legacyBarrierReleased: false,
585
556
  };
586
557
  this._localCapabilityContextBySession.set(
587
558
  properties.peerSession,
@@ -646,52 +617,18 @@ export class ReplicationInfoV2ReceiveCoordinator {
646
617
  const firstAttempt =
647
618
  state.firstAttempt ??
648
619
  (state.firstAttempt = this.runLocalCapabilityAdvertisement(state));
649
- const advertisement = state;
650
620
  return {
651
621
  firstAttempt,
652
- releaseLegacyBarrier: () =>
653
- this.releaseLocalCapabilityLegacyBarrier(
654
- advertisement.peerSession,
655
- context,
656
- ),
622
+ releaseLegacyBarrier: () => {},
657
623
  };
658
624
  }
659
625
 
660
- private releaseLocalCapabilityLegacyBarrier(
661
- peerSession: object,
662
- context: ReplicationInfoV2LocalCapabilityContext,
663
- ): void {
664
- if (context.legacyBarrierReleased) {
665
- return;
666
- }
667
- if (
668
- this._localCapabilityContextBySession.get(peerSession) !== context ||
669
- context.lifecycleSignal.aborted ||
670
- this.deps.isClosed() ||
671
- !this.deps.isPeerSessionCurrent(context.peerHash, peerSession)
672
- ) {
673
- return;
674
- }
675
- context.legacyBarrierReleased = true;
676
- const state = this._localCapabilityAdvertisementsByPeer.get(
677
- context.peerHash,
678
- );
679
- if (state?.peerSession === peerSession && state.context === context) {
680
- if (!this.isLocalCapabilityAdvertisementOwnerCurrent(state)) {
681
- this.clearLocalCapabilityAdvertisement(state);
682
- return;
683
- }
684
- this.promoteLocalCapabilityAdvertisement(state);
685
- }
686
- }
687
-
688
626
  private promoteLocalCapabilityAdvertisement(
689
627
  state: ReplicationInfoV2LocalCapabilityAdvertisement,
690
628
  ): boolean {
691
629
  const ready = state.acknowledgedReady;
692
630
  if (
693
631
  state.ready ||
694
- !state.context.legacyBarrierReleased ||
695
632
  !ready ||
696
633
  ready.receiveEpoch !== state.receiveEpoch ||
697
634
  ready.advertisement !== state ||
@@ -725,9 +662,7 @@ export class ReplicationInfoV2ReceiveCoordinator {
725
662
 
726
663
  /**
727
664
  * Re-advertise one exact current recovery epoch from the stable membership
728
- * context captured during opening. The opening handle owns barrier release;
729
- * recovery never bypasses a legacy snapshot or role publication still in
730
- * progress.
665
+ * context captured during opening.
731
666
  */
732
667
  reAdvertiseLocalCapabilityForRecovery(properties: {
733
668
  peerHash: string;
@@ -946,9 +881,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
946
881
  requestsSinceCapabilityRefresh: 0,
947
882
  requestParked: false,
948
883
  capabilityRefreshRequired: retainedCutover,
949
- legacyFallbackAmbiguous: false,
950
- recentCommittedPayloads: [],
951
- lastLegacyObservationAmbiguous: false,
952
884
  };
953
885
  this._receiveStates.set(peerHash, state);
954
886
  const ready = this._localCapabilityReadyBySession.get(peerSession);
@@ -1090,10 +1022,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
1090
1022
  }
1091
1023
  }
1092
1024
 
1093
- isLegacyCutover(peerSession: object | null): boolean {
1094
- return peerSession !== null && this._cutoverPeerSessions.has(peerSession);
1095
- }
1096
-
1097
1025
  prepare(
1098
1026
  message: ReplicationInfoV2Message,
1099
1027
  properties: {
@@ -1235,10 +1163,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
1235
1163
  clearTimeout(state.requestTimer);
1236
1164
  state.requestTimer = undefined;
1237
1165
  }
1238
- if (state.legacyFallbackTimer) {
1239
- clearTimeout(state.legacyFallbackTimer);
1240
- state.legacyFallbackTimer = undefined;
1241
- }
1242
1166
  return admission;
1243
1167
  }
1244
1168
 
@@ -1273,156 +1197,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
1273
1197
  // worker so the exact current generation cannot become stranded.
1274
1198
  this.armRequest(state, 0);
1275
1199
  }
1276
- if (
1277
- currentState === state &&
1278
- this.isStateCurrent(state) &&
1279
- state.phase === "active" &&
1280
- state.legacyFallbackFingerprint !== undefined
1281
- ) {
1282
- // A reservation also pauses compat sidecar recovery. Matching commits
1283
- // clear the evidence; an uncommitted or non-matching frame restores its
1284
- // bounded fallback without invalidating work in the host apply lane.
1285
- this.armLegacyFallback(state);
1286
- }
1287
- }
1288
-
1289
- /**
1290
- * B9 can lose its sender grant while keeping the topic session open. Its
1291
- * unmatched legacy sidecar is the compatibility signal to re-handshake; a
1292
- * matching V2 payload before or after the legacy copy suppresses the timer.
1293
- */
1294
- noteLegacyAnnouncement(properties: {
1295
- peerHash: string;
1296
- peerSession: object;
1297
- receiveEpoch: object | null;
1298
- senderTransportSession: bigint;
1299
- transportTimestamp: bigint;
1300
- message: LegacyReplicationInfoMessage;
1301
- }): boolean {
1302
- const state = this._receiveStates.get(properties.peerHash);
1303
- if (
1304
- !state ||
1305
- state.peerSession !== properties.peerSession ||
1306
- state.receiveEpoch !== properties.receiveEpoch ||
1307
- state.senderTransportSession !== properties.senderTransportSession ||
1308
- !this._cutoverPeerSessions.has(properties.peerSession) ||
1309
- !this.isStateCurrent(state)
1310
- ) {
1311
- return false;
1312
- }
1313
- const fingerprint = replicationInfoPayloadFingerprint(properties.message);
1314
- if (
1315
- state.lastCommittedTransportTimestamp !== undefined &&
1316
- properties.transportTimestamp < state.lastCommittedTransportTimestamp
1317
- ) {
1318
- return true;
1319
- }
1320
- if (
1321
- state.recentCommittedPayloads.some(
1322
- (committed) =>
1323
- properties.transportTimestamp <= committed.transportTimestamp &&
1324
- bytesEqual(committed.fingerprint, fingerprint),
1325
- )
1326
- ) {
1327
- return true;
1328
- }
1329
- if (state.lastLegacyObservationTimestamp !== undefined) {
1330
- if (
1331
- properties.transportTimestamp < state.lastLegacyObservationTimestamp
1332
- ) {
1333
- return true;
1334
- }
1335
- if (
1336
- properties.transportTimestamp === state.lastLegacyObservationTimestamp
1337
- ) {
1338
- if (
1339
- state.lastLegacyObservationAmbiguous ||
1340
- (state.lastLegacyObservationFingerprint !== undefined &&
1341
- bytesEqual(state.lastLegacyObservationFingerprint, fingerprint))
1342
- ) {
1343
- return true;
1344
- }
1345
- state.lastLegacyObservationAmbiguous = true;
1346
- } else {
1347
- state.lastLegacyObservationTimestamp = properties.transportTimestamp;
1348
- state.lastLegacyObservationFingerprint = fingerprint.slice();
1349
- state.lastLegacyObservationAmbiguous = false;
1350
- }
1351
- } else {
1352
- state.lastLegacyObservationTimestamp = properties.transportTimestamp;
1353
- state.lastLegacyObservationFingerprint = fingerprint.slice();
1354
- state.lastLegacyObservationAmbiguous = false;
1355
- }
1356
- const reserved = this._reservedAdmissionsByPeer.get(properties.peerHash);
1357
- if (
1358
- reserved?.state === state &&
1359
- !bytesEqual(reserved.payloadFingerprint, fingerprint)
1360
- ) {
1361
- // A legacy sidecar observed while a different V2 payload is applying
1362
- // cannot be erased by that commit. The transport has already ACKed the
1363
- // sidecar, so require one authoritative successor after release.
1364
- reserved.resyncAfterRelease = true;
1365
- }
1366
- if (!state.legacyFallbackFingerprint) {
1367
- state.legacyFallbackFingerprint = fingerprint;
1368
- state.legacyFallbackTimestamp = properties.transportTimestamp;
1369
- state.legacyFallbackAmbiguous = false;
1370
- } else {
1371
- if (!bytesEqual(state.legacyFallbackFingerprint, fingerprint)) {
1372
- state.legacyFallbackAmbiguous = true;
1373
- }
1374
- if (
1375
- state.legacyFallbackTimestamp === undefined ||
1376
- properties.transportTimestamp > state.legacyFallbackTimestamp
1377
- ) {
1378
- state.legacyFallbackTimestamp = properties.transportTimestamp;
1379
- }
1380
- }
1381
- if (state.phase !== "active") {
1382
- if (state.requestParked) {
1383
- this.transitionToResync(state, {
1384
- force: true,
1385
- refreshCapability: true,
1386
- });
1387
- }
1388
- return true;
1389
- }
1390
- if (state.legacyFallbackTimer) {
1391
- return true;
1392
- }
1393
- this.armLegacyFallback(state);
1394
- return true;
1395
- }
1396
-
1397
- private armLegacyFallback(state: ReplicationInfoV2ReceiveState): void {
1398
- if (
1399
- state.legacyFallbackTimer ||
1400
- state.phase !== "active" ||
1401
- state.legacyFallbackFingerprint === undefined ||
1402
- this._reservedAdmissionsByPeer.has(state.peerHash)
1403
- ) {
1404
- return;
1405
- }
1406
- state.legacyFallbackTimer = setTimeout(() => {
1407
- state.legacyFallbackTimer = undefined;
1408
- if (this.isStateCurrent(state) && state.phase === "active") {
1409
- this.transitionToResync(state, {
1410
- force: true,
1411
- refreshCapability: true,
1412
- });
1413
- }
1414
- }, this.legacyFallbackDelayMs);
1415
- state.legacyFallbackTimer.unref?.();
1416
- }
1417
-
1418
- private clearLegacyFallback(state: ReplicationInfoV2ReceiveState): void {
1419
- if (state.legacyFallbackTimer) {
1420
- clearTimeout(state.legacyFallbackTimer);
1421
- state.legacyFallbackTimer = undefined;
1422
- }
1423
- state.legacyFallbackFingerprint = undefined;
1424
- state.legacyFallbackTimestamp = undefined;
1425
- state.legacyFallbackAmbiguous = false;
1426
1200
  }
1427
1201
 
1428
1202
  isAdmissionCurrent(admission: ReplicationInfoV2ReceiveAdmission): boolean {
@@ -1464,26 +1238,6 @@ export class ReplicationInfoV2ReceiveCoordinator {
1464
1238
  state.requestsSinceCapabilityRefresh = 0;
1465
1239
  state.requestParked = false;
1466
1240
  state.capabilityRefreshRequired = false;
1467
- state.lastCommittedTransportTimestamp = admission.transportTimestamp;
1468
- state.recentCommittedPayloads.push({
1469
- fingerprint: admission.payloadFingerprint.slice(),
1470
- transportTimestamp: admission.transportTimestamp,
1471
- });
1472
- if (state.recentCommittedPayloads.length > 8) {
1473
- state.recentCommittedPayloads.shift();
1474
- }
1475
- if (
1476
- (state.legacyFallbackTimestamp !== undefined &&
1477
- admission.transportTimestamp > state.legacyFallbackTimestamp) ||
1478
- (!state.legacyFallbackAmbiguous &&
1479
- state.legacyFallbackFingerprint !== undefined &&
1480
- bytesEqual(
1481
- state.legacyFallbackFingerprint,
1482
- admission.payloadFingerprint,
1483
- ))
1484
- ) {
1485
- this.clearLegacyFallback(state);
1486
- }
1487
1241
  if (state.requestTimer) {
1488
1242
  clearTimeout(state.requestTimer);
1489
1243
  state.requestTimer = undefined;
@@ -392,13 +392,6 @@ export class ReplicationInfoV2SendCoordinator<R extends "u32" | "u64"> {
392
392
  }
393
393
  }
394
394
 
395
- enqueueSnapshotForPeer(peerHash: string): void {
396
- const state = this._sendStates.get(peerHash);
397
- if (state) {
398
- this.enqueueState(state, { kind: "snapshot" });
399
- }
400
- }
401
-
402
395
  private enqueueState(
403
396
  state: ReplicationInfoV2SendState,
404
397
  request: SendRequest,
@@ -7,14 +7,12 @@ import {
7
7
  variant,
8
8
  vec,
9
9
  } from "@dao-xyz/borsh";
10
- import { PublicSignKey, randomBytes } from "@peerbit/crypto";
10
+ import { PublicSignKey } from "@peerbit/crypto";
11
11
  import { type Index } from "@peerbit/indexer-interface";
12
12
  import { TransportMessage } from "./message.js";
13
13
  import {
14
- ReplicationIntent,
15
14
  type ReplicationRangeIndexable,
16
15
  ReplicationRangeMessage,
17
- ReplicationRangeMessageU32,
18
16
  } from "./ranges.js";
19
17
  import { Observer, Replicator, Role } from "./role.js";
20
18
 
@@ -63,23 +61,6 @@ export class ResponseRoleMessage extends TransportMessage {
63
61
  super();
64
62
  this.role = properties.role;
65
63
  }
66
-
67
- toReplicationInfoMessage(): AllReplicatingSegmentsMessage {
68
- return new AllReplicatingSegmentsMessage({
69
- segments:
70
- this.role instanceof Replicator
71
- ? this.role.segments.map((x) => {
72
- return new ReplicationRangeMessageU32({
73
- id: randomBytes(32),
74
- offset: x.offset,
75
- factor: x.factor,
76
- timestamp: x.timestamp,
77
- mode: ReplicationIntent.NonStrict,
78
- });
79
- })
80
- : [],
81
- });
82
- }
83
64
  }
84
65
 
85
66
  @variant([1, 2])
@@ -14,7 +14,6 @@ import type {
14
14
  Syncronizer,
15
15
  } from "./index.js";
16
16
  import { RatelessIBLTSynchronizer } from "./rateless-iblt.js";
17
- import { SimpleSyncronizer } from "./simple.js";
18
17
 
19
18
  export type CreateSyncronizerProps<R extends "u32" | "u64"> = {
20
19
  // pass-through refs (snapshotted at open() time; stable post-open)
@@ -39,7 +38,6 @@ export type CreateSyncronizerProps<R extends "u32" | "u64"> = {
39
38
  sendRawExchangeHeads: RawExchangeHeadsSender;
40
39
  warn: (message: string) => void;
41
40
  // construction-time scalars
42
- compatibility?: number;
43
41
  resolution: R;
44
42
  sync?: SyncOptions<R>;
45
43
  syncronizer?: SynchronizerConstructor<R>;
@@ -113,42 +111,30 @@ export function createSyncronizer<R extends "u32" | "u64">(
113
111
  peerSupportsRawExchangeHeads: props.peerSupportsRawExchangeHeads,
114
112
  sendRawExchangeHeads: props.sendRawExchangeHeads,
115
113
  });
116
- } else {
117
- if (props.compatibility !== undefined && props.compatibility < 10) {
118
- return new SimpleSyncronizer({
119
- log: props.log,
120
- rpc: props.rpc,
121
- entryIndex: props.entryIndex,
122
- coordinateToHash: props.coordinateToHash,
123
- resolveHashesForSymbols,
124
- resolveHashListForSymbols,
125
- sync: props.sync,
126
- isEntryRecentlyKnownByPeer: props.isEntryRecentlyKnownByPeer,
127
- peerSupportsRawExchangeHeads: props.peerSupportsRawExchangeHeads,
128
- sendRawExchangeHeads: props.sendRawExchangeHeads,
129
- });
130
- } else {
131
- if (props.resolution === "u32") {
132
- props.warn(
133
- "u32 resolution is not recommended for RatelessIBLTSynchronizer",
134
- );
135
- }
114
+ }
136
115
 
137
- return new RatelessIBLTSynchronizer<R>({
138
- numbers: props.numbers,
139
- entryIndex: props.entryIndex,
140
- log: props.log,
141
- rangeIndex: props.rangeIndex,
142
- rpc: props.rpc,
143
- coordinateToHash: props.coordinateToHash,
144
- resolveHashesForSymbols,
145
- resolveHashListForSymbols,
146
- resolveHashNumbersInRange,
147
- sync: props.sync,
148
- isEntryRecentlyKnownByPeer: props.isEntryRecentlyKnownByPeer,
149
- peerSupportsRawExchangeHeads: props.peerSupportsRawExchangeHeads,
150
- sendRawExchangeHeads: props.sendRawExchangeHeads,
151
- }) as Syncronizer<R>;
152
- }
116
+ // Default synchronizer. SimpleSyncronizer stays a first-class explicit
117
+ // choice via the `syncronizer` option above; only the retired
118
+ // compatibility-coupled defaulting arm that once selected it is gone (B12).
119
+ if (props.resolution === "u32") {
120
+ props.warn(
121
+ "u32 resolution is not recommended for RatelessIBLTSynchronizer",
122
+ );
153
123
  }
124
+
125
+ return new RatelessIBLTSynchronizer<R>({
126
+ numbers: props.numbers,
127
+ entryIndex: props.entryIndex,
128
+ log: props.log,
129
+ rangeIndex: props.rangeIndex,
130
+ rpc: props.rpc,
131
+ coordinateToHash: props.coordinateToHash,
132
+ resolveHashesForSymbols,
133
+ resolveHashListForSymbols,
134
+ resolveHashNumbersInRange,
135
+ sync: props.sync,
136
+ isEntryRecentlyKnownByPeer: props.isEntryRecentlyKnownByPeer,
137
+ peerSupportsRawExchangeHeads: props.peerSupportsRawExchangeHeads,
138
+ sendRawExchangeHeads: props.sendRawExchangeHeads,
139
+ }) as Syncronizer<R>;
154
140
  }