@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.
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 +126 -6
  17. package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
  18. package/dist/src/cluster/cluster-repo.js +378 -50
  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 +77 -5
  112. package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
  113. package/dist/src/repo/cluster-coordinator.js +131 -20
  114. package/dist/src/repo/cluster-coordinator.js.map +1 -1
  115. package/dist/src/repo/coordinator-repo.d.ts +238 -122
  116. package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
  117. package/dist/src/repo/coordinator-repo.js +625 -472
  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 +422 -56
  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 +145 -19
  217. package/src/repo/coordinator-repo.ts +652 -505
  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
@@ -300,8 +300,8 @@ function isVoteMap(value: unknown): value is Record<string, Signature> {
300
300
  * Count distinct `approve` votes over `hash` from signers inside `peerSet`, verifying each signature
301
301
  * against the Ed25519 key its peer id names. Per-entry rules (the spec's step 5/6):
302
302
  *
303
- * - a non-`approve` vote is ignored silently (rejects/conflicts are part of the signed record but
304
- * never count toward approval);
303
+ * - a non-`approve` vote is ignored silently (rejects and the two transient refusals, `conflict` and
304
+ * `held`, are part of the signed record but never count toward approval);
305
305
  * - a signer outside `peerSet` is skipped and noted (`sawUnknownSigner`) — the caller downgrades a
306
306
  * failed threshold to `unknown-signer`;
307
307
  * - a signer inside `peerSet` whose id is not a valid Ed25519 peer id → immediate
@@ -98,9 +98,11 @@ export function resolveRace(existing: ClusterRecord, incoming: ClusterRecord): '
98
98
 
99
99
  /**
100
100
  * Aged advisory priority carried by a record's pend operation, clamped to [0, MaxPriority].
101
- * The multi-collection path carries it on `pend.validation.transaction.priority`; the single-collection
102
- * (`Collection.sync`) path carries it as top-level `pend.priority`; a record with neither — a
103
- * legacy/unversioned coordinator's transaction, or a non-pend operationis priority 0
101
+ * A validated multi-collection pend carries it on `pend.validation.transaction.priority`; a pend
102
+ * without a transaction — the single-collection (`Collection.sync`) path, and a coordinator built
103
+ * with `pendValidation: 'none'` (the Quereus adapter's legacy multi-tree commit)carries it as
104
+ * top-level `pend.priority`; a record with neither — an unversioned coordinator's transaction, or a
105
+ * non-pend operation — is priority 0
104
106
  * (backward compatible: such transactions simply never age). Both carriers live inside the signed
105
107
  * `message`, so priority is integrity-protected in transit; clamping here bounds a self-asserted
106
108
  * out-of-range value to the cap.
@@ -126,10 +128,52 @@ export function recordPriority(record: ClusterRecord): number {
126
128
  }
127
129
 
128
130
  /**
129
- * Whether two messages must serialize against each other: true when they touch a common block AND
130
- * are not the same action. The same-action escape is what lets a commit follow its own pend — both
131
- * name every block the action writes, so a bare overlap test would have each transaction blocking
132
- * its own next phase. Gates whether {@link resolveRace} runs at all.
131
+ * Whether two messages must serialize against each other: true when they touch a common block, are
132
+ * not the same action, and neither is cancel-only. The same-action escape is what lets a commit
133
+ * follow its own pend — both name every block the action writes, so a bare overlap test would have
134
+ * each transaction blocking its own next phase. Gates whether {@link resolveRace} runs at all.
135
+ *
136
+ * A cancel-only message commutes with every message of a different action, so it never conflicts.
137
+ * Cancelling action X only deletes X's pending records on the named blocks (`StorageRepo.cancel`); it
138
+ * never moves a block's revision, so it reorders nobody's history:
139
+ * - a commit of Y never reads X's pending record (that was checked at Y's pend);
140
+ * - a pend of Y is refused by storage and by `validatePendOperations` while X's record stands, in
141
+ * either arrival order — the worst outcome is a retry of Y, never a wrong result;
142
+ * - an invalidation writes compensating revisions and does not touch pending records.
143
+ * Counting the cancel as a rival was actively harmful: on a two-member cohort a single conflict vote
144
+ * makes super-majority unreachable, so a refused writer's cancel knocked out the WINNER's commit after
145
+ * its log tail had landed, and the winner tore. It also let a pend or commit abort a cancel's own
146
+ * reservation, leaving the refused pending records standing longer.
147
+ *
148
+ * A commit-only message competes with nothing but an invalidation. A commit is only ever sent for an
149
+ * action whose pend already WON its slot (the race above ran at the pend, and storage holds that
150
+ * pend's record); the commit only promotes that record, so there is no contest left for it to lose:
151
+ * - a pend of Y: storage and `validatePendOperations` refuse it while X's record stands and Y has
152
+ * not built on it (`isReservationAgainst`: Y asks for X's slot or an earlier one, or — at the vote
153
+ * of a cohort that can leave a member out — the base Y declares for the block is below X's slot),
154
+ * and refuse it as stale once X has committed
155
+ * there — the worst outcome is a retry of Y. A Y that built on X (it read the block, and
156
+ * `StorageRepo.get` promotes X's record for a reader whose log names X) lands after X: Y's pend
157
+ * declares X's revision as its base, and a member X has not reached yet refuses Y as behind (the
158
+ * fork guard in `StorageRepo.internalCommit`) and reconciles, rather than applying Y over the older
159
+ * base. That guard reads the base Y's pend carried for the block (`PendRequest.baseRevs`, stored
160
+ * with the record) and falls back to the base Y's commit declared. A Y that read the block WITHOUT
161
+ * X's change — from four members up, from a member that never received X's pend — declares the
162
+ * pre-X base, and every member still holding X's record holds it at the vote, however far past
163
+ * X's slot Y asks (that shape needs a member outside X's promise quorum, which is exactly where
164
+ * the vote reads Y's base — `cohortCanMissAPend`). What neither closes is a Y from a sender that names no base at all (an older build;
165
+ * accepted as the residual, see docs/internals.md "An update-only transform is applied only to
166
+ * the base its author read"). Counting the commit as a rival never closed any of these: it only
167
+ * fired while X's commit was still in its own promise round at a member, and when the race went
168
+ * Y's way it tore X instead;
169
+ * - a commit of Y: `StorageRepo.commit` never looks at another action's pending record; its own
170
+ * stale and fork checks, and `validateCommitRevisions` at the vote, order the two under the block
171
+ * latch.
172
+ * Counting either as a rival was the same tear as the cancel's, one step later: on a two-member cohort
173
+ * a writer whose log tail had just landed had its data-block commit knocked out by the NEXT writer's
174
+ * pend (which had read, and was building on, exactly that commit), so the next writer's revision
175
+ * landed over a member that never took the first one, and the first writer tore. An invalidation
176
+ * still serializes against a commit: it writes compensating revisions to the same blocks.
133
177
  */
134
178
  export function operationsConflict(ops1: RepoMessage['operations'], ops2: RepoMessage['operations']): boolean {
135
179
  // Check if one is a commit for the same action as a pend - these don't conflict
@@ -140,6 +184,14 @@ export function operationsConflict(ops1: RepoMessage['operations'], ops2: RepoMe
140
184
  return false;
141
185
  }
142
186
 
187
+ if (isCancelOnly(ops1) || isCancelOnly(ops2)) {
188
+ return false;
189
+ }
190
+
191
+ if ((isCommitOnly(ops1) && !invalidates(ops2)) || (isCommitOnly(ops2) && !invalidates(ops1))) {
192
+ return false;
193
+ }
194
+
143
195
  const blocks1 = new Set(getAffectedBlockIds(ops1));
144
196
  const blocks2 = new Set(getAffectedBlockIds(ops2));
145
197
 
@@ -156,3 +208,20 @@ export function operationsConflict(ops1: RepoMessage['operations'], ops2: RepoMe
156
208
 
157
209
  return false;
158
210
  }
211
+
212
+ /**
213
+ * Every operation is a cancel. Stated over the whole list, although a `RepoMessage` carries one
214
+ * operation in practice, so a mixed message stays conservative and keeps conflicting.
215
+ */
216
+ function isCancelOnly(operations: RepoMessage['operations']): boolean {
217
+ return operations.length > 0 && operations.every(operation => 'cancel' in operation);
218
+ }
219
+
220
+ /** Every operation is a commit — conservative on a mixed list, like {@link isCancelOnly}. */
221
+ function isCommitOnly(operations: RepoMessage['operations']): boolean {
222
+ return operations.length > 0 && operations.every(operation => 'commit' in operation);
223
+ }
224
+
225
+ function invalidates(operations: RepoMessage['operations']): boolean {
226
+ return operations.some(operation => 'invalidate' in operation);
227
+ }