@peerbit/shared-log 13.2.27 → 13.2.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/src/index.js CHANGED
@@ -475,7 +475,7 @@ const cloneRepairPendingPeersByMode = (pending) => new Map(REPAIR_DISPATCH_MODES
475
475
  new Set(pending.get(mode) ?? []),
476
476
  ]));
477
477
  const createRepairFrontierByMode = () => new Map(REPAIR_DISPATCH_MODES.map((mode) => [mode, new Map()]));
478
- const createRepairActiveTargetsByMode = () => new Map(REPAIR_DISPATCH_MODES.map((mode) => [mode, new Set()]));
478
+ const createRepairActiveTargetsByMode = () => new Map(REPAIR_DISPATCH_MODES.map((mode) => [mode, new Map()]));
479
479
  const createRepairFrontierBypassKnownPeersByMode = () => new Map(REPAIR_DISPATCH_MODES.map((mode) => [mode, new Set()]));
480
480
  const getRepairRetrySchedule = (mode) => {
481
481
  switch (mode) {
@@ -4964,7 +4964,10 @@ let SharedLog = (() => {
4964
4964
  !this.isRepairLifecycleActive(repairLifecycleController)) {
4965
4965
  return;
4966
4966
  }
4967
- activeTargets.add(target);
4967
+ const runnerToken = {};
4968
+ activeTargets.set(target, runnerToken);
4969
+ const isCurrentRunner = () => activeTargets.get(target) === runnerToken &&
4970
+ this.isRepairLifecycleActive(repairLifecycleController);
4968
4971
  const retrySchedule = resolveRepairRetrySchedule(mode, retryScheduleMs, this.isFrontierTrackedRepairMode(mode));
4969
4972
  const steadyStateDelay = retrySchedule.length > 1
4970
4973
  ? Math.max(1, retrySchedule[retrySchedule.length - 1] -
@@ -4974,12 +4977,12 @@ let SharedLog = (() => {
4974
4977
  let attemptIndex = 0;
4975
4978
  try {
4976
4979
  for (;;) {
4977
- if (!this.isRepairLifecycleActive(repairLifecycleController)) {
4980
+ if (!isCurrentRunner()) {
4978
4981
  return;
4979
4982
  }
4980
4983
  const pending = this._repairFrontierByMode.get(mode)?.get(target);
4981
4984
  if (!pending || pending.size === 0) {
4982
- if (!this.isRepairLifecycleActive(repairLifecycleController)) {
4985
+ if (!isCurrentRunner()) {
4983
4986
  return;
4984
4987
  }
4985
4988
  this._repairFrontierBypassKnownPeersByMode
@@ -4994,7 +4997,7 @@ let SharedLog = (() => {
4994
4997
  }
4995
4998
  continue;
4996
4999
  }
4997
- if (!this.isRepairLifecycleActive(repairLifecycleController)) {
5000
+ if (!isCurrentRunner()) {
4998
5001
  return;
4999
5002
  }
5000
5003
  await this.sendMaybeMissingEntriesNow(target, pending, {
@@ -5005,7 +5008,7 @@ let SharedLog = (() => {
5005
5008
  .get(mode)
5006
5009
  ?.has(target) === true,
5007
5010
  }, repairLifecycleController);
5008
- if (!this.isRepairLifecycleActive(repairLifecycleController)) {
5011
+ if (!isCurrentRunner()) {
5009
5012
  return;
5010
5013
  }
5011
5014
  const remaining = this._repairFrontierByMode.get(mode)?.get(target);
@@ -5022,14 +5025,18 @@ let SharedLog = (() => {
5022
5025
  }
5023
5026
  }
5024
5027
  finally {
5025
- activeTargets.delete(target);
5026
- if (this.isRepairLifecycleActive(repairLifecycleController) &&
5027
- (this._repairFrontierByMode.get(mode)?.get(target)?.size || 0) > 0) {
5028
- this.ensureRepairFrontierRunner(mode, target, retryScheduleMs, repairLifecycleController);
5028
+ if (activeTargets.get(target) === runnerToken) {
5029
+ activeTargets.delete(target);
5030
+ if (this.isRepairLifecycleActive(repairLifecycleController) &&
5031
+ (this._repairFrontierByMode.get(mode)?.get(target)?.size || 0) > 0) {
5032
+ this.ensureRepairFrontierRunner(mode, target, retryScheduleMs, repairLifecycleController);
5033
+ }
5029
5034
  }
5030
5035
  }
5031
5036
  })().catch((error) => {
5032
- activeTargets.delete(target);
5037
+ if (activeTargets.get(target) === runnerToken) {
5038
+ activeTargets.delete(target);
5039
+ }
5033
5040
  if (this.isRepairLifecycleActive(repairLifecycleController)) {
5034
5041
  logger.error(error);
5035
5042
  }
@@ -11264,6 +11271,241 @@ let SharedLog = (() => {
11264
11271
  resolveReleasedBlock: (hash) => backbone.rawReceiveBlockBytes(hash),
11265
11272
  });
11266
11273
  }
11274
+ /**
11275
+ * Normalize a raw exchange-heads receive into the regular exchange message
11276
+ * consumed by the rest of the receive path. An undefined result means the
11277
+ * message was fully handled (all heads were already present or the native
11278
+ * receive plan dropped every head).
11279
+ *
11280
+ * This helper intentionally runs inside `onMessage`'s shared try/finally
11281
+ * envelope so receive errors keep their existing classification and a
11282
+ * wire-backed message keeps its single outer stash-release boundary.
11283
+ */
11284
+ async materializeRawReceiveMessage(msg, properties) {
11285
+ const { from: rawFrom, stashBackedRawMessage, syncProfile, receiveOwnershipRevision, } = properties;
11286
+ const fromIsSelf = rawFrom.equals(this.node.identity.publicKey);
11287
+ if (syncProfile && !stashBackedRawMessage) {
11288
+ // Per-message JS-side entry decode: the heads were
11289
+ // borsh-decoded in TS (regular RPC path) instead of being
11290
+ // resolved from the native wire stash. Zero on the fused
11291
+ // hot path.
11292
+ emitSyncProfileEvent(syncProfile, {
11293
+ name: "sharedLog.rawReceive.jsEntryDecode",
11294
+ component: "shared-log",
11295
+ entries: msg.heads.length,
11296
+ messages: 1,
11297
+ });
11298
+ }
11299
+ const rawExistingStartedAt = syncProfileStart(syncProfile);
11300
+ const rawExistingHashes = await this.log.hasMany(msg.heads.map((head) => head.hash));
11301
+ if (syncProfile) {
11302
+ emitSyncProfileDuration(syncProfile, rawExistingStartedAt, {
11303
+ name: "sharedLog.rawReceive.existingHeads",
11304
+ component: "shared-log",
11305
+ entries: msg.heads.length,
11306
+ messages: 1,
11307
+ });
11308
+ }
11309
+ const rawMissingHeads = [];
11310
+ const rawConfirmedHashes = new Set();
11311
+ let rawMissingBytes = 0;
11312
+ for (const head of msg.heads) {
11313
+ if (rawExistingHashes.has(head.hash)) {
11314
+ rawConfirmedHashes.add(head.hash);
11315
+ }
11316
+ else {
11317
+ rawMissingHeads.push(head);
11318
+ rawMissingBytes += getRawExchangeHeadByteLength(head);
11319
+ }
11320
+ }
11321
+ if (rawConfirmedHashes.size > 0 && !fromIsSelf) {
11322
+ const rawConfirmStartedAt = syncProfileStart(syncProfile);
11323
+ this.markEntriesKnownByPeer(rawConfirmedHashes, rawFrom.hashcode());
11324
+ await this.sendRepairConfirmation(rawFrom, rawConfirmedHashes);
11325
+ if (syncProfile) {
11326
+ emitSyncProfileDuration(syncProfile, rawConfirmStartedAt, {
11327
+ name: "sharedLog.rawReceive.confirmExisting",
11328
+ component: "shared-log",
11329
+ entries: rawConfirmedHashes.size,
11330
+ messages: 1,
11331
+ });
11332
+ }
11333
+ }
11334
+ if (rawMissingHeads.length === 0) {
11335
+ return undefined;
11336
+ }
11337
+ const rawIsRepairHint = (msg.reserved[0] & EXCHANGE_HEADS_REPAIR_HINT) !== 0;
11338
+ const rawPrepareVerifySetting = this._logProperties?.sync?.rawExchangeHeadsVerifySignaturesDuringPrepare;
11339
+ // A program-level canAppend hook must observe every entry before
11340
+ // it commits, so the native join commit (which validates and
11341
+ // commits entirely in wasm) is not used for programs that
11342
+ // register one; those joins run through the lower-log batch
11343
+ // join where the hook fires per entry.
11344
+ const programCanAppend = !!this._logProperties?.canAppend;
11345
+ const canVerifyPreparedRawReceiveOnCommit = !programCanAppend &&
11346
+ !!this._nativeBackbone?.graph.commitVerifiedPreparedRawReceiveJoinBatch;
11347
+ const canDeferRawReceiveVerificationUntilNativeSelection = !rawIsRepairHint &&
11348
+ !!this._nativeBackbone?.verifyPreparedRawReceiveEntries &&
11349
+ !this._isReplicating &&
11350
+ !this.keep &&
11351
+ !this.closed &&
11352
+ !!this.syncronizer.onReceivedEntryHashes &&
11353
+ rawMissingHeads.every((head) => head.gidRefrences.length === 0);
11354
+ const verifyNativeBackboneSignaturesDuringPrepare = rawPrepareVerifySetting === true ||
11355
+ (rawPrepareVerifySetting !== false &&
11356
+ (canDeferRawReceiveVerificationUntilNativeSelection ||
11357
+ (this._isReplicating &&
11358
+ !rawIsRepairHint &&
11359
+ !canVerifyPreparedRawReceiveOnCommit)));
11360
+ const deferNativeBackboneSignatureVerificationUntilSelection = verifyNativeBackboneSignaturesDuringPrepare &&
11361
+ canDeferRawReceiveVerificationUntilNativeSelection;
11362
+ const deferNativeBackboneSignatureVerificationUntilCommit = deferNativeBackboneSignatureVerificationUntilSelection &&
11363
+ !programCanAppend &&
11364
+ !!this._nativeBackbone?.graph.commitVerifiedPreparedRawReceiveJoinBatch;
11365
+ let rawPreparedReceiveSelectionValue;
11366
+ let rawPreparedReceiveSelection;
11367
+ const getRawPreparedReceiveSelection = async (heads, hashes) => {
11368
+ if (rawPreparedReceiveSelectionValue) {
11369
+ return rawPreparedReceiveSelectionValue;
11370
+ }
11371
+ rawPreparedReceiveSelection ??=
11372
+ this.planNativePreparedRawReceiveSelection({
11373
+ heads,
11374
+ hashes,
11375
+ from: rawFrom,
11376
+ });
11377
+ rawPreparedReceiveSelectionValue = await rawPreparedReceiveSelection;
11378
+ return rawPreparedReceiveSelectionValue;
11379
+ };
11380
+ // Receive fusion: when this message was resolved from the wire
11381
+ // stash, the prepared receive reads entry block bytes straight
11382
+ // out of wasm memory (indexed into the stashed frame) instead
11383
+ // of copying a JS blocks array across the boundary.
11384
+ const rawStashIndexes = stashBackedRawMessage
11385
+ ? getRawExchangeHeadStashIndexes(rawMissingHeads)
11386
+ : undefined;
11387
+ const prepareNativeBackboneExpectedColumns = stashBackedRawMessage && rawStashIndexes
11388
+ ? ({ hashes, verifySignatures, }) => {
11389
+ const backbone = this._nativeBackbone;
11390
+ const wireSession = this._wireSyncSession;
11391
+ if (!backbone || !wireSession) {
11392
+ return undefined;
11393
+ }
11394
+ try {
11395
+ return backbone.prepareStashedRawReceiveExpectedColumnsBatch(wireSession, stashBackedRawMessage.messageId, rawStashIndexes, hashes, { verifySignatures });
11396
+ }
11397
+ catch {
11398
+ return undefined;
11399
+ }
11400
+ }
11401
+ : undefined;
11402
+ const prepareNativeBackboneExpectedColumnsAndSelection = rawIsRepairHint
11403
+ ? undefined
11404
+ : async ({ blocks, hashes, verifySignatures, }) => {
11405
+ if (verifySignatures ||
11406
+ !canDeferRawReceiveVerificationUntilNativeSelection) {
11407
+ return undefined;
11408
+ }
11409
+ try {
11410
+ const replicaOptions = {
11411
+ minReplicas: this.replicas.min?.getValue(this) || 1,
11412
+ maxReplicas: this.replicas.max?.getValue(this),
11413
+ };
11414
+ const leaderSelectionContext = await this.createLeaderSelectionContext();
11415
+ const prepareOptions = {
11416
+ verifySignatures: false,
11417
+ ...replicaOptions,
11418
+ leaderOptions: this.createNativeLeaderOptions(leaderSelectionContext),
11419
+ fromHash: rawFrom.hashcode(),
11420
+ };
11421
+ let prepared;
11422
+ const wireSession = this._wireSyncSession;
11423
+ if (stashBackedRawMessage &&
11424
+ rawStashIndexes &&
11425
+ wireSession &&
11426
+ this._nativeBackbone) {
11427
+ prepared =
11428
+ this._nativeBackbone.prepareStashedRawReceiveExpectedColumnsAndSelectionBatch(wireSession, stashBackedRawMessage.messageId, rawStashIndexes, hashes, prepareOptions);
11429
+ }
11430
+ if (!prepared &&
11431
+ this._nativeBackbone
11432
+ ?.prepareRawReceiveExpectedColumnsAndSelectionBatch) {
11433
+ prepared =
11434
+ this._nativeBackbone.prepareRawReceiveExpectedColumnsAndSelectionBatch(blocks(), hashes, prepareOptions);
11435
+ }
11436
+ if (!prepared) {
11437
+ return undefined;
11438
+ }
11439
+ rawPreparedReceiveSelectionValue = prepared.selection;
11440
+ rawPreparedReceiveSelection = Promise.resolve(rawPreparedReceiveSelectionValue);
11441
+ return { columns: prepared.columns };
11442
+ }
11443
+ catch {
11444
+ this.throwIfReplicationOwnershipPoisoned();
11445
+ return undefined;
11446
+ }
11447
+ };
11448
+ const rawMaterializeStartedAt = syncProfileStart(syncProfile);
11449
+ const materializedRawMessage = await materializeVerifiedRawExchangeHeadsMessage(new RawExchangeHeadsMessage({
11450
+ heads: rawMissingHeads,
11451
+ reserved: msg.reserved,
11452
+ }), this.log, syncProfile, {
11453
+ nativeBackbone: this._nativeBackbone,
11454
+ verifyNativeBackboneSignaturesDuringPrepare: verifyNativeBackboneSignaturesDuringPrepare,
11455
+ deferNativeBackboneSignatureVerificationUntilSelection: deferNativeBackboneSignatureVerificationUntilSelection,
11456
+ deferNativeBackboneSignatureVerificationUntilCommit: deferNativeBackboneSignatureVerificationUntilCommit,
11457
+ prepareNativeBackboneExpectedColumnsAndSelection: prepareNativeBackboneExpectedColumnsAndSelection,
11458
+ prepareNativeBackboneExpectedColumns: prepareNativeBackboneExpectedColumns,
11459
+ tryPreparedRawReceiveFastDrop: rawIsRepairHint
11460
+ ? undefined
11461
+ : async ({ heads, hashes }) => this.tryFastDropPreparedRawReceive({
11462
+ heads,
11463
+ hashes,
11464
+ from: rawFrom,
11465
+ fromIsSelf,
11466
+ syncProfile,
11467
+ selection: await getRawPreparedReceiveSelection(heads, hashes),
11468
+ receiveOwnershipRevision,
11469
+ }),
11470
+ selectPreparedRawReceiveHashes: rawIsRepairHint
11471
+ ? undefined
11472
+ : async ({ heads, hashes }) => this.selectNativePreparedRawReceiveHashes({
11473
+ heads,
11474
+ hashes,
11475
+ from: rawFrom,
11476
+ fromIsSelf,
11477
+ syncProfile,
11478
+ selection: await getRawPreparedReceiveSelection(heads, hashes),
11479
+ receiveOwnershipRevision,
11480
+ }),
11481
+ });
11482
+ if (materializedRawMessage === undefined) {
11483
+ if (syncProfile) {
11484
+ emitSyncProfileDuration(syncProfile, rawMaterializeStartedAt, {
11485
+ name: "sharedLog.rawReceive.materialize",
11486
+ component: "shared-log",
11487
+ entries: rawMissingHeads.length,
11488
+ bytes: rawMissingBytes,
11489
+ messages: 1,
11490
+ details: { nativeFastDropEarly: true },
11491
+ });
11492
+ }
11493
+ return undefined;
11494
+ }
11495
+ if (syncProfile) {
11496
+ emitSyncProfileDuration(syncProfile, rawMaterializeStartedAt, {
11497
+ name: "sharedLog.rawReceive.materialize",
11498
+ component: "shared-log",
11499
+ entries: rawMissingHeads.length,
11500
+ bytes: rawMissingBytes,
11501
+ messages: 1,
11502
+ });
11503
+ }
11504
+ return {
11505
+ message: materializedRawMessage,
11506
+ preparedSelection: rawPreparedReceiveSelectionValue,
11507
+ };
11508
+ }
11267
11509
  // Callback for receiving a message from the network
11268
11510
  async onMessage(msg, context) {
11269
11511
  const stashBackedRawMessage = isStashBackedRawExchangeHeadsMessage(msg)
@@ -11323,229 +11565,19 @@ let SharedLog = (() => {
11323
11565
  let rawMaterializedKnownMissing = false;
11324
11566
  let rawPreparedReceiveSelectionValue;
11325
11567
  if (msg instanceof RawExchangeHeadsMessage) {
11326
- const rawFrom = context.from;
11327
- const fromIsSelf = rawFrom.equals(this.node.identity.publicKey);
11328
- if (syncProfile && !stashBackedRawMessage) {
11329
- // Per-message JS-side entry decode: the heads were
11330
- // borsh-decoded in TS (regular RPC path) instead of being
11331
- // resolved from the native wire stash. Zero on the fused
11332
- // hot path.
11333
- emitSyncProfileEvent(syncProfile, {
11334
- name: "sharedLog.rawReceive.jsEntryDecode",
11335
- component: "shared-log",
11336
- entries: msg.heads.length,
11337
- messages: 1,
11338
- });
11339
- }
11340
- const rawExistingStartedAt = syncProfileStart(syncProfile);
11341
- const rawExistingHashes = await this.log.hasMany(msg.heads.map((head) => head.hash));
11342
- if (syncProfile) {
11343
- emitSyncProfileDuration(syncProfile, rawExistingStartedAt, {
11344
- name: "sharedLog.rawReceive.existingHeads",
11345
- component: "shared-log",
11346
- entries: msg.heads.length,
11347
- messages: 1,
11348
- });
11349
- }
11350
- const rawMissingHeads = [];
11351
- const rawConfirmedHashes = new Set();
11352
- let rawMissingBytes = 0;
11353
- for (const head of msg.heads) {
11354
- if (rawExistingHashes.has(head.hash)) {
11355
- rawConfirmedHashes.add(head.hash);
11356
- }
11357
- else {
11358
- rawMissingHeads.push(head);
11359
- rawMissingBytes += getRawExchangeHeadByteLength(head);
11360
- }
11361
- }
11362
- if (rawConfirmedHashes.size > 0 && !fromIsSelf) {
11363
- const rawConfirmStartedAt = syncProfileStart(syncProfile);
11364
- this.markEntriesKnownByPeer(rawConfirmedHashes, rawFrom.hashcode());
11365
- await this.sendRepairConfirmation(rawFrom, rawConfirmedHashes);
11366
- if (syncProfile) {
11367
- emitSyncProfileDuration(syncProfile, rawConfirmStartedAt, {
11368
- name: "sharedLog.rawReceive.confirmExisting",
11369
- component: "shared-log",
11370
- entries: rawConfirmedHashes.size,
11371
- messages: 1,
11372
- });
11373
- }
11374
- }
11375
- if (rawMissingHeads.length === 0) {
11376
- return;
11377
- }
11378
- const rawIsRepairHint = (msg.reserved[0] & EXCHANGE_HEADS_REPAIR_HINT) !== 0;
11379
- const rawPrepareVerifySetting = this._logProperties?.sync
11380
- ?.rawExchangeHeadsVerifySignaturesDuringPrepare;
11381
- // A program-level canAppend hook must observe every entry before
11382
- // it commits, so the native join commit (which validates and
11383
- // commits entirely in wasm) is not used for programs that
11384
- // register one; those joins run through the lower-log batch
11385
- // join where the hook fires per entry.
11386
- const programCanAppend = !!this._logProperties?.canAppend;
11387
- const canVerifyPreparedRawReceiveOnCommit = !programCanAppend &&
11388
- !!this._nativeBackbone?.graph
11389
- .commitVerifiedPreparedRawReceiveJoinBatch;
11390
- const canDeferRawReceiveVerificationUntilNativeSelection = !rawIsRepairHint &&
11391
- !!this._nativeBackbone?.verifyPreparedRawReceiveEntries &&
11392
- !this._isReplicating &&
11393
- !this.keep &&
11394
- !this.closed &&
11395
- !!this.syncronizer.onReceivedEntryHashes &&
11396
- rawMissingHeads.every((head) => head.gidRefrences.length === 0);
11397
- const verifyNativeBackboneSignaturesDuringPrepare = rawPrepareVerifySetting === true ||
11398
- (rawPrepareVerifySetting !== false &&
11399
- (canDeferRawReceiveVerificationUntilNativeSelection ||
11400
- (this._isReplicating &&
11401
- !rawIsRepairHint &&
11402
- !canVerifyPreparedRawReceiveOnCommit)));
11403
- const deferNativeBackboneSignatureVerificationUntilSelection = verifyNativeBackboneSignaturesDuringPrepare &&
11404
- canDeferRawReceiveVerificationUntilNativeSelection;
11405
- const deferNativeBackboneSignatureVerificationUntilCommit = deferNativeBackboneSignatureVerificationUntilSelection &&
11406
- !programCanAppend &&
11407
- !!this._nativeBackbone?.graph
11408
- .commitVerifiedPreparedRawReceiveJoinBatch;
11409
- let rawPreparedReceiveSelection;
11410
- const getRawPreparedReceiveSelection = async (heads, hashes) => {
11411
- if (rawPreparedReceiveSelectionValue) {
11412
- return rawPreparedReceiveSelectionValue;
11413
- }
11414
- rawPreparedReceiveSelection ??=
11415
- this.planNativePreparedRawReceiveSelection({
11416
- heads,
11417
- hashes,
11418
- from: rawFrom,
11419
- });
11420
- rawPreparedReceiveSelectionValue = await rawPreparedReceiveSelection;
11421
- return rawPreparedReceiveSelectionValue;
11422
- };
11423
- // Receive fusion: when this message was resolved from the wire
11424
- // stash, the prepared receive reads entry block bytes straight
11425
- // out of wasm memory (indexed into the stashed frame) instead
11426
- // of copying a JS blocks array across the boundary.
11427
- const rawStashIndexes = stashBackedRawMessage
11428
- ? getRawExchangeHeadStashIndexes(rawMissingHeads)
11429
- : undefined;
11430
- const prepareNativeBackboneExpectedColumns = stashBackedRawMessage && rawStashIndexes
11431
- ? ({ hashes, verifySignatures, }) => {
11432
- const backbone = this._nativeBackbone;
11433
- const wireSession = this._wireSyncSession;
11434
- if (!backbone || !wireSession) {
11435
- return undefined;
11436
- }
11437
- try {
11438
- return backbone.prepareStashedRawReceiveExpectedColumnsBatch(wireSession, stashBackedRawMessage.messageId, rawStashIndexes, hashes, { verifySignatures });
11439
- }
11440
- catch {
11441
- return undefined;
11442
- }
11443
- }
11444
- : undefined;
11445
- const prepareNativeBackboneExpectedColumnsAndSelection = rawIsRepairHint
11446
- ? undefined
11447
- : async ({ blocks, hashes, verifySignatures, }) => {
11448
- if (verifySignatures ||
11449
- !canDeferRawReceiveVerificationUntilNativeSelection) {
11450
- return undefined;
11451
- }
11452
- try {
11453
- const replicaOptions = {
11454
- minReplicas: this.replicas.min?.getValue(this) || 1,
11455
- maxReplicas: this.replicas.max?.getValue(this),
11456
- };
11457
- const leaderSelectionContext = await this.createLeaderSelectionContext();
11458
- const prepareOptions = {
11459
- verifySignatures: false,
11460
- ...replicaOptions,
11461
- leaderOptions: this.createNativeLeaderOptions(leaderSelectionContext),
11462
- fromHash: rawFrom.hashcode(),
11463
- };
11464
- let prepared;
11465
- const wireSession = this._wireSyncSession;
11466
- if (stashBackedRawMessage &&
11467
- rawStashIndexes &&
11468
- wireSession &&
11469
- this._nativeBackbone) {
11470
- prepared =
11471
- this._nativeBackbone.prepareStashedRawReceiveExpectedColumnsAndSelectionBatch(wireSession, stashBackedRawMessage.messageId, rawStashIndexes, hashes, prepareOptions);
11472
- }
11473
- if (!prepared &&
11474
- this._nativeBackbone
11475
- ?.prepareRawReceiveExpectedColumnsAndSelectionBatch) {
11476
- prepared =
11477
- this._nativeBackbone.prepareRawReceiveExpectedColumnsAndSelectionBatch(blocks(), hashes, prepareOptions);
11478
- }
11479
- if (!prepared) {
11480
- return undefined;
11481
- }
11482
- rawPreparedReceiveSelectionValue = prepared.selection;
11483
- rawPreparedReceiveSelection = Promise.resolve(rawPreparedReceiveSelectionValue);
11484
- return { columns: prepared.columns };
11485
- }
11486
- catch {
11487
- this.throwIfReplicationOwnershipPoisoned();
11488
- return undefined;
11489
- }
11490
- };
11491
- const rawMaterializeStartedAt = syncProfileStart(syncProfile);
11492
- const materializedRawMessage = await materializeVerifiedRawExchangeHeadsMessage(new RawExchangeHeadsMessage({
11493
- heads: rawMissingHeads,
11494
- reserved: msg.reserved,
11495
- }), this.log, syncProfile, {
11496
- nativeBackbone: this._nativeBackbone,
11497
- verifyNativeBackboneSignaturesDuringPrepare: verifyNativeBackboneSignaturesDuringPrepare,
11498
- deferNativeBackboneSignatureVerificationUntilSelection: deferNativeBackboneSignatureVerificationUntilSelection,
11499
- deferNativeBackboneSignatureVerificationUntilCommit: deferNativeBackboneSignatureVerificationUntilCommit,
11500
- prepareNativeBackboneExpectedColumnsAndSelection: prepareNativeBackboneExpectedColumnsAndSelection,
11501
- prepareNativeBackboneExpectedColumns: prepareNativeBackboneExpectedColumns,
11502
- tryPreparedRawReceiveFastDrop: rawIsRepairHint
11503
- ? undefined
11504
- : async ({ heads, hashes }) => this.tryFastDropPreparedRawReceive({
11505
- heads,
11506
- hashes,
11507
- from: rawFrom,
11508
- fromIsSelf,
11509
- syncProfile,
11510
- selection: await getRawPreparedReceiveSelection(heads, hashes),
11511
- receiveOwnershipRevision,
11512
- }),
11513
- selectPreparedRawReceiveHashes: rawIsRepairHint
11514
- ? undefined
11515
- : async ({ heads, hashes }) => this.selectNativePreparedRawReceiveHashes({
11516
- heads,
11517
- hashes,
11518
- from: rawFrom,
11519
- fromIsSelf,
11520
- syncProfile,
11521
- selection: await getRawPreparedReceiveSelection(heads, hashes),
11522
- receiveOwnershipRevision,
11523
- }),
11568
+ const materializedRawReceive = await this.materializeRawReceiveMessage(msg, {
11569
+ from: context.from,
11570
+ stashBackedRawMessage,
11571
+ syncProfile,
11572
+ receiveOwnershipRevision,
11524
11573
  });
11525
- if (materializedRawMessage === undefined) {
11526
- if (syncProfile) {
11527
- emitSyncProfileDuration(syncProfile, rawMaterializeStartedAt, {
11528
- name: "sharedLog.rawReceive.materialize",
11529
- component: "shared-log",
11530
- entries: rawMissingHeads.length,
11531
- bytes: rawMissingBytes,
11532
- messages: 1,
11533
- details: { nativeFastDropEarly: true },
11534
- });
11535
- }
11574
+ if (materializedRawReceive === undefined) {
11536
11575
  return;
11537
11576
  }
11538
- msg = materializedRawMessage;
11577
+ msg = materializedRawReceive.message;
11578
+ rawPreparedReceiveSelectionValue =
11579
+ materializedRawReceive.preparedSelection;
11539
11580
  rawMaterializedKnownMissing = true;
11540
- if (syncProfile) {
11541
- emitSyncProfileDuration(syncProfile, rawMaterializeStartedAt, {
11542
- name: "sharedLog.rawReceive.materialize",
11543
- component: "shared-log",
11544
- entries: rawMissingHeads.length,
11545
- bytes: rawMissingBytes,
11546
- messages: 1,
11547
- });
11548
- }
11549
11581
  }
11550
11582
  if (msg instanceof ExchangeHeadsMessage) {
11551
11583
  /**