@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/src/index.ts
CHANGED
|
@@ -1494,8 +1494,8 @@ const createRepairFrontierByMode = () =>
|
|
|
1494
1494
|
>(REPAIR_DISPATCH_MODES.map((mode) => [mode, new Map()]));
|
|
1495
1495
|
|
|
1496
1496
|
const createRepairActiveTargetsByMode = () =>
|
|
1497
|
-
new Map<RepairDispatchMode,
|
|
1498
|
-
REPAIR_DISPATCH_MODES.map((mode) => [mode, new
|
|
1497
|
+
new Map<RepairDispatchMode, Map<string, object>>(
|
|
1498
|
+
REPAIR_DISPATCH_MODES.map((mode) => [mode, new Map()]),
|
|
1499
1499
|
);
|
|
1500
1500
|
|
|
1501
1501
|
const createRepairFrontierBypassKnownPeersByMode = () =>
|
|
@@ -3246,7 +3246,7 @@ export class SharedLog<
|
|
|
3246
3246
|
>;
|
|
3247
3247
|
private _repairFrontierActiveTargetsByMode!: Map<
|
|
3248
3248
|
RepairDispatchMode,
|
|
3249
|
-
|
|
3249
|
+
Map<string, object>
|
|
3250
3250
|
>;
|
|
3251
3251
|
private _repairFrontierBypassKnownPeersByMode!: Map<
|
|
3252
3252
|
RepairDispatchMode,
|
|
@@ -7821,7 +7821,11 @@ export class SharedLog<
|
|
|
7821
7821
|
) {
|
|
7822
7822
|
return;
|
|
7823
7823
|
}
|
|
7824
|
-
|
|
7824
|
+
const runnerToken = {};
|
|
7825
|
+
activeTargets.set(target, runnerToken);
|
|
7826
|
+
const isCurrentRunner = () =>
|
|
7827
|
+
activeTargets.get(target) === runnerToken &&
|
|
7828
|
+
this.isRepairLifecycleActive(repairLifecycleController);
|
|
7825
7829
|
const retrySchedule = resolveRepairRetrySchedule(
|
|
7826
7830
|
mode,
|
|
7827
7831
|
retryScheduleMs,
|
|
@@ -7840,12 +7844,12 @@ export class SharedLog<
|
|
|
7840
7844
|
let attemptIndex = 0;
|
|
7841
7845
|
try {
|
|
7842
7846
|
for (;;) {
|
|
7843
|
-
if (!
|
|
7847
|
+
if (!isCurrentRunner()) {
|
|
7844
7848
|
return;
|
|
7845
7849
|
}
|
|
7846
7850
|
const pending = this._repairFrontierByMode.get(mode)?.get(target);
|
|
7847
7851
|
if (!pending || pending.size === 0) {
|
|
7848
|
-
if (!
|
|
7852
|
+
if (!isCurrentRunner()) {
|
|
7849
7853
|
return;
|
|
7850
7854
|
}
|
|
7851
7855
|
this._repairFrontierBypassKnownPeersByMode
|
|
@@ -7872,7 +7876,7 @@ export class SharedLog<
|
|
|
7872
7876
|
continue;
|
|
7873
7877
|
}
|
|
7874
7878
|
|
|
7875
|
-
if (!
|
|
7879
|
+
if (!isCurrentRunner()) {
|
|
7876
7880
|
return;
|
|
7877
7881
|
}
|
|
7878
7882
|
await this.sendMaybeMissingEntriesNow(
|
|
@@ -7889,7 +7893,7 @@ export class SharedLog<
|
|
|
7889
7893
|
},
|
|
7890
7894
|
repairLifecycleController,
|
|
7891
7895
|
);
|
|
7892
|
-
if (!
|
|
7896
|
+
if (!isCurrentRunner()) {
|
|
7893
7897
|
return;
|
|
7894
7898
|
}
|
|
7895
7899
|
|
|
@@ -7911,21 +7915,25 @@ export class SharedLog<
|
|
|
7911
7915
|
}
|
|
7912
7916
|
}
|
|
7913
7917
|
} finally {
|
|
7914
|
-
activeTargets.
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7918
|
+
if (activeTargets.get(target) === runnerToken) {
|
|
7919
|
+
activeTargets.delete(target);
|
|
7920
|
+
if (
|
|
7921
|
+
this.isRepairLifecycleActive(repairLifecycleController) &&
|
|
7922
|
+
(this._repairFrontierByMode.get(mode)?.get(target)?.size || 0) > 0
|
|
7923
|
+
) {
|
|
7924
|
+
this.ensureRepairFrontierRunner(
|
|
7925
|
+
mode,
|
|
7926
|
+
target,
|
|
7927
|
+
retryScheduleMs,
|
|
7928
|
+
repairLifecycleController,
|
|
7929
|
+
);
|
|
7930
|
+
}
|
|
7925
7931
|
}
|
|
7926
7932
|
}
|
|
7927
7933
|
})().catch((error: any) => {
|
|
7928
|
-
activeTargets.
|
|
7934
|
+
if (activeTargets.get(target) === runnerToken) {
|
|
7935
|
+
activeTargets.delete(target);
|
|
7936
|
+
}
|
|
7929
7937
|
if (this.isRepairLifecycleActive(repairLifecycleController)) {
|
|
7930
7938
|
logger.error(error);
|
|
7931
7939
|
}
|
|
@@ -16778,6 +16786,339 @@ export class SharedLog<
|
|
|
16778
16786
|
});
|
|
16779
16787
|
}
|
|
16780
16788
|
|
|
16789
|
+
/**
|
|
16790
|
+
* Normalize a raw exchange-heads receive into the regular exchange message
|
|
16791
|
+
* consumed by the rest of the receive path. An undefined result means the
|
|
16792
|
+
* message was fully handled (all heads were already present or the native
|
|
16793
|
+
* receive plan dropped every head).
|
|
16794
|
+
*
|
|
16795
|
+
* This helper intentionally runs inside `onMessage`'s shared try/finally
|
|
16796
|
+
* envelope so receive errors keep their existing classification and a
|
|
16797
|
+
* wire-backed message keeps its single outer stash-release boundary.
|
|
16798
|
+
*/
|
|
16799
|
+
private async materializeRawReceiveMessage(
|
|
16800
|
+
msg: RawExchangeHeadsMessage,
|
|
16801
|
+
properties: {
|
|
16802
|
+
from: PublicSignKey;
|
|
16803
|
+
stashBackedRawMessage?: StashBackedRawExchangeHeadsMessage;
|
|
16804
|
+
syncProfile?: SyncProfileFn;
|
|
16805
|
+
receiveOwnershipRevision: number;
|
|
16806
|
+
},
|
|
16807
|
+
): Promise<
|
|
16808
|
+
| {
|
|
16809
|
+
message: ExchangeHeadsMessage<any>;
|
|
16810
|
+
preparedSelection: NativeBackboneRawReceiveSelectionPlan | undefined;
|
|
16811
|
+
}
|
|
16812
|
+
| undefined
|
|
16813
|
+
> {
|
|
16814
|
+
const {
|
|
16815
|
+
from: rawFrom,
|
|
16816
|
+
stashBackedRawMessage,
|
|
16817
|
+
syncProfile,
|
|
16818
|
+
receiveOwnershipRevision,
|
|
16819
|
+
} = properties;
|
|
16820
|
+
const fromIsSelf = rawFrom.equals(this.node.identity.publicKey);
|
|
16821
|
+
if (syncProfile && !stashBackedRawMessage) {
|
|
16822
|
+
// Per-message JS-side entry decode: the heads were
|
|
16823
|
+
// borsh-decoded in TS (regular RPC path) instead of being
|
|
16824
|
+
// resolved from the native wire stash. Zero on the fused
|
|
16825
|
+
// hot path.
|
|
16826
|
+
emitSyncProfileEvent(syncProfile, {
|
|
16827
|
+
name: "sharedLog.rawReceive.jsEntryDecode",
|
|
16828
|
+
component: "shared-log",
|
|
16829
|
+
entries: msg.heads.length,
|
|
16830
|
+
messages: 1,
|
|
16831
|
+
});
|
|
16832
|
+
}
|
|
16833
|
+
const rawExistingStartedAt = syncProfileStart(syncProfile);
|
|
16834
|
+
const rawExistingHashes = await this.log.hasMany(
|
|
16835
|
+
msg.heads.map((head) => head.hash),
|
|
16836
|
+
);
|
|
16837
|
+
if (syncProfile) {
|
|
16838
|
+
emitSyncProfileDuration(syncProfile, rawExistingStartedAt, {
|
|
16839
|
+
name: "sharedLog.rawReceive.existingHeads",
|
|
16840
|
+
component: "shared-log",
|
|
16841
|
+
entries: msg.heads.length,
|
|
16842
|
+
messages: 1,
|
|
16843
|
+
});
|
|
16844
|
+
}
|
|
16845
|
+
const rawMissingHeads = [];
|
|
16846
|
+
const rawConfirmedHashes = new Set<string>();
|
|
16847
|
+
let rawMissingBytes = 0;
|
|
16848
|
+
for (const head of msg.heads) {
|
|
16849
|
+
if (rawExistingHashes.has(head.hash)) {
|
|
16850
|
+
rawConfirmedHashes.add(head.hash);
|
|
16851
|
+
} else {
|
|
16852
|
+
rawMissingHeads.push(head);
|
|
16853
|
+
rawMissingBytes += getRawExchangeHeadByteLength(head);
|
|
16854
|
+
}
|
|
16855
|
+
}
|
|
16856
|
+
if (rawConfirmedHashes.size > 0 && !fromIsSelf) {
|
|
16857
|
+
const rawConfirmStartedAt = syncProfileStart(syncProfile);
|
|
16858
|
+
this.markEntriesKnownByPeer(rawConfirmedHashes, rawFrom.hashcode());
|
|
16859
|
+
await this.sendRepairConfirmation(rawFrom, rawConfirmedHashes);
|
|
16860
|
+
if (syncProfile) {
|
|
16861
|
+
emitSyncProfileDuration(syncProfile, rawConfirmStartedAt, {
|
|
16862
|
+
name: "sharedLog.rawReceive.confirmExisting",
|
|
16863
|
+
component: "shared-log",
|
|
16864
|
+
entries: rawConfirmedHashes.size,
|
|
16865
|
+
messages: 1,
|
|
16866
|
+
});
|
|
16867
|
+
}
|
|
16868
|
+
}
|
|
16869
|
+
if (rawMissingHeads.length === 0) {
|
|
16870
|
+
return undefined;
|
|
16871
|
+
}
|
|
16872
|
+
const rawIsRepairHint =
|
|
16873
|
+
(msg.reserved[0] & EXCHANGE_HEADS_REPAIR_HINT) !== 0;
|
|
16874
|
+
const rawPrepareVerifySetting =
|
|
16875
|
+
this._logProperties?.sync?.rawExchangeHeadsVerifySignaturesDuringPrepare;
|
|
16876
|
+
// A program-level canAppend hook must observe every entry before
|
|
16877
|
+
// it commits, so the native join commit (which validates and
|
|
16878
|
+
// commits entirely in wasm) is not used for programs that
|
|
16879
|
+
// register one; those joins run through the lower-log batch
|
|
16880
|
+
// join where the hook fires per entry.
|
|
16881
|
+
const programCanAppend = !!this._logProperties?.canAppend;
|
|
16882
|
+
const canVerifyPreparedRawReceiveOnCommit =
|
|
16883
|
+
!programCanAppend &&
|
|
16884
|
+
!!this._nativeBackbone?.graph.commitVerifiedPreparedRawReceiveJoinBatch;
|
|
16885
|
+
const canDeferRawReceiveVerificationUntilNativeSelection =
|
|
16886
|
+
!rawIsRepairHint &&
|
|
16887
|
+
!!this._nativeBackbone?.verifyPreparedRawReceiveEntries &&
|
|
16888
|
+
!this._isReplicating &&
|
|
16889
|
+
!this.keep &&
|
|
16890
|
+
!this.closed &&
|
|
16891
|
+
!!this.syncronizer.onReceivedEntryHashes &&
|
|
16892
|
+
rawMissingHeads.every((head) => head.gidRefrences.length === 0);
|
|
16893
|
+
const verifyNativeBackboneSignaturesDuringPrepare =
|
|
16894
|
+
rawPrepareVerifySetting === true ||
|
|
16895
|
+
(rawPrepareVerifySetting !== false &&
|
|
16896
|
+
(canDeferRawReceiveVerificationUntilNativeSelection ||
|
|
16897
|
+
(this._isReplicating &&
|
|
16898
|
+
!rawIsRepairHint &&
|
|
16899
|
+
!canVerifyPreparedRawReceiveOnCommit)));
|
|
16900
|
+
const deferNativeBackboneSignatureVerificationUntilSelection =
|
|
16901
|
+
verifyNativeBackboneSignaturesDuringPrepare &&
|
|
16902
|
+
canDeferRawReceiveVerificationUntilNativeSelection;
|
|
16903
|
+
const deferNativeBackboneSignatureVerificationUntilCommit =
|
|
16904
|
+
deferNativeBackboneSignatureVerificationUntilSelection &&
|
|
16905
|
+
!programCanAppend &&
|
|
16906
|
+
!!this._nativeBackbone?.graph.commitVerifiedPreparedRawReceiveJoinBatch;
|
|
16907
|
+
let rawPreparedReceiveSelectionValue:
|
|
16908
|
+
| NativeBackboneRawReceiveSelectionPlan
|
|
16909
|
+
| undefined;
|
|
16910
|
+
let rawPreparedReceiveSelection:
|
|
16911
|
+
| Promise<NativeBackboneRawReceiveSelectionPlan | undefined>
|
|
16912
|
+
| undefined;
|
|
16913
|
+
const getRawPreparedReceiveSelection = async (
|
|
16914
|
+
heads: RawEntryWithRefs[],
|
|
16915
|
+
hashes: string[],
|
|
16916
|
+
) => {
|
|
16917
|
+
if (rawPreparedReceiveSelectionValue) {
|
|
16918
|
+
return rawPreparedReceiveSelectionValue;
|
|
16919
|
+
}
|
|
16920
|
+
rawPreparedReceiveSelection ??=
|
|
16921
|
+
this.planNativePreparedRawReceiveSelection({
|
|
16922
|
+
heads,
|
|
16923
|
+
hashes,
|
|
16924
|
+
from: rawFrom,
|
|
16925
|
+
});
|
|
16926
|
+
rawPreparedReceiveSelectionValue = await rawPreparedReceiveSelection;
|
|
16927
|
+
return rawPreparedReceiveSelectionValue;
|
|
16928
|
+
};
|
|
16929
|
+
// Receive fusion: when this message was resolved from the wire
|
|
16930
|
+
// stash, the prepared receive reads entry block bytes straight
|
|
16931
|
+
// out of wasm memory (indexed into the stashed frame) instead
|
|
16932
|
+
// of copying a JS blocks array across the boundary.
|
|
16933
|
+
const rawStashIndexes = stashBackedRawMessage
|
|
16934
|
+
? getRawExchangeHeadStashIndexes(rawMissingHeads)
|
|
16935
|
+
: undefined;
|
|
16936
|
+
const prepareNativeBackboneExpectedColumns =
|
|
16937
|
+
stashBackedRawMessage && rawStashIndexes
|
|
16938
|
+
? ({
|
|
16939
|
+
hashes,
|
|
16940
|
+
verifySignatures,
|
|
16941
|
+
}: {
|
|
16942
|
+
hashes: string[];
|
|
16943
|
+
verifySignatures: boolean;
|
|
16944
|
+
}) => {
|
|
16945
|
+
const backbone = this._nativeBackbone;
|
|
16946
|
+
const wireSession = this._wireSyncSession;
|
|
16947
|
+
if (!backbone || !wireSession) {
|
|
16948
|
+
return undefined;
|
|
16949
|
+
}
|
|
16950
|
+
try {
|
|
16951
|
+
return backbone.prepareStashedRawReceiveExpectedColumnsBatch(
|
|
16952
|
+
wireSession,
|
|
16953
|
+
stashBackedRawMessage.messageId,
|
|
16954
|
+
rawStashIndexes,
|
|
16955
|
+
hashes,
|
|
16956
|
+
{ verifySignatures },
|
|
16957
|
+
);
|
|
16958
|
+
} catch {
|
|
16959
|
+
return undefined;
|
|
16960
|
+
}
|
|
16961
|
+
}
|
|
16962
|
+
: undefined;
|
|
16963
|
+
const prepareNativeBackboneExpectedColumnsAndSelection = rawIsRepairHint
|
|
16964
|
+
? undefined
|
|
16965
|
+
: async ({
|
|
16966
|
+
blocks,
|
|
16967
|
+
hashes,
|
|
16968
|
+
verifySignatures,
|
|
16969
|
+
}: {
|
|
16970
|
+
blocks: () => Uint8Array[];
|
|
16971
|
+
hashes: string[];
|
|
16972
|
+
verifySignatures: boolean;
|
|
16973
|
+
}) => {
|
|
16974
|
+
if (
|
|
16975
|
+
verifySignatures ||
|
|
16976
|
+
!canDeferRawReceiveVerificationUntilNativeSelection
|
|
16977
|
+
) {
|
|
16978
|
+
return undefined;
|
|
16979
|
+
}
|
|
16980
|
+
try {
|
|
16981
|
+
const replicaOptions = {
|
|
16982
|
+
minReplicas: this.replicas.min?.getValue(this) || 1,
|
|
16983
|
+
maxReplicas: this.replicas.max?.getValue(this),
|
|
16984
|
+
};
|
|
16985
|
+
const leaderSelectionContext =
|
|
16986
|
+
await this.createLeaderSelectionContext();
|
|
16987
|
+
const prepareOptions = {
|
|
16988
|
+
verifySignatures: false as const,
|
|
16989
|
+
...replicaOptions,
|
|
16990
|
+
leaderOptions: this.createNativeLeaderOptions(
|
|
16991
|
+
leaderSelectionContext,
|
|
16992
|
+
),
|
|
16993
|
+
fromHash: rawFrom.hashcode(),
|
|
16994
|
+
};
|
|
16995
|
+
let prepared:
|
|
16996
|
+
| ReturnType<
|
|
16997
|
+
NativePeerbitBackbone["prepareRawReceiveExpectedColumnsAndSelectionBatch"]
|
|
16998
|
+
>
|
|
16999
|
+
| undefined;
|
|
17000
|
+
const wireSession = this._wireSyncSession;
|
|
17001
|
+
if (
|
|
17002
|
+
stashBackedRawMessage &&
|
|
17003
|
+
rawStashIndexes &&
|
|
17004
|
+
wireSession &&
|
|
17005
|
+
this._nativeBackbone
|
|
17006
|
+
) {
|
|
17007
|
+
prepared =
|
|
17008
|
+
this._nativeBackbone.prepareStashedRawReceiveExpectedColumnsAndSelectionBatch(
|
|
17009
|
+
wireSession,
|
|
17010
|
+
stashBackedRawMessage.messageId,
|
|
17011
|
+
rawStashIndexes,
|
|
17012
|
+
hashes,
|
|
17013
|
+
prepareOptions,
|
|
17014
|
+
);
|
|
17015
|
+
}
|
|
17016
|
+
if (
|
|
17017
|
+
!prepared &&
|
|
17018
|
+
this._nativeBackbone
|
|
17019
|
+
?.prepareRawReceiveExpectedColumnsAndSelectionBatch
|
|
17020
|
+
) {
|
|
17021
|
+
prepared =
|
|
17022
|
+
this._nativeBackbone.prepareRawReceiveExpectedColumnsAndSelectionBatch(
|
|
17023
|
+
blocks(),
|
|
17024
|
+
hashes,
|
|
17025
|
+
prepareOptions,
|
|
17026
|
+
);
|
|
17027
|
+
}
|
|
17028
|
+
if (!prepared) {
|
|
17029
|
+
return undefined;
|
|
17030
|
+
}
|
|
17031
|
+
rawPreparedReceiveSelectionValue = prepared.selection;
|
|
17032
|
+
rawPreparedReceiveSelection = Promise.resolve(
|
|
17033
|
+
rawPreparedReceiveSelectionValue,
|
|
17034
|
+
);
|
|
17035
|
+
return { columns: prepared.columns };
|
|
17036
|
+
} catch {
|
|
17037
|
+
this.throwIfReplicationOwnershipPoisoned();
|
|
17038
|
+
return undefined;
|
|
17039
|
+
}
|
|
17040
|
+
};
|
|
17041
|
+
const rawMaterializeStartedAt = syncProfileStart(syncProfile);
|
|
17042
|
+
const materializedRawMessage =
|
|
17043
|
+
await materializeVerifiedRawExchangeHeadsMessage(
|
|
17044
|
+
new RawExchangeHeadsMessage({
|
|
17045
|
+
heads: rawMissingHeads,
|
|
17046
|
+
reserved: msg.reserved,
|
|
17047
|
+
}),
|
|
17048
|
+
this.log,
|
|
17049
|
+
syncProfile,
|
|
17050
|
+
{
|
|
17051
|
+
nativeBackbone: this._nativeBackbone,
|
|
17052
|
+
verifyNativeBackboneSignaturesDuringPrepare:
|
|
17053
|
+
verifyNativeBackboneSignaturesDuringPrepare,
|
|
17054
|
+
deferNativeBackboneSignatureVerificationUntilSelection:
|
|
17055
|
+
deferNativeBackboneSignatureVerificationUntilSelection,
|
|
17056
|
+
deferNativeBackboneSignatureVerificationUntilCommit:
|
|
17057
|
+
deferNativeBackboneSignatureVerificationUntilCommit,
|
|
17058
|
+
prepareNativeBackboneExpectedColumnsAndSelection:
|
|
17059
|
+
prepareNativeBackboneExpectedColumnsAndSelection,
|
|
17060
|
+
prepareNativeBackboneExpectedColumns:
|
|
17061
|
+
prepareNativeBackboneExpectedColumns,
|
|
17062
|
+
tryPreparedRawReceiveFastDrop: rawIsRepairHint
|
|
17063
|
+
? undefined
|
|
17064
|
+
: async ({ heads, hashes }) =>
|
|
17065
|
+
this.tryFastDropPreparedRawReceive({
|
|
17066
|
+
heads,
|
|
17067
|
+
hashes,
|
|
17068
|
+
from: rawFrom,
|
|
17069
|
+
fromIsSelf,
|
|
17070
|
+
syncProfile,
|
|
17071
|
+
selection: await getRawPreparedReceiveSelection(
|
|
17072
|
+
heads,
|
|
17073
|
+
hashes,
|
|
17074
|
+
),
|
|
17075
|
+
receiveOwnershipRevision,
|
|
17076
|
+
}),
|
|
17077
|
+
selectPreparedRawReceiveHashes: rawIsRepairHint
|
|
17078
|
+
? undefined
|
|
17079
|
+
: async ({ heads, hashes }) =>
|
|
17080
|
+
this.selectNativePreparedRawReceiveHashes({
|
|
17081
|
+
heads,
|
|
17082
|
+
hashes,
|
|
17083
|
+
from: rawFrom,
|
|
17084
|
+
fromIsSelf,
|
|
17085
|
+
syncProfile,
|
|
17086
|
+
selection: await getRawPreparedReceiveSelection(
|
|
17087
|
+
heads,
|
|
17088
|
+
hashes,
|
|
17089
|
+
),
|
|
17090
|
+
receiveOwnershipRevision,
|
|
17091
|
+
}),
|
|
17092
|
+
},
|
|
17093
|
+
);
|
|
17094
|
+
if (materializedRawMessage === undefined) {
|
|
17095
|
+
if (syncProfile) {
|
|
17096
|
+
emitSyncProfileDuration(syncProfile, rawMaterializeStartedAt, {
|
|
17097
|
+
name: "sharedLog.rawReceive.materialize",
|
|
17098
|
+
component: "shared-log",
|
|
17099
|
+
entries: rawMissingHeads.length,
|
|
17100
|
+
bytes: rawMissingBytes,
|
|
17101
|
+
messages: 1,
|
|
17102
|
+
details: { nativeFastDropEarly: true },
|
|
17103
|
+
});
|
|
17104
|
+
}
|
|
17105
|
+
return undefined;
|
|
17106
|
+
}
|
|
17107
|
+
if (syncProfile) {
|
|
17108
|
+
emitSyncProfileDuration(syncProfile, rawMaterializeStartedAt, {
|
|
17109
|
+
name: "sharedLog.rawReceive.materialize",
|
|
17110
|
+
component: "shared-log",
|
|
17111
|
+
entries: rawMissingHeads.length,
|
|
17112
|
+
bytes: rawMissingBytes,
|
|
17113
|
+
messages: 1,
|
|
17114
|
+
});
|
|
17115
|
+
}
|
|
17116
|
+
return {
|
|
17117
|
+
message: materializedRawMessage,
|
|
17118
|
+
preparedSelection: rawPreparedReceiveSelectionValue,
|
|
17119
|
+
};
|
|
17120
|
+
}
|
|
17121
|
+
|
|
16781
17122
|
// Callback for receiving a message from the network
|
|
16782
17123
|
async onMessage(
|
|
16783
17124
|
msg: TransportMessage,
|
|
@@ -16855,307 +17196,23 @@ export class SharedLog<
|
|
|
16855
17196
|
| NativeBackboneRawReceiveSelectionPlan
|
|
16856
17197
|
| undefined;
|
|
16857
17198
|
if (msg instanceof RawExchangeHeadsMessage) {
|
|
16858
|
-
const
|
|
16859
|
-
|
|
16860
|
-
|
|
16861
|
-
|
|
16862
|
-
|
|
16863
|
-
// resolved from the native wire stash. Zero on the fused
|
|
16864
|
-
// hot path.
|
|
16865
|
-
emitSyncProfileEvent(syncProfile, {
|
|
16866
|
-
name: "sharedLog.rawReceive.jsEntryDecode",
|
|
16867
|
-
component: "shared-log",
|
|
16868
|
-
entries: msg.heads.length,
|
|
16869
|
-
messages: 1,
|
|
16870
|
-
});
|
|
16871
|
-
}
|
|
16872
|
-
const rawExistingStartedAt = syncProfileStart(syncProfile);
|
|
16873
|
-
const rawExistingHashes = await this.log.hasMany(
|
|
16874
|
-
msg.heads.map((head) => head.hash),
|
|
16875
|
-
);
|
|
16876
|
-
if (syncProfile) {
|
|
16877
|
-
emitSyncProfileDuration(syncProfile, rawExistingStartedAt, {
|
|
16878
|
-
name: "sharedLog.rawReceive.existingHeads",
|
|
16879
|
-
component: "shared-log",
|
|
16880
|
-
entries: msg.heads.length,
|
|
16881
|
-
messages: 1,
|
|
16882
|
-
});
|
|
16883
|
-
}
|
|
16884
|
-
const rawMissingHeads = [];
|
|
16885
|
-
const rawConfirmedHashes = new Set<string>();
|
|
16886
|
-
let rawMissingBytes = 0;
|
|
16887
|
-
for (const head of msg.heads) {
|
|
16888
|
-
if (rawExistingHashes.has(head.hash)) {
|
|
16889
|
-
rawConfirmedHashes.add(head.hash);
|
|
16890
|
-
} else {
|
|
16891
|
-
rawMissingHeads.push(head);
|
|
16892
|
-
rawMissingBytes += getRawExchangeHeadByteLength(head);
|
|
16893
|
-
}
|
|
16894
|
-
}
|
|
16895
|
-
if (rawConfirmedHashes.size > 0 && !fromIsSelf) {
|
|
16896
|
-
const rawConfirmStartedAt = syncProfileStart(syncProfile);
|
|
16897
|
-
this.markEntriesKnownByPeer(rawConfirmedHashes, rawFrom.hashcode());
|
|
16898
|
-
await this.sendRepairConfirmation(rawFrom, rawConfirmedHashes);
|
|
16899
|
-
if (syncProfile) {
|
|
16900
|
-
emitSyncProfileDuration(syncProfile, rawConfirmStartedAt, {
|
|
16901
|
-
name: "sharedLog.rawReceive.confirmExisting",
|
|
16902
|
-
component: "shared-log",
|
|
16903
|
-
entries: rawConfirmedHashes.size,
|
|
16904
|
-
messages: 1,
|
|
16905
|
-
});
|
|
16906
|
-
}
|
|
16907
|
-
}
|
|
16908
|
-
if (rawMissingHeads.length === 0) {
|
|
16909
|
-
return;
|
|
16910
|
-
}
|
|
16911
|
-
const rawIsRepairHint =
|
|
16912
|
-
(msg.reserved[0] & EXCHANGE_HEADS_REPAIR_HINT) !== 0;
|
|
16913
|
-
const rawPrepareVerifySetting =
|
|
16914
|
-
this._logProperties?.sync
|
|
16915
|
-
?.rawExchangeHeadsVerifySignaturesDuringPrepare;
|
|
16916
|
-
// A program-level canAppend hook must observe every entry before
|
|
16917
|
-
// it commits, so the native join commit (which validates and
|
|
16918
|
-
// commits entirely in wasm) is not used for programs that
|
|
16919
|
-
// register one; those joins run through the lower-log batch
|
|
16920
|
-
// join where the hook fires per entry.
|
|
16921
|
-
const programCanAppend = !!this._logProperties?.canAppend;
|
|
16922
|
-
const canVerifyPreparedRawReceiveOnCommit =
|
|
16923
|
-
!programCanAppend &&
|
|
16924
|
-
!!this._nativeBackbone?.graph
|
|
16925
|
-
.commitVerifiedPreparedRawReceiveJoinBatch;
|
|
16926
|
-
const canDeferRawReceiveVerificationUntilNativeSelection =
|
|
16927
|
-
!rawIsRepairHint &&
|
|
16928
|
-
!!this._nativeBackbone?.verifyPreparedRawReceiveEntries &&
|
|
16929
|
-
!this._isReplicating &&
|
|
16930
|
-
!this.keep &&
|
|
16931
|
-
!this.closed &&
|
|
16932
|
-
!!this.syncronizer.onReceivedEntryHashes &&
|
|
16933
|
-
rawMissingHeads.every((head) => head.gidRefrences.length === 0);
|
|
16934
|
-
const verifyNativeBackboneSignaturesDuringPrepare =
|
|
16935
|
-
rawPrepareVerifySetting === true ||
|
|
16936
|
-
(rawPrepareVerifySetting !== false &&
|
|
16937
|
-
(canDeferRawReceiveVerificationUntilNativeSelection ||
|
|
16938
|
-
(this._isReplicating &&
|
|
16939
|
-
!rawIsRepairHint &&
|
|
16940
|
-
!canVerifyPreparedRawReceiveOnCommit)));
|
|
16941
|
-
const deferNativeBackboneSignatureVerificationUntilSelection =
|
|
16942
|
-
verifyNativeBackboneSignaturesDuringPrepare &&
|
|
16943
|
-
canDeferRawReceiveVerificationUntilNativeSelection;
|
|
16944
|
-
const deferNativeBackboneSignatureVerificationUntilCommit =
|
|
16945
|
-
deferNativeBackboneSignatureVerificationUntilSelection &&
|
|
16946
|
-
!programCanAppend &&
|
|
16947
|
-
!!this._nativeBackbone?.graph
|
|
16948
|
-
.commitVerifiedPreparedRawReceiveJoinBatch;
|
|
16949
|
-
let rawPreparedReceiveSelection:
|
|
16950
|
-
| Promise<NativeBackboneRawReceiveSelectionPlan | undefined>
|
|
16951
|
-
| undefined;
|
|
16952
|
-
const getRawPreparedReceiveSelection = async (
|
|
16953
|
-
heads: RawEntryWithRefs[],
|
|
16954
|
-
hashes: string[],
|
|
16955
|
-
) => {
|
|
16956
|
-
if (rawPreparedReceiveSelectionValue) {
|
|
16957
|
-
return rawPreparedReceiveSelectionValue;
|
|
16958
|
-
}
|
|
16959
|
-
rawPreparedReceiveSelection ??=
|
|
16960
|
-
this.planNativePreparedRawReceiveSelection({
|
|
16961
|
-
heads,
|
|
16962
|
-
hashes,
|
|
16963
|
-
from: rawFrom,
|
|
16964
|
-
});
|
|
16965
|
-
rawPreparedReceiveSelectionValue = await rawPreparedReceiveSelection;
|
|
16966
|
-
return rawPreparedReceiveSelectionValue;
|
|
16967
|
-
};
|
|
16968
|
-
// Receive fusion: when this message was resolved from the wire
|
|
16969
|
-
// stash, the prepared receive reads entry block bytes straight
|
|
16970
|
-
// out of wasm memory (indexed into the stashed frame) instead
|
|
16971
|
-
// of copying a JS blocks array across the boundary.
|
|
16972
|
-
const rawStashIndexes = stashBackedRawMessage
|
|
16973
|
-
? getRawExchangeHeadStashIndexes(rawMissingHeads)
|
|
16974
|
-
: undefined;
|
|
16975
|
-
const prepareNativeBackboneExpectedColumns =
|
|
16976
|
-
stashBackedRawMessage && rawStashIndexes
|
|
16977
|
-
? ({
|
|
16978
|
-
hashes,
|
|
16979
|
-
verifySignatures,
|
|
16980
|
-
}: {
|
|
16981
|
-
hashes: string[];
|
|
16982
|
-
verifySignatures: boolean;
|
|
16983
|
-
}) => {
|
|
16984
|
-
const backbone = this._nativeBackbone;
|
|
16985
|
-
const wireSession = this._wireSyncSession;
|
|
16986
|
-
if (!backbone || !wireSession) {
|
|
16987
|
-
return undefined;
|
|
16988
|
-
}
|
|
16989
|
-
try {
|
|
16990
|
-
return backbone.prepareStashedRawReceiveExpectedColumnsBatch(
|
|
16991
|
-
wireSession,
|
|
16992
|
-
stashBackedRawMessage.messageId,
|
|
16993
|
-
rawStashIndexes,
|
|
16994
|
-
hashes,
|
|
16995
|
-
{ verifySignatures },
|
|
16996
|
-
);
|
|
16997
|
-
} catch {
|
|
16998
|
-
return undefined;
|
|
16999
|
-
}
|
|
17000
|
-
}
|
|
17001
|
-
: undefined;
|
|
17002
|
-
const prepareNativeBackboneExpectedColumnsAndSelection = rawIsRepairHint
|
|
17003
|
-
? undefined
|
|
17004
|
-
: async ({
|
|
17005
|
-
blocks,
|
|
17006
|
-
hashes,
|
|
17007
|
-
verifySignatures,
|
|
17008
|
-
}: {
|
|
17009
|
-
blocks: () => Uint8Array[];
|
|
17010
|
-
hashes: string[];
|
|
17011
|
-
verifySignatures: boolean;
|
|
17012
|
-
}) => {
|
|
17013
|
-
if (
|
|
17014
|
-
verifySignatures ||
|
|
17015
|
-
!canDeferRawReceiveVerificationUntilNativeSelection
|
|
17016
|
-
) {
|
|
17017
|
-
return undefined;
|
|
17018
|
-
}
|
|
17019
|
-
try {
|
|
17020
|
-
const replicaOptions = {
|
|
17021
|
-
minReplicas: this.replicas.min?.getValue(this) || 1,
|
|
17022
|
-
maxReplicas: this.replicas.max?.getValue(this),
|
|
17023
|
-
};
|
|
17024
|
-
const leaderSelectionContext =
|
|
17025
|
-
await this.createLeaderSelectionContext();
|
|
17026
|
-
const prepareOptions = {
|
|
17027
|
-
verifySignatures: false as const,
|
|
17028
|
-
...replicaOptions,
|
|
17029
|
-
leaderOptions: this.createNativeLeaderOptions(
|
|
17030
|
-
leaderSelectionContext,
|
|
17031
|
-
),
|
|
17032
|
-
fromHash: rawFrom.hashcode(),
|
|
17033
|
-
};
|
|
17034
|
-
let prepared:
|
|
17035
|
-
| ReturnType<
|
|
17036
|
-
NativePeerbitBackbone["prepareRawReceiveExpectedColumnsAndSelectionBatch"]
|
|
17037
|
-
>
|
|
17038
|
-
| undefined;
|
|
17039
|
-
const wireSession = this._wireSyncSession;
|
|
17040
|
-
if (
|
|
17041
|
-
stashBackedRawMessage &&
|
|
17042
|
-
rawStashIndexes &&
|
|
17043
|
-
wireSession &&
|
|
17044
|
-
this._nativeBackbone
|
|
17045
|
-
) {
|
|
17046
|
-
prepared =
|
|
17047
|
-
this._nativeBackbone.prepareStashedRawReceiveExpectedColumnsAndSelectionBatch(
|
|
17048
|
-
wireSession,
|
|
17049
|
-
stashBackedRawMessage.messageId,
|
|
17050
|
-
rawStashIndexes,
|
|
17051
|
-
hashes,
|
|
17052
|
-
prepareOptions,
|
|
17053
|
-
);
|
|
17054
|
-
}
|
|
17055
|
-
if (
|
|
17056
|
-
!prepared &&
|
|
17057
|
-
this._nativeBackbone
|
|
17058
|
-
?.prepareRawReceiveExpectedColumnsAndSelectionBatch
|
|
17059
|
-
) {
|
|
17060
|
-
prepared =
|
|
17061
|
-
this._nativeBackbone.prepareRawReceiveExpectedColumnsAndSelectionBatch(
|
|
17062
|
-
blocks(),
|
|
17063
|
-
hashes,
|
|
17064
|
-
prepareOptions,
|
|
17065
|
-
);
|
|
17066
|
-
}
|
|
17067
|
-
if (!prepared) {
|
|
17068
|
-
return undefined;
|
|
17069
|
-
}
|
|
17070
|
-
rawPreparedReceiveSelectionValue = prepared.selection;
|
|
17071
|
-
rawPreparedReceiveSelection = Promise.resolve(
|
|
17072
|
-
rawPreparedReceiveSelectionValue,
|
|
17073
|
-
);
|
|
17074
|
-
return { columns: prepared.columns };
|
|
17075
|
-
} catch {
|
|
17076
|
-
this.throwIfReplicationOwnershipPoisoned();
|
|
17077
|
-
return undefined;
|
|
17078
|
-
}
|
|
17079
|
-
};
|
|
17080
|
-
const rawMaterializeStartedAt = syncProfileStart(syncProfile);
|
|
17081
|
-
const materializedRawMessage =
|
|
17082
|
-
await materializeVerifiedRawExchangeHeadsMessage(
|
|
17083
|
-
new RawExchangeHeadsMessage({
|
|
17084
|
-
heads: rawMissingHeads,
|
|
17085
|
-
reserved: msg.reserved,
|
|
17086
|
-
}),
|
|
17087
|
-
this.log,
|
|
17199
|
+
const materializedRawReceive = await this.materializeRawReceiveMessage(
|
|
17200
|
+
msg,
|
|
17201
|
+
{
|
|
17202
|
+
from: context.from,
|
|
17203
|
+
stashBackedRawMessage,
|
|
17088
17204
|
syncProfile,
|
|
17089
|
-
|
|
17090
|
-
|
|
17091
|
-
|
|
17092
|
-
|
|
17093
|
-
deferNativeBackboneSignatureVerificationUntilSelection:
|
|
17094
|
-
deferNativeBackboneSignatureVerificationUntilSelection,
|
|
17095
|
-
deferNativeBackboneSignatureVerificationUntilCommit:
|
|
17096
|
-
deferNativeBackboneSignatureVerificationUntilCommit,
|
|
17097
|
-
prepareNativeBackboneExpectedColumnsAndSelection:
|
|
17098
|
-
prepareNativeBackboneExpectedColumnsAndSelection,
|
|
17099
|
-
prepareNativeBackboneExpectedColumns:
|
|
17100
|
-
prepareNativeBackboneExpectedColumns,
|
|
17101
|
-
tryPreparedRawReceiveFastDrop: rawIsRepairHint
|
|
17102
|
-
? undefined
|
|
17103
|
-
: async ({ heads, hashes }) =>
|
|
17104
|
-
this.tryFastDropPreparedRawReceive({
|
|
17105
|
-
heads,
|
|
17106
|
-
hashes,
|
|
17107
|
-
from: rawFrom,
|
|
17108
|
-
fromIsSelf,
|
|
17109
|
-
syncProfile,
|
|
17110
|
-
selection: await getRawPreparedReceiveSelection(
|
|
17111
|
-
heads,
|
|
17112
|
-
hashes,
|
|
17113
|
-
),
|
|
17114
|
-
receiveOwnershipRevision,
|
|
17115
|
-
}),
|
|
17116
|
-
selectPreparedRawReceiveHashes: rawIsRepairHint
|
|
17117
|
-
? undefined
|
|
17118
|
-
: async ({ heads, hashes }) =>
|
|
17119
|
-
this.selectNativePreparedRawReceiveHashes({
|
|
17120
|
-
heads,
|
|
17121
|
-
hashes,
|
|
17122
|
-
from: rawFrom,
|
|
17123
|
-
fromIsSelf,
|
|
17124
|
-
syncProfile,
|
|
17125
|
-
selection: await getRawPreparedReceiveSelection(
|
|
17126
|
-
heads,
|
|
17127
|
-
hashes,
|
|
17128
|
-
),
|
|
17129
|
-
receiveOwnershipRevision,
|
|
17130
|
-
}),
|
|
17131
|
-
},
|
|
17132
|
-
);
|
|
17133
|
-
if (materializedRawMessage === undefined) {
|
|
17134
|
-
if (syncProfile) {
|
|
17135
|
-
emitSyncProfileDuration(syncProfile, rawMaterializeStartedAt, {
|
|
17136
|
-
name: "sharedLog.rawReceive.materialize",
|
|
17137
|
-
component: "shared-log",
|
|
17138
|
-
entries: rawMissingHeads.length,
|
|
17139
|
-
bytes: rawMissingBytes,
|
|
17140
|
-
messages: 1,
|
|
17141
|
-
details: { nativeFastDropEarly: true },
|
|
17142
|
-
});
|
|
17143
|
-
}
|
|
17205
|
+
receiveOwnershipRevision,
|
|
17206
|
+
},
|
|
17207
|
+
);
|
|
17208
|
+
if (materializedRawReceive === undefined) {
|
|
17144
17209
|
return;
|
|
17145
17210
|
}
|
|
17146
|
-
msg =
|
|
17211
|
+
msg = materializedRawReceive.message;
|
|
17212
|
+
rawPreparedReceiveSelectionValue =
|
|
17213
|
+
materializedRawReceive.preparedSelection;
|
|
17147
17214
|
rawMaterializedKnownMissing = true;
|
|
17148
|
-
if (syncProfile) {
|
|
17149
|
-
emitSyncProfileDuration(syncProfile, rawMaterializeStartedAt, {
|
|
17150
|
-
name: "sharedLog.rawReceive.materialize",
|
|
17151
|
-
component: "shared-log",
|
|
17152
|
-
entries: rawMissingHeads.length,
|
|
17153
|
-
bytes: rawMissingBytes,
|
|
17154
|
-
messages: 1,
|
|
17155
|
-
});
|
|
17156
|
-
}
|
|
17157
17215
|
}
|
|
17158
|
-
|
|
17159
17216
|
if (msg instanceof ExchangeHeadsMessage) {
|
|
17160
17217
|
/**
|
|
17161
17218
|
* I have received heads from someone else.
|