@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.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +262 -230
- package/dist/src/index.js.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +373 -316
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
|
|
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
|
-
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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.
|
|
5026
|
-
|
|
5027
|
-
(this.
|
|
5028
|
-
|
|
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.
|
|
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
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
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 (
|
|
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 =
|
|
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
|
/**
|