@optimystic/db-p2p 1.0.0-beta.3 → 1.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.
- package/dist/src/cluster/block-transfer-service.d.ts +73 -1
- package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer-service.js +70 -3
- package/dist/src/cluster/block-transfer-service.js.map +1 -1
- package/dist/src/cluster/block-transfer.d.ts +16 -1
- package/dist/src/cluster/block-transfer.d.ts.map +1 -1
- package/dist/src/cluster/block-transfer.js +73 -72
- package/dist/src/cluster/block-transfer.js.map +1 -1
- package/dist/src/cluster/client.d.ts +4 -6
- package/dist/src/cluster/client.d.ts.map +1 -1
- package/dist/src/cluster/client.js +8 -13
- package/dist/src/cluster/client.js.map +1 -1
- package/dist/src/cluster/cluster-policy.d.ts +2 -1
- package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
- package/dist/src/cluster/cluster-policy.js.map +1 -1
- package/dist/src/cluster/cluster-repo.d.ts +126 -6
- package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
- package/dist/src/cluster/cluster-repo.js +378 -50
- package/dist/src/cluster/cluster-repo.js.map +1 -1
- package/dist/src/cluster/commit-proof.js +2 -2
- package/dist/src/cluster/race-resolution.d.ts +51 -7
- package/dist/src/cluster/race-resolution.d.ts.map +1 -1
- package/dist/src/cluster/race-resolution.js +71 -7
- package/dist/src/cluster/race-resolution.js.map +1 -1
- package/dist/src/cluster/rebalance-monitor.d.ts +67 -5
- package/dist/src/cluster/rebalance-monitor.d.ts.map +1 -1
- package/dist/src/cluster/rebalance-monitor.js +120 -26
- package/dist/src/cluster/rebalance-monitor.js.map +1 -1
- package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
- package/dist/src/cluster/spread-on-churn.js +34 -47
- package/dist/src/cluster/spread-on-churn.js.map +1 -1
- package/dist/src/cohort-topic/host.d.ts.map +1 -1
- package/dist/src/cohort-topic/host.js +8 -6
- package/dist/src/cohort-topic/host.js.map +1 -1
- package/dist/src/cohort-topic/membership-source.js +1 -1
- package/dist/src/cohort-topic/membership-source.js.map +1 -1
- package/dist/src/cohort-topic/peer-codec.d.ts.map +1 -1
- package/dist/src/cohort-topic/peer-codec.js +5 -2
- package/dist/src/cohort-topic/peer-codec.js.map +1 -1
- package/dist/src/cohort-topic/stream-util.d.ts +24 -3
- package/dist/src/cohort-topic/stream-util.d.ts.map +1 -1
- package/dist/src/cohort-topic/stream-util.js +36 -3
- package/dist/src/cohort-topic/stream-util.js.map +1 -1
- package/dist/src/cohort-topic/topic-router.d.ts +9 -0
- package/dist/src/cohort-topic/topic-router.d.ts.map +1 -1
- package/dist/src/cohort-topic/topic-router.js +12 -2
- package/dist/src/cohort-topic/topic-router.js.map +1 -1
- package/dist/src/dispute/client.d.ts.map +1 -1
- package/dist/src/dispute/client.js +15 -3
- package/dist/src/dispute/client.js.map +1 -1
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/libp2p-key-network.d.ts +78 -17
- package/dist/src/libp2p-key-network.d.ts.map +1 -1
- package/dist/src/libp2p-key-network.js +234 -147
- package/dist/src/libp2p-key-network.js.map +1 -1
- package/dist/src/libp2p-node-base.d.ts +35 -1
- package/dist/src/libp2p-node-base.d.ts.map +1 -1
- package/dist/src/libp2p-node-base.js +151 -26
- package/dist/src/libp2p-node-base.js.map +1 -1
- package/dist/src/libp2p-node-rn.d.ts +2 -2
- package/dist/src/libp2p-node-rn.d.ts.map +1 -1
- package/dist/src/libp2p-node-rn.js.map +1 -1
- package/dist/src/libp2p-node.d.ts +2 -2
- package/dist/src/libp2p-node.d.ts.map +1 -1
- package/dist/src/libp2p-node.js.map +1 -1
- package/dist/src/logger.d.ts.map +1 -1
- package/dist/src/logger.js +6 -1
- package/dist/src/logger.js.map +1 -1
- package/dist/src/matchmaking/query-transport.d.ts +3 -4
- package/dist/src/matchmaking/query-transport.d.ts.map +1 -1
- package/dist/src/matchmaking/query-transport.js +9 -9
- package/dist/src/matchmaking/query-transport.js.map +1 -1
- package/dist/src/network/network-manager-service.d.ts +10 -5
- package/dist/src/network/network-manager-service.d.ts.map +1 -1
- package/dist/src/network/network-manager-service.js +11 -2
- package/dist/src/network/network-manager-service.js.map +1 -1
- package/dist/src/network/relay-reservation.d.ts +170 -0
- package/dist/src/network/relay-reservation.d.ts.map +1 -0
- package/dist/src/network/relay-reservation.js +527 -0
- package/dist/src/network/relay-reservation.js.map +1 -0
- package/dist/src/pend-validation.d.ts +3 -2
- package/dist/src/pend-validation.d.ts.map +1 -1
- package/dist/src/pend-validation.js +3 -2
- package/dist/src/pend-validation.js.map +1 -1
- package/dist/src/protocol-client.d.ts +8 -1
- package/dist/src/protocol-client.d.ts.map +1 -1
- package/dist/src/protocol-client.js +11 -0
- package/dist/src/protocol-client.js.map +1 -1
- package/dist/src/reactivity/forwarder-host.d.ts +2 -1
- package/dist/src/reactivity/forwarder-host.d.ts.map +1 -1
- package/dist/src/reactivity/forwarder-host.js +2 -1
- package/dist/src/reactivity/forwarder-host.js.map +1 -1
- package/dist/src/reactivity/origination-manager.d.ts +3 -3
- package/dist/src/reactivity/origination-manager.js +3 -3
- package/dist/src/reactivity/recover-transport.d.ts +22 -14
- package/dist/src/reactivity/recover-transport.d.ts.map +1 -1
- package/dist/src/reactivity/recover-transport.js +32 -19
- package/dist/src/reactivity/recover-transport.js.map +1 -1
- package/dist/src/reactivity/subscription-manager.d.ts +2 -2
- package/dist/src/reactivity/topic-bytes.d.ts +6 -7
- package/dist/src/reactivity/topic-bytes.d.ts.map +1 -1
- package/dist/src/reactivity/topic-bytes.js +8 -9
- package/dist/src/reactivity/topic-bytes.js.map +1 -1
- package/dist/src/repo/client.d.ts +5 -2
- package/dist/src/repo/client.d.ts.map +1 -1
- package/dist/src/repo/client.js +49 -40
- package/dist/src/repo/client.js.map +1 -1
- package/dist/src/repo/cluster-coordinator.d.ts +77 -5
- package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
- package/dist/src/repo/cluster-coordinator.js +131 -20
- package/dist/src/repo/cluster-coordinator.js.map +1 -1
- package/dist/src/repo/coordinator-repo.d.ts +238 -122
- package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
- package/dist/src/repo/coordinator-repo.js +625 -472
- package/dist/src/repo/coordinator-repo.js.map +1 -1
- package/dist/src/repo/i-under-replication-ledger.d.ts +87 -0
- package/dist/src/repo/i-under-replication-ledger.d.ts.map +1 -0
- package/dist/src/repo/i-under-replication-ledger.js +2 -0
- package/dist/src/repo/i-under-replication-ledger.js.map +1 -0
- package/dist/src/repo/kv-under-replication-ledger.d.ts +91 -0
- package/dist/src/repo/kv-under-replication-ledger.d.ts.map +1 -0
- package/dist/src/repo/kv-under-replication-ledger.js +287 -0
- package/dist/src/repo/kv-under-replication-ledger.js.map +1 -0
- package/dist/src/repo/responsibility.d.ts +37 -0
- package/dist/src/repo/responsibility.d.ts.map +1 -0
- package/dist/src/repo/responsibility.js +37 -0
- package/dist/src/repo/responsibility.js.map +1 -0
- package/dist/src/repo/service.d.ts +44 -15
- package/dist/src/repo/service.d.ts.map +1 -1
- package/dist/src/repo/service.js +64 -27
- package/dist/src/repo/service.js.map +1 -1
- package/dist/src/repo/stuck-reservation.d.ts +127 -0
- package/dist/src/repo/stuck-reservation.d.ts.map +1 -0
- package/dist/src/repo/stuck-reservation.js +179 -0
- package/dist/src/repo/stuck-reservation.js.map +1 -0
- package/dist/src/repo/under-replication-drain.d.ts +208 -0
- package/dist/src/repo/under-replication-drain.d.ts.map +1 -0
- package/dist/src/repo/under-replication-drain.js +461 -0
- package/dist/src/repo/under-replication-drain.js.map +1 -0
- package/dist/src/rn.d.ts +5 -0
- package/dist/src/rn.d.ts.map +1 -1
- package/dist/src/rn.js +5 -0
- package/dist/src/rn.js.map +1 -1
- package/dist/src/storage/block-latch.d.ts +3 -2
- package/dist/src/storage/block-latch.d.ts.map +1 -1
- package/dist/src/storage/block-latch.js +7 -4
- package/dist/src/storage/block-latch.js.map +1 -1
- package/dist/src/storage/block-storage.d.ts +45 -3
- package/dist/src/storage/block-storage.d.ts.map +1 -1
- package/dist/src/storage/block-storage.js +156 -9
- package/dist/src/storage/block-storage.js.map +1 -1
- package/dist/src/storage/i-block-storage.d.ts +57 -5
- package/dist/src/storage/i-block-storage.d.ts.map +1 -1
- package/dist/src/storage/i-block-storage.js.map +1 -1
- package/dist/src/storage/pending-claim.d.ts +167 -0
- package/dist/src/storage/pending-claim.d.ts.map +1 -0
- package/dist/src/storage/pending-claim.js +156 -0
- package/dist/src/storage/pending-claim.js.map +1 -0
- package/dist/src/storage/raw-store-codec.d.ts +13 -0
- package/dist/src/storage/raw-store-codec.d.ts.map +1 -1
- package/dist/src/storage/raw-store-codec.js +24 -3
- package/dist/src/storage/raw-store-codec.js.map +1 -1
- package/dist/src/storage/restoration-coordinator.d.ts.map +1 -1
- package/dist/src/storage/restoration-coordinator.js +2 -1
- package/dist/src/storage/restoration-coordinator.js.map +1 -1
- package/dist/src/storage/ring-shift-coordinator.d.ts.map +1 -1
- package/dist/src/storage/ring-shift-coordinator.js +3 -3
- package/dist/src/storage/ring-shift-coordinator.js.map +1 -1
- package/dist/src/storage/storage-repo.d.ts +122 -5
- package/dist/src/storage/storage-repo.d.ts.map +1 -1
- package/dist/src/storage/storage-repo.js +245 -68
- package/dist/src/storage/storage-repo.js.map +1 -1
- package/dist/src/storage/struct.d.ts +58 -0
- package/dist/src/storage/struct.d.ts.map +1 -1
- package/dist/src/testing/mesh-harness.d.ts +77 -11
- package/dist/src/testing/mesh-harness.d.ts.map +1 -1
- package/dist/src/testing/mesh-harness.js +226 -100
- package/dist/src/testing/mesh-harness.js.map +1 -1
- package/package.json +2 -2
- package/readme.md +27 -3
- package/src/cluster/block-transfer-service.ts +132 -4
- package/src/cluster/block-transfer.ts +79 -84
- package/src/cluster/client.ts +115 -119
- package/src/cluster/cluster-policy.ts +2 -1
- package/src/cluster/cluster-repo.ts +422 -56
- package/src/cluster/commit-proof.ts +2 -2
- package/src/cluster/race-resolution.ts +76 -7
- package/src/cluster/rebalance-monitor.ts +677 -539
- package/src/cluster/spread-on-churn.ts +34 -54
- package/src/cohort-topic/host.ts +8 -6
- package/src/cohort-topic/membership-source.ts +1 -1
- package/src/cohort-topic/peer-codec.ts +34 -31
- package/src/cohort-topic/stream-util.ts +39 -4
- package/src/cohort-topic/topic-router.ts +12 -2
- package/src/dispute/client.ts +17 -7
- package/src/index.ts +64 -59
- package/src/libp2p-key-network.ts +1377 -1260
- package/src/libp2p-node-base.ts +186 -27
- package/src/libp2p-node-rn.ts +31 -30
- package/src/libp2p-node.ts +37 -36
- package/src/logger.ts +6 -1
- package/src/matchmaking/query-transport.ts +9 -9
- package/src/network/network-manager-service.ts +16 -5
- package/src/network/relay-reservation.ts +636 -0
- package/src/pend-validation.ts +3 -2
- package/src/protocol-client.ts +13 -1
- package/src/reactivity/forwarder-host.ts +2 -1
- package/src/reactivity/origination-manager.ts +3 -3
- package/src/reactivity/recover-transport.ts +39 -22
- package/src/reactivity/subscription-manager.ts +2 -2
- package/src/reactivity/topic-bytes.ts +35 -37
- package/src/repo/client.ts +172 -173
- package/src/repo/cluster-coordinator.ts +145 -19
- package/src/repo/coordinator-repo.ts +652 -505
- package/src/repo/i-under-replication-ledger.ts +89 -0
- package/src/repo/kv-under-replication-ledger.ts +302 -0
- package/src/repo/responsibility.ts +48 -0
- package/src/repo/service.ts +76 -39
- package/src/repo/stuck-reservation.ts +224 -0
- package/src/repo/under-replication-drain.ts +582 -0
- package/src/rn.ts +74 -69
- package/src/storage/block-latch.ts +7 -4
- package/src/storage/block-storage.ts +161 -10
- package/src/storage/i-block-storage.ts +60 -5
- package/src/storage/pending-claim.ts +200 -0
- package/src/storage/raw-store-codec.ts +26 -3
- package/src/storage/restoration-coordinator.ts +212 -211
- package/src/storage/ring-shift-coordinator.ts +271 -271
- package/src/storage/storage-repo.ts +280 -72
- package/src/storage/struct.ts +58 -0
- package/src/testing/mesh-harness.ts +293 -112
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { PendRequest, ActionBlocks, IRepo, MessageOptions, CommitResult, GetBlockResults, PendResult, StaleFailure, BlockGets, CommitRequest, RepoMessage, IKeyNetwork, ICluster, ClusterConsensusConfig, BlockId, ActionContext, ClusterRecord } from "@optimystic/db-core";
|
|
2
|
+
import { type CohortResolution } from "./cluster-coordinator.js";
|
|
2
3
|
import type { PeerId } from "@libp2p/interface";
|
|
3
4
|
import type { FretService } from "p2p-fret";
|
|
4
5
|
import type { IPeerReputation } from "../reputation/types.js";
|
|
5
6
|
import type { ITransactionStateStore } from "../cluster/i-transaction-state-store.js";
|
|
6
7
|
import { type ProofAnchoring } from "../cluster/certified-claims.js";
|
|
7
8
|
import { type BlockCommitProof } from "../cluster/commit-proof.js";
|
|
8
|
-
import type { ReconcileBlockCallback } from "../cluster/cluster-repo.js";
|
|
9
|
+
import type { ReconcileBlockCallback, CommittedHoldersSink } from "../cluster/cluster-repo.js";
|
|
9
10
|
import type { CertifiedActionRev } from "../storage/block-archive.js";
|
|
11
|
+
import type { IUnderReplicationLedger } from "./i-under-replication-ledger.js";
|
|
10
12
|
/**
|
|
11
13
|
* Acquire a block's content for a cohort-corroborated revision, from the cohort, and persist it.
|
|
12
14
|
*
|
|
@@ -79,6 +81,17 @@ interface CoordinatorRepoComponents {
|
|
|
79
81
|
* acceptance internally regardless.
|
|
80
82
|
*/
|
|
81
83
|
proofAnchoring?: ProofAnchoring;
|
|
84
|
+
/**
|
|
85
|
+
* Optional durable record of commits acknowledged below full replication, and who is still
|
|
86
|
+
* missing each block — see {@link CoordinatorRepo.noteReplicationShortfall}. Absent → nothing is
|
|
87
|
+
* recorded and commit behaves exactly as without it.
|
|
88
|
+
*/
|
|
89
|
+
underReplicationLedger?: IUnderReplicationLedger;
|
|
90
|
+
/**
|
|
91
|
+
* Optional: told who holds each cohort commit this node acknowledges and holds — see
|
|
92
|
+
* {@link CoordinatorRepo.reportCommittedHolders}. Absent → commit behaves exactly as without it.
|
|
93
|
+
*/
|
|
94
|
+
onCommittedHolders?: CommittedHoldersSink;
|
|
82
95
|
}
|
|
83
96
|
/**
|
|
84
97
|
* Consensus config for the coordinator side, plus the repair yardstick the read-repair path measures
|
|
@@ -108,8 +121,11 @@ export declare function coordinatorRepo(keyNetwork: IKeyNetwork, createClusterCl
|
|
|
108
121
|
* revert to being ignored. If that field is ever renamed, grep the specs for `coordinator:`.
|
|
109
122
|
*/
|
|
110
123
|
export interface ICoordinatorClusterSeam {
|
|
124
|
+
/** Used by `cancel` alone; `pend` and `commit` read {@link resolveCohort}. */
|
|
111
125
|
getClusterSize(blockId: BlockId): Promise<number>;
|
|
112
|
-
|
|
126
|
+
/** Whether the cohort could be established at all, and who it is — the primitive
|
|
127
|
+
* `getClusterSize` derives from. `pend` and `commit` classify their solo short-circuit on it. */
|
|
128
|
+
resolveCohort(blockId: BlockId): Promise<CohortResolution>;
|
|
113
129
|
executeClusterTransaction(blockId: BlockId, message: RepoMessage, options?: MessageOptions): Promise<{
|
|
114
130
|
record: ClusterRecord;
|
|
115
131
|
localExecuted: boolean;
|
|
@@ -135,37 +151,13 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
135
151
|
private readonly clusterLatestCallback?;
|
|
136
152
|
private readonly acquireBlockFromCohort?;
|
|
137
153
|
private readonly proofAnchoring?;
|
|
154
|
+
private readonly underReplicationLedger?;
|
|
155
|
+
private readonly onCommittedHolders?;
|
|
138
156
|
private coordinator;
|
|
139
157
|
private readonly DEFAULT_TIMEOUT;
|
|
140
158
|
private readonly localPeerId?;
|
|
141
159
|
private readonly responsibilityCache;
|
|
142
|
-
private static readonly RESPONSIBILITY_TTL_MS;
|
|
143
160
|
private readonly lastSeenCommitMs;
|
|
144
|
-
/**
|
|
145
|
-
* Per block, when (`this.now()` at the consult's start) a consult last SETTLED that this node's
|
|
146
|
-
* absence of it is the cohort's answer too — see `absenceSettled` on {@link fetchBlockFromCluster}'s
|
|
147
|
-
* result. Only the solo-self exit settles today: when this node is the block's whole cohort, every
|
|
148
|
-
* acknowledged commit of it lands in this node's storage before the writer hears success, so the
|
|
149
|
-
* block reads present and the memo dies. Read only for a block still missing locally
|
|
150
|
-
* ({@link absenceIsSettled}); cleared by any pend or commit this node coordinates for the block, by
|
|
151
|
-
* seeing it present, and by any later consult of it that does not settle.
|
|
152
|
-
*
|
|
153
|
-
* Deliberately its OWN map rather than `lastSeenCommitMs`: that one is also stamped for missing
|
|
154
|
-
* blocks at exits whose verdict is NOT a confirmed absence (the `cohort-too-small` arm when a peer
|
|
155
|
-
* claimed a revision, the post-restore arm when acquisition failed), so reading it here would turn
|
|
156
|
-
* a `claimed-elsewhere` absence into an authoritative one for a whole window.
|
|
157
|
-
*
|
|
158
|
-
* NOTE: accepted tradeoff — a cohort-of-one view can be transient (peers still mid-identify; see
|
|
159
|
-
* the solo exit), and a block another node creates through the cohort it sees is then reported
|
|
160
|
-
* absent here for up to one `readRepairWindowMs` after this node's view grows — the same one-window
|
|
161
|
-
* cost the held-block window pays for a growing cohort. Revisit if a caller ever needs
|
|
162
|
-
* create-visibility across coordinators tighter than one window — such a caller needs a revision
|
|
163
|
-
* floor (backlog `feat-refresh-can-demand-a-revision-floor`), not a shorter window.
|
|
164
|
-
*
|
|
165
|
-
* NOTE: LRU-bounded like its siblings; an eviction under >1000 settled blocks loses a memo and
|
|
166
|
-
* costs one extra consult — the safe direction.
|
|
167
|
-
*/
|
|
168
|
-
private readonly settledAbsences;
|
|
169
161
|
/** Per block, what earlier repair passes left unresolved — see {@link AheadClaimState}.
|
|
170
162
|
* Outlives the consult on purpose: the read-repair window skips consults for blocks checked
|
|
171
163
|
* recently, and a doubt dropped there is a stale answer served as confirmed again.
|
|
@@ -174,14 +166,14 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
174
166
|
* {@link reportRepairDeadlock} say its piece a second time. */
|
|
175
167
|
private readonly unsettledAheadClaims;
|
|
176
168
|
/**
|
|
177
|
-
* Per block, what its pending-conflict refusals have added up to — see {@link
|
|
178
|
-
* and {@link noteStuckReservation}. Deliberately its OWN
|
|
179
|
-
* {@link unsettledAheadClaims}: that entry belongs to the read-repair path and is cleared by a
|
|
180
|
-
* converging on a revision, whereas this one belongs to the write path and is cleared by the
|
|
181
|
-
* accepting a write. Sharing the entry would mean teaching both of those lifetimes about a
|
|
182
|
-
* neither owns (backlog `debt-freshness-state-scattered-across-coordinator-repo` is the
|
|
183
|
-
* argument for collapsing all of this per-block state behind one collaborator; adding a
|
|
184
|
-
* carve-out to the freshness entry would have made that harder, not easier).
|
|
169
|
+
* Per block, what its pending-conflict refusals have added up to — see {@link StuckReservationTracker}
|
|
170
|
+
* and {@link noteStuckReservation}. Deliberately its OWN collaborator rather than a third fact hung
|
|
171
|
+
* off {@link unsettledAheadClaims}: that entry belongs to the read-repair path and is cleared by a
|
|
172
|
+
* block converging on a revision, whereas this one belongs to the write path and is cleared by the
|
|
173
|
+
* block accepting a write. Sharing the entry would mean teaching both of those lifetimes about a
|
|
174
|
+
* fact neither owns (backlog `debt-freshness-state-scattered-across-coordinator-repo` is the
|
|
175
|
+
* standing argument for collapsing all of this per-block state behind one collaborator; adding a
|
|
176
|
+
* fourth carve-out to the freshness entry would have made that harder, not easier).
|
|
185
177
|
*
|
|
186
178
|
* NOTE: LRU-bounded like its siblings. An eviction under >1000 conflicted blocks loses an episode's
|
|
187
179
|
* say-once flag, so the line can repeat once for that block — the same bounded duplication
|
|
@@ -190,10 +182,9 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
190
182
|
* NOTE: per COORDINATOR, and a block's coordinator is whichever peer the writer's key lookup
|
|
191
183
|
* resolved — normally stable, but cohort churn or a routing change moves it. When it moves, the
|
|
192
184
|
* count restarts on the new coordinator (the condition is named later) and the old one may name the
|
|
193
|
-
* same episode again (the condition is named twice).
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
* storage) rather than to where the refusal was classified.
|
|
185
|
+
* same episode again (the condition is named twice). Each MEMBER now keeps its own tracker as well
|
|
186
|
+
* (`ClusterMember.validatePendOperations`), fed by its own `held` votes, so the episode is also
|
|
187
|
+
* named where the record lives, by a count that does not move with the coordinator.
|
|
197
188
|
*/
|
|
198
189
|
private readonly stuckReservations;
|
|
199
190
|
private readonly readRepairMode;
|
|
@@ -217,7 +208,7 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
217
208
|
now: () => number;
|
|
218
209
|
/** Test seam: overridable RNG (0..1) for sample-rate gating. */
|
|
219
210
|
rand: () => number;
|
|
220
|
-
constructor(keyNetwork: IKeyNetwork, createClusterClient: (peerId: PeerId) => ICluster, storageRepo: IRepo, cfg?: CoordinatorRepoConfig, localCluster?: LocalClusterWithExecutionTracking | undefined, localPeerId?: PeerId, fretService?: FretService, clusterLatestCallback?: ClusterLatestCallback | undefined, reputation?: IPeerReputation, stateStore?: ITransactionStateStore, acquireBlockFromCohort?: AcquireBlockCallback | undefined, proofAnchoring?: ProofAnchoring | undefined);
|
|
211
|
+
constructor(keyNetwork: IKeyNetwork, createClusterClient: (peerId: PeerId) => ICluster, storageRepo: IRepo, cfg?: CoordinatorRepoConfig, localCluster?: LocalClusterWithExecutionTracking | undefined, localPeerId?: PeerId, fretService?: FretService, clusterLatestCallback?: ClusterLatestCallback | undefined, reputation?: IPeerReputation, stateStore?: ITransactionStateStore, acquireBlockFromCohort?: AcquireBlockCallback | undefined, proofAnchoring?: ProofAnchoring | undefined, underReplicationLedger?: IUnderReplicationLedger | undefined, onCommittedHolders?: CommittedHoldersSink | undefined);
|
|
221
212
|
/**
|
|
222
213
|
* The resolved super-majority threshold this coordinator commits on. Exposed so the composition root
|
|
223
214
|
* can fail-fast if the coordinator and the cluster member would run different thresholds (see the
|
|
@@ -227,15 +218,38 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
227
218
|
/** Recover coordinator transactions from persistent store after a restart. */
|
|
228
219
|
recoverTransactions(): Promise<void>;
|
|
229
220
|
/**
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
221
|
+
* Whether this node is in the cohort for a block. Uses `findCluster` membership — in the real network
|
|
222
|
+
* layer, self is in the cohort exactly when this node is among the nearest `clusterSize` serving peers
|
|
223
|
+
* for the block, so a request that reaches a node outside it was sent to the wrong machine.
|
|
224
|
+
*
|
|
225
|
+
* Three answers, because a lookup that THREW is not an answer: `undetermined` is never cached (routing
|
|
226
|
+
* can recover on the next request) and never read as `responsible` — what each caller does with it is
|
|
227
|
+
* that caller's posture (see {@link verifyResponsibility} and `get`).
|
|
228
|
+
*
|
|
229
|
+
* With no `localPeerId` the check is skipped and the answer is `responsible`. That bypass exists for
|
|
230
|
+
* wiring without an identity (direct constructors, single-node and test setups), never for production,
|
|
231
|
+
* where `libp2p-node-base` always passes the node's peer id.
|
|
232
|
+
*
|
|
233
|
+
* NOTE: a cached answer stands for up to {@link RESPONSIBILITY_TTL_MS} after the cohort changes, so a
|
|
234
|
+
* node can still say `responsible` for a minute after it stops being so. {@link soloCohortDurability}'s
|
|
235
|
+
* `unrouted` class and `ClusterCoordinator.executeClusterTransaction`'s cohort-membership guard are what
|
|
236
|
+
* keep that window honest; if churn ever makes the window matter, shorten the TTL rather than
|
|
237
|
+
* re-looking-up on every write.
|
|
235
238
|
*/
|
|
236
|
-
private
|
|
239
|
+
private responsibilityFor;
|
|
237
240
|
/**
|
|
238
|
-
*
|
|
241
|
+
* The write path's gate (`pend`, `cancel`, `commit`): refuse unless this node is responsible for EVERY
|
|
242
|
+
* block, and refuse too when it cannot tell — fail CLOSED. A write accepted on a thrown lookup commits
|
|
243
|
+
* where the network was never consulted (GitHub #19); refusing hands it back to the writer's transactor,
|
|
244
|
+
* which excludes this peer and re-picks inside the cohort.
|
|
245
|
+
*
|
|
246
|
+
* Every block is checked so the error names all of them. When the blocks split between the two kinds,
|
|
247
|
+
* `not-responsible` is the one thrown: it is a settled answer that the request is misrouted, which no
|
|
248
|
+
* recovery of the lookup would change; the undetermined blocks are still logged.
|
|
249
|
+
*
|
|
250
|
+
* For `cancel`, a refusal on a transient lookup fault leaves the pending record standing on this node
|
|
251
|
+
* until the writer's cancel retry lands on another cohort member — and this node is still discharged
|
|
252
|
+
* then, since as a member it judges the cancel against the record's own `peers`, not against a lookup.
|
|
239
253
|
*/
|
|
240
254
|
private verifyResponsibility;
|
|
241
255
|
get(blockGets: BlockGets, options?: MessageOptions): Promise<GetBlockResults>;
|
|
@@ -327,29 +341,30 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
327
341
|
private flagUnconfirmedCurrency;
|
|
328
342
|
/** Decide whether the read-repair policy wants us to consult the cluster for a present-but-possibly-stale block. */
|
|
329
343
|
private shouldReadRepair;
|
|
330
|
-
/**
|
|
331
|
-
* Decide whether a block MISSING locally may skip its consult: an earlier consult settled its
|
|
332
|
-
* absence within one read-repair window (see {@link settledAbsences}). The absence counterpart of
|
|
333
|
-
* {@link shouldReadRepair}, giving absence the guarantee the window already gives content —
|
|
334
|
-
* "checked with the cohort within one window" — and nothing weaker.
|
|
335
|
-
*
|
|
336
|
-
* Modes: `paranoid` never skips ("verify every read" means every read). `lazy` uses the window and
|
|
337
|
-
* the sample rate, exactly as {@link shouldReadRepair} does. `off` uses the window but not the
|
|
338
|
-
* sample rate (a `lazy`-only knob, as it is for content): `off` disables STALE-CONTENT repair, and
|
|
339
|
-
* the absence consult is not that — it is what makes an absent answer authoritative at all — so
|
|
340
|
-
* leaving it unbounded would make the mode meant to do less network work do more.
|
|
341
|
-
*/
|
|
342
|
-
private absenceIsSettled;
|
|
343
344
|
/** Milliseconds since we last marked this block fresh, or undefined if never. */
|
|
344
345
|
private ageMs;
|
|
346
|
+
/**
|
|
347
|
+
* Whether the solo-self exit of {@link fetchBlockFromCluster} has already named `blockId` inside
|
|
348
|
+
* the current read-repair window, for a block this node does NOT hold (`localRev` undefined). Such
|
|
349
|
+
* a block reaches that exit on every read, because `get` never remembers an absence (GitHub
|
|
350
|
+
* issue #20). So its `cluster-fetch:solo-self-skip` line and its stamp are both skipped while the
|
|
351
|
+
* stamp is at most one `readRepairWindowMs` old. An unconditional line would bring back issue #8's
|
|
352
|
+
* log volume for a probed but never-written collection. Re-stamping on every read would keep the
|
|
353
|
+
* stamp fresh and silence the line for good on a block read more often than once a window.
|
|
354
|
+
*
|
|
355
|
+
* Withholding the stamp never skips a consult: `get` asks {@link shouldReadRepair} only about
|
|
356
|
+
* present blocks. A HELD block reaches the exit only when read-repair already chose to consult, so
|
|
357
|
+
* this is always false for one. Its line and stamp are unchanged, and the line keeps pairing with
|
|
358
|
+
* `cluster-tx:read-repair-triggered`.
|
|
359
|
+
*
|
|
360
|
+
* NOTE: the stamp is shared with every exit that marks a block seen, so a missing block one of
|
|
361
|
+
* them stamped inside the window is not named until that stamp lapses. Fine for a diagnostic
|
|
362
|
+
* line; if anything ever needs "first answer from a self-only view" exactly, give the line its own
|
|
363
|
+
* per-block stamp.
|
|
364
|
+
*/
|
|
365
|
+
private soloAbsenceNamedThisWindow;
|
|
345
366
|
/** Mark blocks as freshly observed from cluster authority (post-commit or post-fetch). */
|
|
346
367
|
private markBlocksSeen;
|
|
347
|
-
/**
|
|
348
|
-
* Drop any settled-absence memo for `blockIds` ({@link settledAbsences}) — called at the top of a
|
|
349
|
-
* local pend or commit, before routing and whatever the outcome. Clearing is always the safe
|
|
350
|
-
* direction: the most it can cost is one extra consult.
|
|
351
|
-
*/
|
|
352
|
-
private forgetSettledAbsences;
|
|
353
368
|
/**
|
|
354
369
|
* True when a commit's approve votes form a strict majority of the FULL cohort — the only case
|
|
355
370
|
* where "this node committed" is evidence that no rival commit moved past it. Two strict
|
|
@@ -404,15 +419,9 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
404
419
|
* retire it when the memo's claimants are among the peers that answered), `no-evidence`
|
|
405
420
|
* leaves it standing untouched. Required, not optional, so an exit added later has to say
|
|
406
421
|
* which it means.
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
* settled absence ({@link settledAbsences}) and skips the consult while the block stays missing.
|
|
411
|
-
* `absence === 'confirmed'` alone is not enough — the empty-cohort exit reports it without
|
|
412
|
-
* asking anyone, and a multi-peer cohort's unanimous "nothing" can be overtaken by a commit
|
|
413
|
-
* still on its way to this node. Required, like
|
|
414
|
-
* `currency`, so an exit added later has to say which side it falls on rather than
|
|
415
|
-
* remembering (or forgetting) to arm something.
|
|
422
|
+
*
|
|
423
|
+
* Nothing is remembered about an absence: `get` runs this pass on every read of a block missing
|
|
424
|
+
* locally (see the accepted-tradeoff NOTE there).
|
|
416
425
|
*/
|
|
417
426
|
private fetchBlockFromCluster;
|
|
418
427
|
/**
|
|
@@ -600,8 +609,34 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
600
609
|
private penalizeProofService;
|
|
601
610
|
pend(request: PendRequest, options?: MessageOptions): Promise<PendResult>;
|
|
602
611
|
/** The cluster half of {@link pend}, after responsibility is verified: consensus, the local-verdict
|
|
603
|
-
* arms, and the
|
|
612
|
+
* arms, and the catch that turns each optimistic-concurrency refusal into a retryable answer —
|
|
613
|
+
* the two signed-evidence ones ({@link ConflictRaceLostError}, {@link BlocksHeldError}) directly,
|
|
614
|
+
* and a validator rejection only through {@link classifyStaleRejection}. */
|
|
604
615
|
private pendThroughCluster;
|
|
616
|
+
/**
|
|
617
|
+
* The solo short-circuit of {@link pend}: a cohort of at most one peer runs no consensus, and the
|
|
618
|
+
* pend goes straight to local storage exactly as before. What changes is the answer's class —
|
|
619
|
+
* see {@link soloCohortDurability} for the four-way split. A refusal is returned untouched.
|
|
620
|
+
*/
|
|
621
|
+
private pendSolo;
|
|
622
|
+
/**
|
|
623
|
+
* The class of a write that took the solo short-circuit, from the cohort resolution that put it
|
|
624
|
+
* there. Policy-free: the write already happened, this only says what it was.
|
|
625
|
+
* - not resolved (the lookup threw, or named nobody) → `unrouted`;
|
|
626
|
+
* - resolved to exactly this node → `local`, a correct and complete one-machine write;
|
|
627
|
+
* - resolved to exactly one peer that is NOT this node → `unrouted` — this node wrote somewhere
|
|
628
|
+
* the cohort does not look, which is a write whose destination is wrong, not a solo write.
|
|
629
|
+
* With no local peer id (direct constructors, single-node and test wiring) a resolved cohort of
|
|
630
|
+
* one reads as `local`: the same posture `responsibilityFor` takes for a node with no
|
|
631
|
+
* identity, and a node with no identity cannot be in any cohort but its own.
|
|
632
|
+
*
|
|
633
|
+
* Both `unrouted` arms are defence in depth now, not the main guard: {@link verifyResponsibility}
|
|
634
|
+
* refuses a write whose lookup throws and a write for a cohort that excludes this node before the
|
|
635
|
+
* short-circuit is reached. A write lands here unrouted only inside the responsibility cache's
|
|
636
|
+
* staleness window, or when a second lookup fails moments after the first succeeded — and then it
|
|
637
|
+
* still reports honestly rather than posing as `local`.
|
|
638
|
+
*/
|
|
639
|
+
private soloCohortDurability;
|
|
605
640
|
/**
|
|
606
641
|
* Decide whether a cluster validator rejection was an optimistic-concurrency loss — the block
|
|
607
642
|
* already advanced past the requested revision — rather than a genuine validation fault.
|
|
@@ -623,62 +658,69 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
623
658
|
*/
|
|
624
659
|
private classifyStaleRejection;
|
|
625
660
|
/**
|
|
626
|
-
*
|
|
627
|
-
*
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
661
|
+
* Answer a pend the cohort refused with signed `held` votes: the blocks are reserved by a different
|
|
662
|
+
* unresolved action on one or more members ({@link BlocksHeldError}). Always a retryable
|
|
663
|
+
* {@link StaleFailure} with `conflict: true`, so the caller's normal retry path
|
|
664
|
+
* (`Collection.sync`, and the multi-collection pendPhase via `isConflictFailure`) absorbs it
|
|
665
|
+
* instead of a thrown error escaping mid-batch and splitting multi-tree pends.
|
|
666
|
+
*
|
|
667
|
+
* The local re-read is an ENRICHER, not a gate. It used to be the gate — this refusal arrived as a
|
|
668
|
+
* `ValidatorRejectionError` and was only converted when the coordinator's own storage corroborated
|
|
669
|
+
* the rival — and under latency the refusing member is routinely ahead of the coordinator, so the
|
|
670
|
+
* corroboration missed and a transient refusal escaped as a permanent-looking throw. The `held`
|
|
671
|
+
* vote is already signed evidence from the member that holds the rival, so retryability no longer
|
|
672
|
+
* depends on a local re-read at all. What the re-read still buys, when it succeeds, is the concrete
|
|
673
|
+
* rival list for {@link StaleFailure.pending} and the input {@link noteStuckReservation} needs to
|
|
674
|
+
* name a block wedged behind a reservation that will never clear.
|
|
631
675
|
*
|
|
632
|
-
*
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
*
|
|
638
|
-
* validation faults. Checked after `classifyStaleRejection` so a confirmed committed loss
|
|
639
|
-
* (which carries the sharper `staleAt`) wins when both hold.
|
|
676
|
+
* NOTE: `error.heldBy` (peerId → holding action id) is dropped at this boundary, the same deliberate
|
|
677
|
+
* drop the {@link ConflictRaceLostError} arm of {@link pendThroughCluster} documents: `StaleFailure`
|
|
678
|
+
* has no field for it, and the members' action ids are not the same claim as the rivals this node
|
|
679
|
+
* read out of its own storage, so they must not be folded into `pending`. A caller that wants to
|
|
680
|
+
* WAIT on the holder rather than re-race it needs a typed field added here; never recover the ids
|
|
681
|
+
* by parsing `reason`.
|
|
640
682
|
*/
|
|
641
|
-
private
|
|
683
|
+
private answerBlocksHeld;
|
|
684
|
+
/**
|
|
685
|
+
* The rival unresolved actions THIS node's own storage says hold `blockIds`, excluding the request's
|
|
686
|
+
* own action (a redelivered pend must not corroborate against itself). Empty when nothing is found
|
|
687
|
+
* — including when the read itself fails, which is reported and then treated as "nothing to add",
|
|
688
|
+
* since the caller's answer does not depend on it.
|
|
689
|
+
*
|
|
690
|
+
* Carries no `transform`, which {@link ActionPending} allows and no consumer rebases from.
|
|
691
|
+
*
|
|
692
|
+
* Diagnostic enrichment only, never a gate: the refusal it corroborates was already cast and signed
|
|
693
|
+
* by a member, and nothing here can turn an admission into a refusal or the reverse.
|
|
694
|
+
*/
|
|
695
|
+
private corroborateHeldBlocks;
|
|
696
|
+
/**
|
|
697
|
+
* This node's pending records on `blockId`, each with the slot it claims when storage can say
|
|
698
|
+
* (`IPendingClaimReader`, which `StorageRepo` implements). A repo without the capability answers
|
|
699
|
+
* with `state.pendings` alone, every record read as an unknown claim — which reserves, so the
|
|
700
|
+
* corroboration can only over-name, never under-name.
|
|
701
|
+
*/
|
|
702
|
+
private pendingClaimsOf;
|
|
642
703
|
/**
|
|
643
704
|
* Count one confirmed pending-conflict refusal against the holder(s) of each block it names, and say
|
|
644
705
|
* ONCE — in words, at the moment it becomes provable — when a block is wedged behind a reservation
|
|
645
|
-
* that is not going to clear.
|
|
646
|
-
*
|
|
647
|
-
* **Why this needs saying at all.** Every individual refusal here is indistinguishable from an
|
|
648
|
-
* ordinary lost race, which is a normal and healthy event, so the logs of a permanently wedged block
|
|
649
|
-
* read exactly like the logs of a busy one. Finding the difference today means noticing that the
|
|
650
|
-
* SAME rival action id keeps appearing across unrelated writers for as long as the process lives —
|
|
651
|
-
* a pattern nothing points at, and one that cost a downstream project several tickets and weeks to
|
|
652
|
-
* re-derive from raw traces. The node has the fact in hand at every refusal; this makes it sayable.
|
|
653
|
-
*
|
|
654
|
-
* **The signal, and the two things that are NOT the signal.** The discriminator is repetition
|
|
655
|
-
* against an unchanged holder — see {@link STUCK_RESERVATION_DISTINCT_ACTIONS} for why distinct
|
|
656
|
-
* refused actions is the right counter and for the measured threshold. Two cheaper-looking tests
|
|
657
|
-
* were tried and do not work: the members' in-memory reservation table
|
|
658
|
-
* (`ClusterMember.activeTransactions`) clears the moment a rival's pend reaches consensus, so a
|
|
659
|
-
* perfectly healthy rival inside its pend-to-commit window is absent from it too and absence there
|
|
660
|
-
* says nothing; and "the block already passed this pending record's revision" catches a different
|
|
661
|
-
* orphan class entirely — in the verified instance the wedged block sat at revision 1 while the
|
|
662
|
-
* orphaned record was for revision 2, still nominally promotable.
|
|
663
|
-
*
|
|
664
|
-
* **Never a control path.** This classifies and logs; it never refuses, expires, or deletes
|
|
665
|
-
* anything. Deciding when a durable pending record may be removed is precisely the hard problem
|
|
666
|
-
* backlog `debt-unpromotable-pending-records-need-a-sweep` exists for — deleting a live reservation
|
|
667
|
-
* is worse than the leak — and a counter accurate enough for a log line is not evidence enough to
|
|
668
|
-
* destroy state.
|
|
706
|
+
* that is not going to clear. The counting, the threshold and the wording live in
|
|
707
|
+
* {@link StuckReservationTracker}; this node's part is the corroborated holder list and the tag.
|
|
669
708
|
*
|
|
670
709
|
* Returns the highest distinct-refusal count any of this refusal's blocks has now reached, for the
|
|
671
710
|
* classification line to carry; it saturates at the threshold once an episode has been reported,
|
|
672
711
|
* since the ids are dropped at that point.
|
|
673
712
|
*
|
|
674
|
-
* NOTE: fed only by {@link
|
|
675
|
-
*
|
|
713
|
+
* NOTE: fed only by {@link answerBlocksHeld}, i.e. by cohort-wide `held`-answered refusals that this
|
|
714
|
+
* node's own storage can corroborate. A block only PART of whose cohort holds the stranded record can
|
|
676
715
|
* still reach approval super-majority, and its refusal then comes back through the retained local
|
|
677
|
-
* apply verdict (`getExecutedPendResult`) instead, which this never sees
|
|
678
|
-
*
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
*
|
|
716
|
+
* apply verdict (`getExecutedPendResult`) instead, which this never sees. The un-corroborated arm of
|
|
717
|
+
* {@link answerBlocksHeld} is likewise unfed: this node cannot name the holder, and feeding it a
|
|
718
|
+
* guess would poison the holder comparison, which is what separates a wedge from healthy
|
|
719
|
+
* contention. Neither gap goes unnamed any more: every MEMBER keeps its own tracker, fed by its own
|
|
720
|
+
* `held` votes (`ClusterMember.validatePendOperations`, tag `cluster-member:stuck-reservation`), so
|
|
721
|
+
* a reservation only some members hold — the shape `a-member-that-missed-a-commit-refuses-every-
|
|
722
|
+
* later-write` measured, before the member stopped refusing on a superseded record at all — is
|
|
723
|
+
* named by the members that hold it.
|
|
682
724
|
*/
|
|
683
725
|
private noteStuckReservation;
|
|
684
726
|
/**
|
|
@@ -742,6 +784,80 @@ export declare class CoordinatorRepo implements IRepo {
|
|
|
742
784
|
* freshness stamp belongs.
|
|
743
785
|
*/
|
|
744
786
|
private tolerateLocalCommitDivergence;
|
|
787
|
+
/**
|
|
788
|
+
* The one way a success leaves {@link commit}: record the replication shortfall the answer
|
|
789
|
+
* describes, then return the answer unchanged. Every success exit — solo, local-executed, local
|
|
790
|
+
* fallback, tolerated divergence — runs after the durability gate admitted it, so a refused
|
|
791
|
+
* commit never reaches the ledger.
|
|
792
|
+
*
|
|
793
|
+
* `localHolds` is whether this node's own storage durably holds every block of the commit, which
|
|
794
|
+
* is what makes it a source for the missing copies — not whether the class counted it. `record`
|
|
795
|
+
* is the consensus the commit ran on, absent for the solo short-circuit (no cohort ran, so no
|
|
796
|
+
* holders to report).
|
|
797
|
+
*/
|
|
798
|
+
private acknowledgeCommit;
|
|
799
|
+
/**
|
|
800
|
+
* Tell the {@link CommittedHoldersSink} who holds a cohort commit this node holds, so its rebalance
|
|
801
|
+
* monitor does not push the blocks back to members that stored them. A holder is a member the
|
|
802
|
+
* durability class confirmed AND that signed an approving commit vote: the confirmation rests on
|
|
803
|
+
* the member's unsigned apply report, and requiring the signature too means a member lying in that
|
|
804
|
+
* report can only misstate its own copy — a member already trusted with the commit. The members
|
|
805
|
+
* the class names unconfirmed are reported as such, which withdraws any earlier record of them
|
|
806
|
+
* (including the signer list this node's own member reported at apply), so they are pushed the
|
|
807
|
+
* block. Never throws: the commit is already acknowledged.
|
|
808
|
+
*/
|
|
809
|
+
private reportCommittedHolders;
|
|
810
|
+
/**
|
|
811
|
+
* Write down who is still missing an acknowledged commit, while this node still knows — the
|
|
812
|
+
* cohort's answer is gone the moment the writer is answered, and the in-memory commit retry does
|
|
813
|
+
* not survive a restart. One entry per block, all sharing this commit's one cohort answer
|
|
814
|
+
* (consensus ran on `blockIds[0]`'s cohort for the whole request):
|
|
815
|
+
* - `full` settles any older entry for the block, whether or not this node holds it;
|
|
816
|
+
* - `majority` records the unconfirmed members by name;
|
|
817
|
+
* - `local` and `unrouted` record an EMPTY missing set, meaning "unknown" — nobody could be named.
|
|
818
|
+
* A shortfall is recorded only when `localHolds`: a node holding nothing has nothing to push, and
|
|
819
|
+
* the remote majority that admitted the commit already holds it.
|
|
820
|
+
*
|
|
821
|
+
* NEVER throws, and that asymmetry is deliberate: by the time this runs the commit is already
|
|
822
|
+
* durable at the class the answer states, so a ledger fault must not turn an acknowledged write
|
|
823
|
+
* into a reported failure. A failure is logged per block and the answer still goes out; the
|
|
824
|
+
* block's copy is then owed with nobody tracking it, exactly as before the ledger existed.
|
|
825
|
+
*
|
|
826
|
+
* NOTE: one ledger read and write per block per below-full commit, awaited before the writer is
|
|
827
|
+
* answered — on a node that is genuinely alone that is every commit (a `full` commit settles from
|
|
828
|
+
* the ledger's in-memory index and touches the store only when an entry exists). If it shows in
|
|
829
|
+
* commit latency, coalesce the writes rather than answering first: an entry written after the
|
|
830
|
+
* answer can be lost to a crash in between, which is the one case the ledger exists for.
|
|
831
|
+
*/
|
|
832
|
+
private noteReplicationShortfall;
|
|
833
|
+
private noteBlockShortfall;
|
|
834
|
+
/**
|
|
835
|
+
* The durability class beside the gate: derived from the SAME sets {@link isDurableMajority} was
|
|
836
|
+
* just measured on, with this node's own contribution passed per arm exactly as the gate counted
|
|
837
|
+
* it, so the class and the gate can never disagree. One rule for all three success exits of
|
|
838
|
+
* {@link commit}: `full` iff every cohort member is confirmed, otherwise `majority` (the gate
|
|
839
|
+
* already refused anything below that). Never `local` or `unrouted` here — those belong to the
|
|
840
|
+
* solo short-circuit, where no cohort ran.
|
|
841
|
+
*/
|
|
842
|
+
private cohortWriteDurability;
|
|
843
|
+
/**
|
|
844
|
+
* The solo short-circuit of {@link commit}: consensus never runs, so no ClusterRecord exists to
|
|
845
|
+
* project a proof from — the lone member self-signs a one-peer proof instead (mintSoloCommitProof),
|
|
846
|
+
* which is what lets a block born on a cohort of one ever gain a second holder under the
|
|
847
|
+
* certified-push default (handlePush refuses a proof-less block). Minted even when the cohort did
|
|
848
|
+
* not resolve or the sole peer is not self — a failed `findCluster` puts the DEGRADED-ROUTING case
|
|
849
|
+
* in this same branch, and self genuinely committed these bytes either way; a proof's peer list is
|
|
850
|
+
* already not evidence of cohort membership by design (caller obligation #1 on
|
|
851
|
+
* verifyBlockCommitProofClaim), so gating the mint on cohort composition would buy no safety while
|
|
852
|
+
* opening a silent no-proof hole exactly when routing is degraded.
|
|
853
|
+
*
|
|
854
|
+
* The policy is unchanged — every write accepted here before is accepted now. What changes is
|
|
855
|
+
* that the answer says which situation it was: the `commit:solo-cohort` log line (how an operator
|
|
856
|
+
* tells a real cohort of one — cohortSize 1, soleIsSelf true — from a routing failure) now also
|
|
857
|
+
* carries the `quorum` the writer is told, and both come from {@link soloCohortDurability}, so the
|
|
858
|
+
* log and the answer cannot disagree.
|
|
859
|
+
*/
|
|
860
|
+
private commitSolo;
|
|
745
861
|
/**
|
|
746
862
|
* The durability gate's answer: a retryable refusal ({@link COMMIT_NOT_DURABLE_REASON}) naming how
|
|
747
863
|
* many of the cohort reported holding the revision. `conflict: true` because the members that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordinator-repo.d.ts","sourceRoot":"","sources":["../../../src/repo/coordinator-repo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"coordinator-repo.d.ts","sourceRoot":"","sources":["../../../src/repo/coordinator-repo.ts"],"names":[],"mappings":"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"}
|