@optimystic/db-p2p 1.0.0-beta.3 → 1.1.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.
Files changed (234) hide show
  1. package/dist/src/cluster/block-transfer-service.d.ts +73 -1
  2. package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
  3. package/dist/src/cluster/block-transfer-service.js +70 -3
  4. package/dist/src/cluster/block-transfer-service.js.map +1 -1
  5. package/dist/src/cluster/block-transfer.d.ts +16 -1
  6. package/dist/src/cluster/block-transfer.d.ts.map +1 -1
  7. package/dist/src/cluster/block-transfer.js +73 -72
  8. package/dist/src/cluster/block-transfer.js.map +1 -1
  9. package/dist/src/cluster/client.d.ts +4 -6
  10. package/dist/src/cluster/client.d.ts.map +1 -1
  11. package/dist/src/cluster/client.js +8 -13
  12. package/dist/src/cluster/client.js.map +1 -1
  13. package/dist/src/cluster/cluster-policy.d.ts +2 -1
  14. package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
  15. package/dist/src/cluster/cluster-policy.js.map +1 -1
  16. package/dist/src/cluster/cluster-repo.d.ts +155 -9
  17. package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
  18. package/dist/src/cluster/cluster-repo.js +446 -58
  19. package/dist/src/cluster/cluster-repo.js.map +1 -1
  20. package/dist/src/cluster/commit-proof.js +2 -2
  21. package/dist/src/cluster/race-resolution.d.ts +51 -7
  22. package/dist/src/cluster/race-resolution.d.ts.map +1 -1
  23. package/dist/src/cluster/race-resolution.js +71 -7
  24. package/dist/src/cluster/race-resolution.js.map +1 -1
  25. package/dist/src/cluster/rebalance-monitor.d.ts +67 -5
  26. package/dist/src/cluster/rebalance-monitor.d.ts.map +1 -1
  27. package/dist/src/cluster/rebalance-monitor.js +120 -26
  28. package/dist/src/cluster/rebalance-monitor.js.map +1 -1
  29. package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
  30. package/dist/src/cluster/spread-on-churn.js +34 -47
  31. package/dist/src/cluster/spread-on-churn.js.map +1 -1
  32. package/dist/src/cohort-topic/host.d.ts.map +1 -1
  33. package/dist/src/cohort-topic/host.js +8 -6
  34. package/dist/src/cohort-topic/host.js.map +1 -1
  35. package/dist/src/cohort-topic/membership-source.js +1 -1
  36. package/dist/src/cohort-topic/membership-source.js.map +1 -1
  37. package/dist/src/cohort-topic/peer-codec.d.ts.map +1 -1
  38. package/dist/src/cohort-topic/peer-codec.js +5 -2
  39. package/dist/src/cohort-topic/peer-codec.js.map +1 -1
  40. package/dist/src/cohort-topic/stream-util.d.ts +24 -3
  41. package/dist/src/cohort-topic/stream-util.d.ts.map +1 -1
  42. package/dist/src/cohort-topic/stream-util.js +36 -3
  43. package/dist/src/cohort-topic/stream-util.js.map +1 -1
  44. package/dist/src/cohort-topic/topic-router.d.ts +9 -0
  45. package/dist/src/cohort-topic/topic-router.d.ts.map +1 -1
  46. package/dist/src/cohort-topic/topic-router.js +12 -2
  47. package/dist/src/cohort-topic/topic-router.js.map +1 -1
  48. package/dist/src/dispute/client.d.ts.map +1 -1
  49. package/dist/src/dispute/client.js +15 -3
  50. package/dist/src/dispute/client.js.map +1 -1
  51. package/dist/src/index.d.ts +5 -0
  52. package/dist/src/index.d.ts.map +1 -1
  53. package/dist/src/index.js +5 -0
  54. package/dist/src/index.js.map +1 -1
  55. package/dist/src/libp2p-key-network.d.ts +78 -17
  56. package/dist/src/libp2p-key-network.d.ts.map +1 -1
  57. package/dist/src/libp2p-key-network.js +234 -147
  58. package/dist/src/libp2p-key-network.js.map +1 -1
  59. package/dist/src/libp2p-node-base.d.ts +35 -1
  60. package/dist/src/libp2p-node-base.d.ts.map +1 -1
  61. package/dist/src/libp2p-node-base.js +151 -26
  62. package/dist/src/libp2p-node-base.js.map +1 -1
  63. package/dist/src/libp2p-node-rn.d.ts +2 -2
  64. package/dist/src/libp2p-node-rn.d.ts.map +1 -1
  65. package/dist/src/libp2p-node-rn.js.map +1 -1
  66. package/dist/src/libp2p-node.d.ts +2 -2
  67. package/dist/src/libp2p-node.d.ts.map +1 -1
  68. package/dist/src/libp2p-node.js.map +1 -1
  69. package/dist/src/logger.d.ts.map +1 -1
  70. package/dist/src/logger.js +6 -1
  71. package/dist/src/logger.js.map +1 -1
  72. package/dist/src/matchmaking/query-transport.d.ts +3 -4
  73. package/dist/src/matchmaking/query-transport.d.ts.map +1 -1
  74. package/dist/src/matchmaking/query-transport.js +9 -9
  75. package/dist/src/matchmaking/query-transport.js.map +1 -1
  76. package/dist/src/network/network-manager-service.d.ts +10 -5
  77. package/dist/src/network/network-manager-service.d.ts.map +1 -1
  78. package/dist/src/network/network-manager-service.js +11 -2
  79. package/dist/src/network/network-manager-service.js.map +1 -1
  80. package/dist/src/network/relay-reservation.d.ts +170 -0
  81. package/dist/src/network/relay-reservation.d.ts.map +1 -0
  82. package/dist/src/network/relay-reservation.js +527 -0
  83. package/dist/src/network/relay-reservation.js.map +1 -0
  84. package/dist/src/pend-validation.d.ts +3 -2
  85. package/dist/src/pend-validation.d.ts.map +1 -1
  86. package/dist/src/pend-validation.js +3 -2
  87. package/dist/src/pend-validation.js.map +1 -1
  88. package/dist/src/protocol-client.d.ts +8 -1
  89. package/dist/src/protocol-client.d.ts.map +1 -1
  90. package/dist/src/protocol-client.js +11 -0
  91. package/dist/src/protocol-client.js.map +1 -1
  92. package/dist/src/reactivity/forwarder-host.d.ts +2 -1
  93. package/dist/src/reactivity/forwarder-host.d.ts.map +1 -1
  94. package/dist/src/reactivity/forwarder-host.js +2 -1
  95. package/dist/src/reactivity/forwarder-host.js.map +1 -1
  96. package/dist/src/reactivity/origination-manager.d.ts +3 -3
  97. package/dist/src/reactivity/origination-manager.js +3 -3
  98. package/dist/src/reactivity/recover-transport.d.ts +22 -14
  99. package/dist/src/reactivity/recover-transport.d.ts.map +1 -1
  100. package/dist/src/reactivity/recover-transport.js +32 -19
  101. package/dist/src/reactivity/recover-transport.js.map +1 -1
  102. package/dist/src/reactivity/subscription-manager.d.ts +2 -2
  103. package/dist/src/reactivity/topic-bytes.d.ts +6 -7
  104. package/dist/src/reactivity/topic-bytes.d.ts.map +1 -1
  105. package/dist/src/reactivity/topic-bytes.js +8 -9
  106. package/dist/src/reactivity/topic-bytes.js.map +1 -1
  107. package/dist/src/repo/client.d.ts +5 -2
  108. package/dist/src/repo/client.d.ts.map +1 -1
  109. package/dist/src/repo/client.js +49 -40
  110. package/dist/src/repo/client.js.map +1 -1
  111. package/dist/src/repo/cluster-coordinator.d.ts +96 -11
  112. package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
  113. package/dist/src/repo/cluster-coordinator.js +164 -25
  114. package/dist/src/repo/cluster-coordinator.js.map +1 -1
  115. package/dist/src/repo/coordinator-repo.d.ts +240 -122
  116. package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
  117. package/dist/src/repo/coordinator-repo.js +627 -473
  118. package/dist/src/repo/coordinator-repo.js.map +1 -1
  119. package/dist/src/repo/i-under-replication-ledger.d.ts +87 -0
  120. package/dist/src/repo/i-under-replication-ledger.d.ts.map +1 -0
  121. package/dist/src/repo/i-under-replication-ledger.js +2 -0
  122. package/dist/src/repo/i-under-replication-ledger.js.map +1 -0
  123. package/dist/src/repo/kv-under-replication-ledger.d.ts +91 -0
  124. package/dist/src/repo/kv-under-replication-ledger.d.ts.map +1 -0
  125. package/dist/src/repo/kv-under-replication-ledger.js +287 -0
  126. package/dist/src/repo/kv-under-replication-ledger.js.map +1 -0
  127. package/dist/src/repo/responsibility.d.ts +37 -0
  128. package/dist/src/repo/responsibility.d.ts.map +1 -0
  129. package/dist/src/repo/responsibility.js +37 -0
  130. package/dist/src/repo/responsibility.js.map +1 -0
  131. package/dist/src/repo/service.d.ts +44 -15
  132. package/dist/src/repo/service.d.ts.map +1 -1
  133. package/dist/src/repo/service.js +64 -27
  134. package/dist/src/repo/service.js.map +1 -1
  135. package/dist/src/repo/stuck-reservation.d.ts +127 -0
  136. package/dist/src/repo/stuck-reservation.d.ts.map +1 -0
  137. package/dist/src/repo/stuck-reservation.js +179 -0
  138. package/dist/src/repo/stuck-reservation.js.map +1 -0
  139. package/dist/src/repo/under-replication-drain.d.ts +208 -0
  140. package/dist/src/repo/under-replication-drain.d.ts.map +1 -0
  141. package/dist/src/repo/under-replication-drain.js +461 -0
  142. package/dist/src/repo/under-replication-drain.js.map +1 -0
  143. package/dist/src/rn.d.ts +5 -0
  144. package/dist/src/rn.d.ts.map +1 -1
  145. package/dist/src/rn.js +5 -0
  146. package/dist/src/rn.js.map +1 -1
  147. package/dist/src/storage/block-latch.d.ts +3 -2
  148. package/dist/src/storage/block-latch.d.ts.map +1 -1
  149. package/dist/src/storage/block-latch.js +7 -4
  150. package/dist/src/storage/block-latch.js.map +1 -1
  151. package/dist/src/storage/block-storage.d.ts +45 -3
  152. package/dist/src/storage/block-storage.d.ts.map +1 -1
  153. package/dist/src/storage/block-storage.js +156 -9
  154. package/dist/src/storage/block-storage.js.map +1 -1
  155. package/dist/src/storage/i-block-storage.d.ts +57 -5
  156. package/dist/src/storage/i-block-storage.d.ts.map +1 -1
  157. package/dist/src/storage/i-block-storage.js.map +1 -1
  158. package/dist/src/storage/pending-claim.d.ts +167 -0
  159. package/dist/src/storage/pending-claim.d.ts.map +1 -0
  160. package/dist/src/storage/pending-claim.js +156 -0
  161. package/dist/src/storage/pending-claim.js.map +1 -0
  162. package/dist/src/storage/raw-store-codec.d.ts +13 -0
  163. package/dist/src/storage/raw-store-codec.d.ts.map +1 -1
  164. package/dist/src/storage/raw-store-codec.js +24 -3
  165. package/dist/src/storage/raw-store-codec.js.map +1 -1
  166. package/dist/src/storage/restoration-coordinator.d.ts.map +1 -1
  167. package/dist/src/storage/restoration-coordinator.js +2 -1
  168. package/dist/src/storage/restoration-coordinator.js.map +1 -1
  169. package/dist/src/storage/ring-shift-coordinator.d.ts.map +1 -1
  170. package/dist/src/storage/ring-shift-coordinator.js +3 -3
  171. package/dist/src/storage/ring-shift-coordinator.js.map +1 -1
  172. package/dist/src/storage/storage-repo.d.ts +122 -5
  173. package/dist/src/storage/storage-repo.d.ts.map +1 -1
  174. package/dist/src/storage/storage-repo.js +245 -68
  175. package/dist/src/storage/storage-repo.js.map +1 -1
  176. package/dist/src/storage/struct.d.ts +58 -0
  177. package/dist/src/storage/struct.d.ts.map +1 -1
  178. package/dist/src/testing/mesh-harness.d.ts +77 -11
  179. package/dist/src/testing/mesh-harness.d.ts.map +1 -1
  180. package/dist/src/testing/mesh-harness.js +226 -100
  181. package/dist/src/testing/mesh-harness.js.map +1 -1
  182. package/package.json +2 -2
  183. package/readme.md +27 -3
  184. package/src/cluster/block-transfer-service.ts +132 -4
  185. package/src/cluster/block-transfer.ts +79 -84
  186. package/src/cluster/client.ts +115 -119
  187. package/src/cluster/cluster-policy.ts +2 -1
  188. package/src/cluster/cluster-repo.ts +493 -65
  189. package/src/cluster/commit-proof.ts +2 -2
  190. package/src/cluster/race-resolution.ts +76 -7
  191. package/src/cluster/rebalance-monitor.ts +677 -539
  192. package/src/cluster/spread-on-churn.ts +34 -54
  193. package/src/cohort-topic/host.ts +8 -6
  194. package/src/cohort-topic/membership-source.ts +1 -1
  195. package/src/cohort-topic/peer-codec.ts +34 -31
  196. package/src/cohort-topic/stream-util.ts +39 -4
  197. package/src/cohort-topic/topic-router.ts +12 -2
  198. package/src/dispute/client.ts +17 -7
  199. package/src/index.ts +64 -59
  200. package/src/libp2p-key-network.ts +1377 -1260
  201. package/src/libp2p-node-base.ts +186 -27
  202. package/src/libp2p-node-rn.ts +31 -30
  203. package/src/libp2p-node.ts +37 -36
  204. package/src/logger.ts +6 -1
  205. package/src/matchmaking/query-transport.ts +9 -9
  206. package/src/network/network-manager-service.ts +16 -5
  207. package/src/network/relay-reservation.ts +636 -0
  208. package/src/pend-validation.ts +3 -2
  209. package/src/protocol-client.ts +13 -1
  210. package/src/reactivity/forwarder-host.ts +2 -1
  211. package/src/reactivity/origination-manager.ts +3 -3
  212. package/src/reactivity/recover-transport.ts +39 -22
  213. package/src/reactivity/subscription-manager.ts +2 -2
  214. package/src/reactivity/topic-bytes.ts +35 -37
  215. package/src/repo/client.ts +172 -173
  216. package/src/repo/cluster-coordinator.ts +183 -25
  217. package/src/repo/coordinator-repo.ts +656 -506
  218. package/src/repo/i-under-replication-ledger.ts +89 -0
  219. package/src/repo/kv-under-replication-ledger.ts +302 -0
  220. package/src/repo/responsibility.ts +48 -0
  221. package/src/repo/service.ts +76 -39
  222. package/src/repo/stuck-reservation.ts +224 -0
  223. package/src/repo/under-replication-drain.ts +582 -0
  224. package/src/rn.ts +74 -69
  225. package/src/storage/block-latch.ts +7 -4
  226. package/src/storage/block-storage.ts +161 -10
  227. package/src/storage/i-block-storage.ts +60 -5
  228. package/src/storage/pending-claim.ts +200 -0
  229. package/src/storage/raw-store-codec.ts +26 -3
  230. package/src/storage/restoration-coordinator.ts +212 -211
  231. package/src/storage/ring-shift-coordinator.ts +271 -271
  232. package/src/storage/storage-repo.ts +280 -72
  233. package/src/storage/struct.ts +58 -0
  234. package/src/testing/mesh-harness.ts +293 -112
@@ -1,6 +1,7 @@
1
- import type { BlockId, IBlock, Transform, ActionId, ActionRev } from "@optimystic/db-core";
1
+ import type { BlockId, IBlock, Transform, ActionId, ActionRev, BlockLineage } from "@optimystic/db-core";
2
2
  import type { BlockCommitProof } from "../cluster/commit-proof.js";
3
3
  import type { BlockWriteLatch } from "./block-latch.js";
4
+ import type { PendingClaim } from "./pending-claim.js";
4
5
  /**
5
6
  * Thrown by {@link IBlockStorage.getBlock} when the block has metadata here but the target revision
6
7
  * lies outside the locally held revision ranges — this node holds no local records that can serve
@@ -101,10 +102,40 @@ export interface IBlockStorage {
101
102
  * under one multi-block write-latch hold, so every block it saves was observed under that same
102
103
  * hold to satisfy `latest === undefined || latest.rev < rev`, and no writer can advance a block
103
104
  * without its latch. A throw here means a caller reintroduced check-then-act.
105
+ *
106
+ * The revision is also KEPT, in the block's metadata (`BlockMetadata.pendingRevs`), so the record
107
+ * can later be read as a claim on a specific slot — see {@link listPendingClaims}.
108
+ *
109
+ * `baseRev` is the committed revision the record's update operations were computed against — the
110
+ * pend's `baseRevs[blockId]` — or `undefined` when the pend named none for this block (an
111
+ * inserted or deleted block, or a base the author did not know). Kept beside the revision
112
+ * (`BlockMetadata.pendingBases`), in the same metadata write, so that every later step that
113
+ * applies the record can refuse to apply it to a different version of the block — see
114
+ * {@link pendingClaimOf}. Stored as told: whether it matches this node's `latest` is decided
115
+ * where the record is APPLIED (`StorageRepo.internalCommit`, and the read-driven promotion in
116
+ * `StorageRepo.get`), never here.
104
117
  */
105
- savePendingTransaction(actionId: ActionId, transform: Transform, rev: number | undefined, latch: BlockWriteLatch): Promise<void>;
106
- /** Deletes a pending action */
118
+ savePendingTransaction(actionId: ActionId, transform: Transform, rev: number | undefined, baseRev: number | undefined, latch: BlockWriteLatch): Promise<void>;
119
+ /** Deletes a pending action, and the revision and base it was recorded as claiming. */
107
120
  deletePendingTransaction(actionId: ActionId, latch: BlockWriteLatch): Promise<void>;
121
+ /**
122
+ * Every pending record on this block, each with the revision it was pended at and the base it
123
+ * was computed against when those are known — the pending namespace joined against
124
+ * `BlockMetadata.pendingRevs` and `pendingBases`. This is the view the rival-pend checks read
125
+ * (`StorageRepo.pend`'s apply-time scan and `ClusterMember.validatePendOperations`' promise
126
+ * vote), because whether a record reserves the block against a given pend depends on the slot
127
+ * it claims measured against the pend's revision — and, at the vote of a cohort that can leave a
128
+ * member out, its base (`isReservationAgainst`) — not on its mere presence. Read-only; no latch.
129
+ */
130
+ listPendingClaims(): Promise<PendingClaim[]>;
131
+ /**
132
+ * The claim of ONE pending record — `actionId`'s entry of {@link listPendingClaims} — or
133
+ * `undefined` when this block holds no pending record for the action. For the two apply sites
134
+ * (`StorageRepo.internalCommit` and the read-driven promotion in `StorageRepo.get`), which need
135
+ * one record's base on the hot commit path and must not enumerate every record to get it.
136
+ * Read-only; no latch of its own: both callers already hold the block's write latch.
137
+ */
138
+ pendingClaimOf(actionId: ActionId): Promise<PendingClaim | undefined>;
108
139
  /** Lists revisions in ascending or descending order between startRev and endRev (inclusive) */
109
140
  listRevisions(startRev: number, endRev: number): AsyncIterable<ActionRev>;
110
141
  /** Saves a materialized block */
@@ -135,8 +166,29 @@ export interface IBlockStorage {
135
166
  * record for a revision the block has already reached.
136
167
  */
137
168
  promotePendingTransaction(actionId: ActionId, latch: BlockWriteLatch): Promise<void>;
138
- /** Sets the latest revision information */
139
- setLatest(latest: ActionRev, latch: BlockWriteLatch): Promise<void>;
169
+ /**
170
+ * Sets the latest revision information, as the last step of committing `latest` here.
171
+ *
172
+ * Call it only after {@link promotePendingTransaction} has moved `latest.actionId`'s record: it
173
+ * drops that action's claim without deleting a record, so a caller that skipped promotion would
174
+ * leave a claim-less pending record behind (see `BlockMetadata.pendingRevs`).
175
+ *
176
+ * `builtOnPrior` says how the revision's content was produced, which is what the block's known
177
+ * lineage depends on (see `BlockMetadata.lineageFloor`): `true` when this node applied the
178
+ * revision's transform to the content of its previous revision (an update-only or delete
179
+ * transform); `false` when the content stands on its own because the transform carried an
180
+ * `insert`. Required rather than defaulted: a caller that guessed `true` for an insert would let
181
+ * {@link lineageOf} vouch for history the content never came from.
182
+ */
183
+ setLatest(latest: ActionRev, builtOnPrior: boolean, latch: BlockWriteLatch): Promise<void>;
184
+ /**
185
+ * What THIS node's records say about whether the block's content at `latest` was built from the
186
+ * committed `target` — see `BlockLineage` in db-core for the four answers. Local and read-only:
187
+ * no latch, no peer fetch, no promotion. `unknown` is the honest answer whenever this node is
188
+ * past `target.rev` but took later content it did not derive itself (a replica, a restore);
189
+ * another cohort member that applied those revisions locally can still answer.
190
+ */
191
+ lineageOf(target: ActionRev): Promise<BlockLineage>;
140
192
  /**
141
193
  * Persist a replica of a block received out-of-band (churn re-replication).
142
194
  *
@@ -1 +1 @@
1
- {"version":3,"file":"i-block-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"i-block-storage.d.ts","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"i-block-storage.js","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAC5B;IAA2B;IAAhD,YAAqB,OAAgB,EAAW,GAAW;QAC1D,KAAK,CAAC,SAAS,OAAO,aAAa,GAAG,kCAAkC,CAAC,CAAC;QADtD,YAAO,GAAP,OAAO,CAAS;QAAW,QAAG,GAAH,GAAG,CAAQ;QAE1D,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACvC,CAAC;CACD;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC3B;IAA2B;IAA6B;IAAsB;IAAnG,YAAqB,OAAgB,EAAW,QAAkB,EAAW,GAAW,EAAW,MAAiB;QACnH,KAAK,CAAC,SAAS,OAAO,wBAAwB,QAAQ,gBAAgB,GAAG,iBAAiB;cACvF,iCAAiC,MAAM,CAAC,GAAG,YAAY,MAAM,CAAC,QAAQ,YAAY;cAClF,wCAAwC,CAAC,CAAC;QAHzB,YAAO,GAAP,OAAO,CAAS;QAAW,aAAQ,GAAR,QAAQ,CAAU;QAAW,QAAG,GAAH,GAAG,CAAQ;QAAW,WAAM,GAAN,MAAM,CAAW;QAInH,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACtC,CAAC;CACD"}
1
+ {"version":3,"file":"i-block-storage.js","sourceRoot":"","sources":["../../../src/storage/i-block-storage.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAC5B;IAA2B;IAAhD,YAAqB,OAAgB,EAAW,GAAW;QAC1D,KAAK,CAAC,SAAS,OAAO,aAAa,GAAG,kCAAkC,CAAC,CAAC;QADtD,YAAO,GAAP,OAAO,CAAS;QAAW,QAAG,GAAH,GAAG,CAAQ;QAE1D,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACvC,CAAC;CACD;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC3B;IAA2B;IAA6B;IAAsB;IAAnG,YAAqB,OAAgB,EAAW,QAAkB,EAAW,GAAW,EAAW,MAAiB;QACnH,KAAK,CAAC,SAAS,OAAO,wBAAwB,QAAQ,gBAAgB,GAAG,iBAAiB;cACvF,iCAAiC,MAAM,CAAC,GAAG,YAAY,MAAM,CAAC,QAAQ,YAAY;cAClF,wCAAwC,CAAC,CAAC;QAHzB,YAAO,GAAP,OAAO,CAAS;QAAW,aAAQ,GAAR,QAAQ,CAAU;QAAW,QAAG,GAAH,GAAG,CAAQ;QAAW,WAAM,GAAN,MAAM,CAAW;QAInH,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACtC,CAAC;CACD"}
@@ -0,0 +1,167 @@
1
+ import type { ActionId, BlockId, PendRequest, Transform } from "@optimystic/db-core";
2
+ /**
3
+ * One pending record on a block, with the revision its pend asked for.
4
+ *
5
+ * `rev` is the `PendRequest.rev` the record was written under (see
6
+ * `IBlockStorage.savePendingTransaction`), kept in the block's metadata beside `latest`
7
+ * (`BlockMetadata.pendingRevs`). Absent for a record that named no revision — an insert-only pend,
8
+ * which no production caller sends — and for a record written before the revision was kept at all.
9
+ * Both read as "unknown", and an unknown claim is treated as the strongest one (see
10
+ * {@link isReservationAgainst}), so an old record can only refuse more than it should, never less.
11
+ */
12
+ export interface PendingClaim {
13
+ actionId: ActionId;
14
+ rev?: number;
15
+ /**
16
+ * The committed revision the record's update operations were computed against — the pend's
17
+ * `baseRevs[blockId]`, kept in `BlockMetadata.pendingBases`. Absent for a record whose pend
18
+ * carried no base for this block (inserted, deleted, or unknown to the author) and for a record
19
+ * written before the field existed; both read as "base unknown". Unlike an unknown `rev`, an
20
+ * unknown base is NOT the strongest kind of anything: it is simply nothing to compare, and each
21
+ * apply site decides what that means for it (`StorageRepo.internalCommit` falls back to the
22
+ * commit's own declaration; the read-driven promotion in `StorageRepo.get` declines; the rival
23
+ * rule, {@link isReservationAgainst}, keeps the revision rule for it).
24
+ */
25
+ baseRev?: number;
26
+ }
27
+ /**
28
+ * What {@link isReservationAgainst} reads of an incoming pend, for one block: the revision it
29
+ * requests, and the committed base the block's update operations were computed against — built from
30
+ * the pend by {@link reservationRequestFor}, so the rule reads exactly the base storage would keep.
31
+ */
32
+ export interface ReservationRequest {
33
+ rev?: number;
34
+ baseRev?: number;
35
+ }
36
+ /**
37
+ * Whether a rival's pending record is a RESERVATION against an incoming pend for the same block —
38
+ * the one question both rival scans ask (`StorageRepo.pend` at apply,
39
+ * `ClusterMember.validatePendOperations` at the promise vote).
40
+ *
41
+ * A pending record reserves the block for the revision it claims: it says "I am about to commit
42
+ * this block at revision `rev`", and it holds that slot from pend-apply until its commit or cancel.
43
+ * It stops reserving once the incoming writer has BUILT ON it — read the block with that change in
44
+ * it — because then admitting the newcomer cannot lose the change, whatever became of the record's
45
+ * action. The rule, first match wins:
46
+ *
47
+ * - Either side's revision unknown → reserves. A record predating revision recording keeps the
48
+ * old behaviour rather than silently admitting a rival, and a rev-less request cannot be placed
49
+ * past anything.
50
+ * - The record carries a base AND the request carries a usable one ({@link usableBase}: a number
51
+ * below the requested revision) → reserves iff `claim.rev > baseRev`. A base at or past the
52
+ * claimed slot means the newcomer's operations were computed against a version of the block that
53
+ * already holds the record's change (it committed there, and this member merely missed the
54
+ * commit — the newcomer's own commit brings it current), or against a version past a slot the
55
+ * record lost. A base below it means the newcomer read the block without that change, and
56
+ * admitting it would let its commit apply over the stale base and sweep the record — the rival's
57
+ * change lost while the log names it.
58
+ * - Otherwise → reserves iff `claim.rev >= rev` (the revision rule). Revisions are allocated per
59
+ * COLLECTION and a writer pends at one past the collection revision it read, so a claim below the
60
+ * requested revision is one the collection has moved past, which is taken as having been built
61
+ * on. That is sound when the newcomer read the block from a member that held the record
62
+ * (`StorageRepo.get` promotes a record for any action the reader's context names, with the block
63
+ * floor, `BlockGets.floors`, as the second line), and false in exactly one shape: a member that
64
+ * never received the rival's pend — possible only where the promise quorum can leave a member
65
+ * out, see {@link cohortCanMissAPend} — serving a floor-less handle while the rival's data-block
66
+ * commit is still in flight. It stays the rule for a request with no usable base (an inserted or
67
+ * deleted block, a sender that names none, or a malformed base), and for a record with no stored
68
+ * base (an inserted or deleted block, or a record written by a release that did not keep bases).
69
+ * A base-less record keeps clearing the moment the collection moves past its slot, as it always
70
+ * did: judged by the newcomer's base, one whose commit ran nowhere could never clear, since no
71
+ * member can promote it (the read-driven promotion declines a record with no base), and a node
72
+ * upgraded over its own leftovers would wedge on them. The price: a rival that DELETES the block
73
+ * keeps no base either, so the missed-pend shape below stays open for a rival delete, exactly as
74
+ * it was before the base arm existed.
75
+ *
76
+ * The base arm is never more permissive than the revision arm: an honest base is at most `rev - 1`,
77
+ * so a claim at or below the base is also below the requested revision. It can only hold more,
78
+ * which is why the safety argument of Theorem 1 does not weaken. It closes the missed-pend shape
79
+ * wherever the members still holding the rival's record are enough to deny the newcomer a
80
+ * super-majority — one member missing the pend leaves every other one holding it — and a member
81
+ * that has meanwhile taken the rival's change refuses the newcomer's commit at the fork guard
82
+ * (`StorageRepo.internalCommit`) instead. Liveness for the missed-commit
83
+ * shape (`a-member-that-missed-a-commit-refuses-every-later-write`) is preserved: a writer that read
84
+ * the block from a member that applied the rival's change declares at least that revision as its
85
+ * base, and one served by the missed-commit member itself is served after that member promotes the
86
+ * record, which it does whenever the record's stored base equals its latest.
87
+ *
88
+ * WHERE the base is read is the callers' decision, and deliberately narrow: only the promise vote
89
+ * reads it, and only for a cohort whose quorum can leave a member out ({@link cohortCanMissAPend});
90
+ * the apply-time scan in `StorageRepo.pend`, and the vote in every smaller cohort, pass no base. So
91
+ * the apply never refuses what the vote approved. Holding more costs liveness in two shapes, and the
92
+ * narrowing keeps both off cohorts that need unanimity (two and three members at the default
93
+ * threshold), where one member's hold sinks the pend: (1) a newcomer that read the block one change
94
+ * short is held until the rival commits, and its retries do not re-read the block today, so it then
95
+ * re-pends on the stale base and the fork guard refuses its commit — refused, never acknowledged over
96
+ * the rival (backlog `bug-a-writer-held-by-a-change-it-never-saw-retries-on-its-stale-copy`); (2) a
97
+ * record whose change no member will ever take — an abandoned action whose data-block pend landed,
98
+ * whose log-tail pend did not, and whose cancel never arrived — used to be superseded as soon as the
99
+ * collection moved past its slot, and under the base arm holds every newcomer instead.
100
+ *
101
+ * NOTE: from four members up, residual (2) wedges the block when the stray record stands on enough
102
+ * members to deny a super-majority (a writer that crashed after its data-block pend, before any
103
+ * cancel); a stray record on one member alone is outvoted, and that member's own apply (revision
104
+ * rule) then admits the newcomer, whose commit sweeps the record. Locally the member cannot tell the
105
+ * crashed writer's record from the missed-pend shape: both are a record claiming a slot past the
106
+ * block's latest, met by a newcomer whose base is that latest. Backlog
107
+ * `debt-unpromotable-pending-records-need-a-sweep` owns abandoned records, and both stuck-reservation
108
+ * lines name the block; if it shows up in the field, the cure is that sweep, not a looser rule here.
109
+ */
110
+ export declare function isReservationAgainst(claim: PendingClaim, request: ReservationRequest): boolean;
111
+ /**
112
+ * Whether a cohort of `peerCount` members, promising at `superMajorityThreshold`, can reach its
113
+ * promise super-majority without one of its members — so a member can miss a pend the rest of the
114
+ * cohort stored, and later serve the block one change short. That is the only shape the base arm of
115
+ * {@link isReservationAgainst} closes, and it is also exactly where one member's hold cannot sink a
116
+ * pend by itself. Below it (two and three members at the default 0.75) every member's approval is
117
+ * needed, so the base arm could only add holds that no lost update justifies. The promise vote
118
+ * reads the incoming base only when this is true.
119
+ */
120
+ export declare function cohortCanMissAPend(peerCount: number, superMajorityThreshold: number): boolean;
121
+ /**
122
+ * `request.baseRev` when {@link isReservationAgainst} can read it: a number strictly below the
123
+ * requested revision. Anything else — absent, not a number (untrusted wire data), or at or past
124
+ * `rev`, which no honest writer sends since its base is a revision it read and it pends past what it
125
+ * read — is `undefined`, and the rule falls back to the requested revision alone.
126
+ */
127
+ export declare function usableBase(request: ReservationRequest): number | undefined;
128
+ /**
129
+ * The {@link ReservationRequest} `pend` makes of `blockId`, whose transform within the pend is
130
+ * `transform`: the pend's revision, and the base {@link declaredBaseFor} keeps for the block — so a
131
+ * base on an inserted or deleted block, or a malformed one, is read by the rule exactly as storage
132
+ * keeps it: not at all. `ignoredBase` carries a base the pend named for the block that the rule does
133
+ * not read (malformed, not below the revision, or on a base-independent transform), for the caller's
134
+ * log line; no producer sends one.
135
+ */
136
+ export declare function reservationRequestFor(pend: Pick<PendRequest, 'rev' | 'baseRevs'>, blockId: BlockId, transform: Transform): {
137
+ request: ReservationRequest;
138
+ ignoredBase?: unknown;
139
+ };
140
+ /**
141
+ * Whether `transform`'s result does not depend on the block's prior content: an insert replaces the
142
+ * block wholesale and a delete materializes to nothing (delete-last-wins in `applyTransform`), so
143
+ * neither can fork on a different base, and no base is ever named for them (`Tracker.stagedBaseRevs`
144
+ * names update-only blocks alone). Every base check keys on this, on the member's OWN pended
145
+ * transform (or the incoming pend's own transform, at the rival scans), never on what a request
146
+ * declares.
147
+ */
148
+ export declare function isBaseIndependent(transform: Transform): boolean;
149
+ /**
150
+ * The base a pend declares for `blockId`, as storage will keep it: `baseRevs[blockId]` when it is a
151
+ * number and the block's transform is update-only, else nothing. Untrusted wire data with no ingress
152
+ * schema (the posture `validateCommitOperations` takes toward `blockDigests`): a malformed or surplus
153
+ * entry is ignored for that id, never thrown on; an entry for an inserted or deleted block — which no
154
+ * producer sends — is dropped, so a base-independent record can never read as base-dependent later.
155
+ *
156
+ * NOTE: the base is stored AS TOLD, and the pend never refuses on it — not when it is behind this
157
+ * member's latest, and not when it is ahead. A member has no grounds to second-guess the author's
158
+ * claim about the author's own computation (the client is what makes an honest claim correct:
159
+ * `Tracker` pins the base at the first staged update and re-stages over a moved one). Refusing here
160
+ * would also be the wrong tier: a member holding a torn or abandoned HIGHER revision would cast a
161
+ * reject that, at three members, fails every honest retry — the writer re-reads the majority's
162
+ * revision and declares it again — whereas the same mismatch at commit time is one member's refusal
163
+ * (`StorageRepo.internalCommit`), heals by reconcile, and the cohort still commits on majority
164
+ * durability.
165
+ */
166
+ export declare function declaredBaseFor(baseRevs: PendRequest['baseRevs'], blockId: BlockId, transform: Transform): number | undefined;
167
+ //# sourceMappingURL=pending-claim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-claim.d.ts","sourceRoot":"","sources":["../../../src/storage/pending-claim.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErF;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAM9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,GAAG,OAAO,CAE7F;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,GAAG,SAAS,CAG1E;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GACjF;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAQxD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAE/D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAM7H"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Whether a rival's pending record is a RESERVATION against an incoming pend for the same block —
3
+ * the one question both rival scans ask (`StorageRepo.pend` at apply,
4
+ * `ClusterMember.validatePendOperations` at the promise vote).
5
+ *
6
+ * A pending record reserves the block for the revision it claims: it says "I am about to commit
7
+ * this block at revision `rev`", and it holds that slot from pend-apply until its commit or cancel.
8
+ * It stops reserving once the incoming writer has BUILT ON it — read the block with that change in
9
+ * it — because then admitting the newcomer cannot lose the change, whatever became of the record's
10
+ * action. The rule, first match wins:
11
+ *
12
+ * - Either side's revision unknown → reserves. A record predating revision recording keeps the
13
+ * old behaviour rather than silently admitting a rival, and a rev-less request cannot be placed
14
+ * past anything.
15
+ * - The record carries a base AND the request carries a usable one ({@link usableBase}: a number
16
+ * below the requested revision) → reserves iff `claim.rev > baseRev`. A base at or past the
17
+ * claimed slot means the newcomer's operations were computed against a version of the block that
18
+ * already holds the record's change (it committed there, and this member merely missed the
19
+ * commit — the newcomer's own commit brings it current), or against a version past a slot the
20
+ * record lost. A base below it means the newcomer read the block without that change, and
21
+ * admitting it would let its commit apply over the stale base and sweep the record — the rival's
22
+ * change lost while the log names it.
23
+ * - Otherwise → reserves iff `claim.rev >= rev` (the revision rule). Revisions are allocated per
24
+ * COLLECTION and a writer pends at one past the collection revision it read, so a claim below the
25
+ * requested revision is one the collection has moved past, which is taken as having been built
26
+ * on. That is sound when the newcomer read the block from a member that held the record
27
+ * (`StorageRepo.get` promotes a record for any action the reader's context names, with the block
28
+ * floor, `BlockGets.floors`, as the second line), and false in exactly one shape: a member that
29
+ * never received the rival's pend — possible only where the promise quorum can leave a member
30
+ * out, see {@link cohortCanMissAPend} — serving a floor-less handle while the rival's data-block
31
+ * commit is still in flight. It stays the rule for a request with no usable base (an inserted or
32
+ * deleted block, a sender that names none, or a malformed base), and for a record with no stored
33
+ * base (an inserted or deleted block, or a record written by a release that did not keep bases).
34
+ * A base-less record keeps clearing the moment the collection moves past its slot, as it always
35
+ * did: judged by the newcomer's base, one whose commit ran nowhere could never clear, since no
36
+ * member can promote it (the read-driven promotion declines a record with no base), and a node
37
+ * upgraded over its own leftovers would wedge on them. The price: a rival that DELETES the block
38
+ * keeps no base either, so the missed-pend shape below stays open for a rival delete, exactly as
39
+ * it was before the base arm existed.
40
+ *
41
+ * The base arm is never more permissive than the revision arm: an honest base is at most `rev - 1`,
42
+ * so a claim at or below the base is also below the requested revision. It can only hold more,
43
+ * which is why the safety argument of Theorem 1 does not weaken. It closes the missed-pend shape
44
+ * wherever the members still holding the rival's record are enough to deny the newcomer a
45
+ * super-majority — one member missing the pend leaves every other one holding it — and a member
46
+ * that has meanwhile taken the rival's change refuses the newcomer's commit at the fork guard
47
+ * (`StorageRepo.internalCommit`) instead. Liveness for the missed-commit
48
+ * shape (`a-member-that-missed-a-commit-refuses-every-later-write`) is preserved: a writer that read
49
+ * the block from a member that applied the rival's change declares at least that revision as its
50
+ * base, and one served by the missed-commit member itself is served after that member promotes the
51
+ * record, which it does whenever the record's stored base equals its latest.
52
+ *
53
+ * WHERE the base is read is the callers' decision, and deliberately narrow: only the promise vote
54
+ * reads it, and only for a cohort whose quorum can leave a member out ({@link cohortCanMissAPend});
55
+ * the apply-time scan in `StorageRepo.pend`, and the vote in every smaller cohort, pass no base. So
56
+ * the apply never refuses what the vote approved. Holding more costs liveness in two shapes, and the
57
+ * narrowing keeps both off cohorts that need unanimity (two and three members at the default
58
+ * threshold), where one member's hold sinks the pend: (1) a newcomer that read the block one change
59
+ * short is held until the rival commits, and its retries do not re-read the block today, so it then
60
+ * re-pends on the stale base and the fork guard refuses its commit — refused, never acknowledged over
61
+ * the rival (backlog `bug-a-writer-held-by-a-change-it-never-saw-retries-on-its-stale-copy`); (2) a
62
+ * record whose change no member will ever take — an abandoned action whose data-block pend landed,
63
+ * whose log-tail pend did not, and whose cancel never arrived — used to be superseded as soon as the
64
+ * collection moved past its slot, and under the base arm holds every newcomer instead.
65
+ *
66
+ * NOTE: from four members up, residual (2) wedges the block when the stray record stands on enough
67
+ * members to deny a super-majority (a writer that crashed after its data-block pend, before any
68
+ * cancel); a stray record on one member alone is outvoted, and that member's own apply (revision
69
+ * rule) then admits the newcomer, whose commit sweeps the record. Locally the member cannot tell the
70
+ * crashed writer's record from the missed-pend shape: both are a record claiming a slot past the
71
+ * block's latest, met by a newcomer whose base is that latest. Backlog
72
+ * `debt-unpromotable-pending-records-need-a-sweep` owns abandoned records, and both stuck-reservation
73
+ * lines name the block; if it shows up in the field, the cure is that sweep, not a looser rule here.
74
+ */
75
+ export function isReservationAgainst(claim, request) {
76
+ if (claim.rev === undefined || request.rev === undefined) {
77
+ return true;
78
+ }
79
+ const base = claim.baseRev === undefined ? undefined : usableBase(request);
80
+ return base === undefined ? claim.rev >= request.rev : claim.rev > base;
81
+ }
82
+ /**
83
+ * Whether a cohort of `peerCount` members, promising at `superMajorityThreshold`, can reach its
84
+ * promise super-majority without one of its members — so a member can miss a pend the rest of the
85
+ * cohort stored, and later serve the block one change short. That is the only shape the base arm of
86
+ * {@link isReservationAgainst} closes, and it is also exactly where one member's hold cannot sink a
87
+ * pend by itself. Below it (two and three members at the default 0.75) every member's approval is
88
+ * needed, so the base arm could only add holds that no lost update justifies. The promise vote
89
+ * reads the incoming base only when this is true.
90
+ */
91
+ export function cohortCanMissAPend(peerCount, superMajorityThreshold) {
92
+ return Math.ceil(peerCount * superMajorityThreshold) < peerCount;
93
+ }
94
+ /**
95
+ * `request.baseRev` when {@link isReservationAgainst} can read it: a number strictly below the
96
+ * requested revision. Anything else — absent, not a number (untrusted wire data), or at or past
97
+ * `rev`, which no honest writer sends since its base is a revision it read and it pends past what it
98
+ * read — is `undefined`, and the rule falls back to the requested revision alone.
99
+ */
100
+ export function usableBase(request) {
101
+ const { rev, baseRev } = request;
102
+ return typeof baseRev === 'number' && rev !== undefined && baseRev < rev ? baseRev : undefined;
103
+ }
104
+ /**
105
+ * The {@link ReservationRequest} `pend` makes of `blockId`, whose transform within the pend is
106
+ * `transform`: the pend's revision, and the base {@link declaredBaseFor} keeps for the block — so a
107
+ * base on an inserted or deleted block, or a malformed one, is read by the rule exactly as storage
108
+ * keeps it: not at all. `ignoredBase` carries a base the pend named for the block that the rule does
109
+ * not read (malformed, not below the revision, or on a base-independent transform), for the caller's
110
+ * log line; no producer sends one.
111
+ */
112
+ export function reservationRequestFor(pend, blockId, transform) {
113
+ const request = { rev: pend.rev };
114
+ const baseRev = declaredBaseFor(pend.baseRevs, blockId, transform);
115
+ if (baseRev !== undefined) {
116
+ request.baseRev = baseRev;
117
+ }
118
+ const named = pend.baseRevs?.[blockId];
119
+ return named !== undefined && usableBase(request) === undefined ? { request, ignoredBase: named } : { request };
120
+ }
121
+ /**
122
+ * Whether `transform`'s result does not depend on the block's prior content: an insert replaces the
123
+ * block wholesale and a delete materializes to nothing (delete-last-wins in `applyTransform`), so
124
+ * neither can fork on a different base, and no base is ever named for them (`Tracker.stagedBaseRevs`
125
+ * names update-only blocks alone). Every base check keys on this, on the member's OWN pended
126
+ * transform (or the incoming pend's own transform, at the rival scans), never on what a request
127
+ * declares.
128
+ */
129
+ export function isBaseIndependent(transform) {
130
+ return Boolean(transform.insert) || Boolean(transform.delete);
131
+ }
132
+ /**
133
+ * The base a pend declares for `blockId`, as storage will keep it: `baseRevs[blockId]` when it is a
134
+ * number and the block's transform is update-only, else nothing. Untrusted wire data with no ingress
135
+ * schema (the posture `validateCommitOperations` takes toward `blockDigests`): a malformed or surplus
136
+ * entry is ignored for that id, never thrown on; an entry for an inserted or deleted block — which no
137
+ * producer sends — is dropped, so a base-independent record can never read as base-dependent later.
138
+ *
139
+ * NOTE: the base is stored AS TOLD, and the pend never refuses on it — not when it is behind this
140
+ * member's latest, and not when it is ahead. A member has no grounds to second-guess the author's
141
+ * claim about the author's own computation (the client is what makes an honest claim correct:
142
+ * `Tracker` pins the base at the first staged update and re-stages over a moved one). Refusing here
143
+ * would also be the wrong tier: a member holding a torn or abandoned HIGHER revision would cast a
144
+ * reject that, at three members, fails every honest retry — the writer re-reads the majority's
145
+ * revision and declares it again — whereas the same mismatch at commit time is one member's refusal
146
+ * (`StorageRepo.internalCommit`), heals by reconcile, and the cohort still commits on majority
147
+ * durability.
148
+ */
149
+ export function declaredBaseFor(baseRevs, blockId, transform) {
150
+ if (isBaseIndependent(transform)) {
151
+ return undefined;
152
+ }
153
+ const declared = baseRevs?.[blockId];
154
+ return typeof declared === 'number' ? declared : undefined;
155
+ }
156
+ //# sourceMappingURL=pending-claim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-claim.js","sourceRoot":"","sources":["../../../src/storage/pending-claim.ts"],"names":[],"mappings":"AAsCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAmB,EAAE,OAA2B;IACpF,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC1D,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC3E,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC;AACzE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,sBAA8B;IACnF,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,sBAAsB,CAAC,GAAG,SAAS,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,OAA2B;IACrD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACjC,OAAO,OAAO,OAAO,KAAK,QAAQ,IAAI,GAAG,KAAK,SAAS,IAAI,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAChG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACpC,IAA2C,EAAE,OAAgB,EAAE,SAAoB;IAEnF,MAAM,OAAO,GAAuB,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;IACtD,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACnE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IACD,MAAM,KAAK,GAAY,IAAI,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;IAChD,OAAO,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;AACjH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAoB;IACrD,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAAC,QAAiC,EAAE,OAAgB,EAAE,SAAoB;IACxG,IAAI,iBAAiB,CAAC,SAAS,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAC5D,CAAC"}
@@ -7,4 +7,17 @@ export declare function decodeJson<T>(bytes: Uint8Array): T;
7
7
  export declare function encodeActionId(actionId: ActionId): Uint8Array;
8
8
  /** Decode UTF-8 bytes back into an `ActionId` string. */
9
9
  export declare function decodeActionId(bytes: Uint8Array): ActionId;
10
+ /**
11
+ * Deep-copy a value this codec decoded (`IBlock` / `Transform`), by the same JSON round-trip the
12
+ * store applies. Used where a caller must mutate a stored value without touching the original, in
13
+ * place of `structuredClone` — which Hermes (React Native) does not provide.
14
+ *
15
+ * Lossless for exactly the values this module hands out: anything `decodeJson` returned is already
16
+ * JSON-shaped, so it carries none of what a JSON round-trip drops or rewrites (an `undefined` array
17
+ * slot, an `undefined`-valued property, a `Date`, a `Uint8Array`) — those were already rewritten when
18
+ * the value was stored. It is NOT a general-purpose `structuredClone` replacement: a live object
19
+ * that never crossed this codec can come back different. `undefined` passes through, since
20
+ * `JSON.parse(JSON.stringify(undefined))` throws.
21
+ */
22
+ export declare function cloneDecoded<T>(value: T): T;
10
23
  //# sourceMappingURL=raw-store-codec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"raw-store-codec.d.ts","sourceRoot":"","sources":["../../../src/storage/raw-store-codec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAuBpD,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,UAAU,CAElD;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CAElD;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAE7D;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CAE1D"}
1
+ {"version":3,"file":"raw-store-codec.d.ts","sourceRoot":"","sources":["../../../src/storage/raw-store-codec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AA8BpD,qFAAqF;AACrF,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,UAAU,CAElD;AAED,6FAA6F;AAC7F,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CAElD;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAE7D;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,QAAQ,CAE1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAE3C"}
@@ -15,15 +15,21 @@
15
15
  * → `"[5]"` → `JSON.parse` → `[5]`, so the open-ended encoding survives byte-exact.
16
16
  * Do NOT normalize ranges here.
17
17
  */
18
+ // The encoder stays module-scope: Hermes provides `TextEncoder` natively (React Native 0.74+).
18
19
  const encoder = new TextEncoder();
19
- const decoder = new TextDecoder();
20
+ // The decoder is built on first use, NOT at module load. Hermes has no native `TextDecoder`, and
21
+ // this module is loaded by the React Native entry (`rn.ts`, via `kv-raw-storage.ts`), so a
22
+ // module-scope `new TextDecoder()` made the import itself throw whenever it ran ahead of the host's
23
+ // polyfill (readme.md § React Native). Memoized, so every call shares one instance as before.
24
+ let decoderInstance;
25
+ const decoder = () => decoderInstance ??= new TextDecoder();
20
26
  /** JSON-encode a value (`BlockMetadata` / `Transform` / `IBlock`) to UTF-8 bytes. */
21
27
  export function encodeJson(value) {
22
28
  return encoder.encode(JSON.stringify(value));
23
29
  }
24
30
  /** Decode UTF-8 JSON bytes back into a value. Callers guard the miss (`undefined`) first. */
25
31
  export function decodeJson(bytes) {
26
- return JSON.parse(decoder.decode(bytes));
32
+ return JSON.parse(decoder().decode(bytes));
27
33
  }
28
34
  /** Encode an `ActionId` string to UTF-8 bytes (stored as the revisions-store value). */
29
35
  export function encodeActionId(actionId) {
@@ -31,6 +37,21 @@ export function encodeActionId(actionId) {
31
37
  }
32
38
  /** Decode UTF-8 bytes back into an `ActionId` string. */
33
39
  export function decodeActionId(bytes) {
34
- return decoder.decode(bytes);
40
+ return decoder().decode(bytes);
41
+ }
42
+ /**
43
+ * Deep-copy a value this codec decoded (`IBlock` / `Transform`), by the same JSON round-trip the
44
+ * store applies. Used where a caller must mutate a stored value without touching the original, in
45
+ * place of `structuredClone` — which Hermes (React Native) does not provide.
46
+ *
47
+ * Lossless for exactly the values this module hands out: anything `decodeJson` returned is already
48
+ * JSON-shaped, so it carries none of what a JSON round-trip drops or rewrites (an `undefined` array
49
+ * slot, an `undefined`-valued property, a `Date`, a `Uint8Array`) — those were already rewritten when
50
+ * the value was stored. It is NOT a general-purpose `structuredClone` replacement: a live object
51
+ * that never crossed this codec can come back different. `undefined` passes through, since
52
+ * `JSON.parse(JSON.stringify(undefined))` throws.
53
+ */
54
+ export function cloneDecoded(value) {
55
+ return value === undefined ? value : JSON.parse(JSON.stringify(value));
35
56
  }
36
57
  //# sourceMappingURL=raw-store-codec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"raw-store-codec.js","sourceRoot":"","sources":["../../../src/storage/raw-store-codec.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAClC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,qFAAqF;AACrF,MAAM,UAAU,UAAU,CAAI,KAAQ;IACrC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,UAAU,CAAI,KAAiB;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAM,CAAC;AAC/C,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,cAAc,CAAC,QAAkB;IAChD,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAC,KAAiB;IAC/C,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAa,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"raw-store-codec.js","sourceRoot":"","sources":["../../../src/storage/raw-store-codec.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,+FAA+F;AAC/F,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,iGAAiG;AACjG,2FAA2F;AAC3F,oGAAoG;AACpG,8FAA8F;AAC9F,IAAI,eAAwC,CAAC;AAC7C,MAAM,OAAO,GAAG,GAAgB,EAAE,CAAC,eAAe,KAAK,IAAI,WAAW,EAAE,CAAC;AAEzE,qFAAqF;AACrF,MAAM,UAAU,UAAU,CAAI,KAAQ;IACrC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,UAAU,CAAI,KAAiB;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAM,CAAC;AACjD,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,cAAc,CAAC,QAAkB;IAChD,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAC,KAAiB;IAC/C,OAAO,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAa,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAI,KAAQ;IACvC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAM,CAAC;AAC7E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"restoration-coordinator.d.ts","sourceRoot":"","sources":["../../../src/storage/restoration-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAGnD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAIxE;;;;;;;;GAQG;AACH,qBAAa,sBAAsB;IASjC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAZ7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAKtB;gBAGgB,WAAW,EAAE,oBAAoB,EACjC,WAAW,EAAE,YAAY,EACzB,cAAc,EAAE,MAAM;IACvC,iFAAiF;IAChE,UAAU,CAAC,EAAE,MAAM,YAAA;IAGrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsC;IAE1D;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IA4DhF;;OAEG;IACH,qBAAqB,IAAI,eAAe;IAMxC;;;OAGG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAazB;;OAEG;YACW,SAAS;IAiBvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAKrB;;OAEG;IACH,UAAU,IAAI;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,iBAAiB,EAAE,MAAM,CAAC;KAC1B;CAWD"}
1
+ {"version":3,"file":"restoration-coordinator.d.ts","sourceRoot":"","sources":["../../../src/storage/restoration-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAInD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAIxE;;;;;;;;GAQG;AACH,qBAAa,sBAAsB;IASjC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAZ7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAKtB;gBAGgB,WAAW,EAAE,oBAAoB,EACjC,WAAW,EAAE,YAAY,EACzB,cAAc,EAAE,MAAM;IACvC,iFAAiF;IAChE,UAAU,CAAC,EAAE,MAAM,YAAA;IAGrC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsC;IAE1D;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IA4DhF;;OAEG;IACH,qBAAqB,IAAI,eAAe;IAMxC;;;OAGG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAazB;;OAEG;YACW,SAAS;IAiBvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAKrB;;OAEG;IACH,UAAU,IAAI;QACb,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,iBAAiB,EAAE,MAAM,CAAC;KAC1B;CAWD"}
@@ -1,3 +1,4 @@
1
+ import { routingKeyForBlock } from '@optimystic/db-core';
1
2
  import { hashKey } from 'p2p-fret';
2
3
  import { peerIdFromString } from '@libp2p/peer-id';
3
4
  import { SyncClient } from '../sync/client.js';
@@ -42,7 +43,7 @@ export class RestorationCoordinator {
42
43
  // (RingSelector.calculatePartition) and cohort assembly both operate on hashed
43
44
  // coords, so restoration must filter in the same space — see getMyRingPeers and
44
45
  // filterByPartition below, which reuse this value.
45
- const blockCoord = await hashKey(new TextEncoder().encode(blockId));
46
+ const blockCoord = await hashKey(routingKeyForBlock(blockId));
46
47
  // 1. Try my transaction ring peers first
47
48
  const myPeers = this.getMyRingPeers(blockCoord);
48
49
  const myRingDepth = this.getMyRingDepth();
@@ -1 +1 @@
1
- {"version":3,"file":"restoration-coordinator.js","sourceRoot":"","sources":["../../../src/storage/restoration-coordinator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"restoration-coordinator.js","sourceRoot":"","sources":["../../../src/storage/restoration-coordinator.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ring-shift-coordinator.d.ts","sourceRoot":"","sources":["../../../src/storage/ring-shift-coordinator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAOvD;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACpC,iBAAiB,CAChB,QAAQ,EAAE,MAAM,EAAE,EAClB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC7B,KAAK,EAAE,MAAM,GACX,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,aAAa;IAC7B,WAAW,EAAE,oBAAoB,CAAC;IAClC,YAAY,EAAE,YAAY,CAAC;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,4EAA4E;IAC5E,SAAS,EAAE,oBAAoB,CAAC;IAChC,8FAA8F;IAC9F,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC;IACnB,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB;;;;OAIG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wFAAwF;AACxF,MAAM,MAAM,YAAY,GACrB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACrE;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,oBAAoB;IAM/B,OAAO,CAAC,QAAQ,CAAC,IAAI;IALtB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,yFAAyF;IACzF,OAAO,CAAC,QAAQ,CAAS;gBAGP,IAAI,EAAE,aAAa,EACpC,MAAM,GAAE,eAAoB;IAK7B;;;;OAIG;IACG,YAAY,CAAC,UAAU,EAAE;QAAE,SAAS,EAAE,IAAI,GAAG,KAAK,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAmBxG;;;;;;OAMG;IACH,gBAAgB,IAAI;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE;YAiB7B,OAAO;IAgCrB;;;OAGG;YACW,gBAAgB;IAiB9B;;;OAGG;YACW,iBAAiB;IAc/B;;;;;OAKG;YACW,cAAc;YAkBd,MAAM;IAapB,wFAAwF;IACxF,OAAO,CAAC,QAAQ;IAkBhB,kGAAkG;IAClG,OAAO,CAAC,SAAS;CAIjB"}
1
+ {"version":3,"file":"ring-shift-coordinator.d.ts","sourceRoot":"","sources":["../../../src/storage/ring-shift-coordinator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EAAE,oBAAoB,EAAiB,MAAM,6BAA6B,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMvD;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACpC,iBAAiB,CAChB,QAAQ,EAAE,MAAM,EAAE,EAClB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC7B,KAAK,EAAE,MAAM,GACX,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,aAAa;IAC7B,WAAW,EAAE,oBAAoB,CAAC;IAClC,YAAY,EAAE,YAAY,CAAC;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,4EAA4E;IAC5E,SAAS,EAAE,oBAAoB,CAAC;IAChC,8FAA8F;IAC9F,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC;IACnB,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB;;;;OAIG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,eAAe;IAC/B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wFAAwF;AACxF,MAAM,MAAM,YAAY,GACrB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACrE;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,oBAAoB;IAM/B,OAAO,CAAC,QAAQ,CAAC,IAAI;IALtB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,yFAAyF;IACzF,OAAO,CAAC,QAAQ,CAAS;gBAGP,IAAI,EAAE,aAAa,EACpC,MAAM,GAAE,eAAoB;IAK7B;;;;OAIG;IACG,YAAY,CAAC,UAAU,EAAE;QAAE,SAAS,EAAE,IAAI,GAAG,KAAK,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAmBxG;;;;;;OAMG;IACH,gBAAgB,IAAI;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE;YAiB7B,OAAO;IAgCrB;;;OAGG;YACW,gBAAgB;IAiB9B;;;OAGG;YACW,iBAAiB;IAc/B;;;;;OAKG;YACW,cAAc;YAkBd,MAAM;IAapB,wFAAwF;IACxF,OAAO,CAAC,QAAQ;IAkBhB,kGAAkG;IAClG,OAAO,CAAC,SAAS;CAIjB"}
@@ -1,8 +1,8 @@
1
1
  import { hashKey } from 'p2p-fret';
2
+ import { routingKeyForBlock } from '@optimystic/db-core';
2
3
  import { partitionCovers, qualifiesForFloor } from './arachnode-partition.js';
3
4
  import { createLogger } from '../logger.js';
4
5
  const log = createLogger('ring-shift');
5
- const textEncoder = new TextEncoder();
6
6
  /**
7
7
  * Drives a single damped ring transition through the **advertise → confirm-replication → release**
8
8
  * handoff (`docs/arachnode-ring-handoff.md` § Part 2), so a ring shift never drops a key below its
@@ -127,7 +127,7 @@ export class RingShiftCoordinator {
127
127
  async computeShedBlocks(oldPartition, newPartition) {
128
128
  const shed = [];
129
129
  for (const blockId of this.deps.ownedBlocks) {
130
- const coord = await hashKey(textEncoder.encode(blockId));
130
+ const coord = await hashKey(routingKeyForBlock(blockId));
131
131
  if (partitionCovers(oldPartition, coord) && !partitionCovers(newPartition, coord)) {
132
132
  shed.push(blockId);
133
133
  }
@@ -144,7 +144,7 @@ export class RingShiftCoordinator {
144
144
  const owners = new Map();
145
145
  const want = floor + 1 + this.candidateMargin; // headroom for self + excluded movers
146
146
  for (const blockId of shed) {
147
- const coord = await hashKey(textEncoder.encode(blockId));
147
+ const coord = await hashKey(routingKeyForBlock(blockId));
148
148
  const cohort = this.deps.fret.assembleCohort(coord, want);
149
149
  const qualifying = cohort.filter(peerId => {
150
150
  if (peerId === this.deps.selfPeerId)