@optimystic/db-p2p 0.24.2 → 0.25.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 (249) hide show
  1. package/{readme.md → README.md} +688 -668
  2. package/dist/src/cluster/block-transfer-service.d.ts +133 -10
  3. package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
  4. package/dist/src/cluster/block-transfer-service.js +155 -9
  5. package/dist/src/cluster/block-transfer-service.js.map +1 -1
  6. package/dist/src/cluster/block-transfer.d.ts +67 -7
  7. package/dist/src/cluster/block-transfer.d.ts.map +1 -1
  8. package/dist/src/cluster/block-transfer.js +127 -24
  9. package/dist/src/cluster/block-transfer.js.map +1 -1
  10. package/dist/src/cluster/certified-claims.d.ts +170 -0
  11. package/dist/src/cluster/certified-claims.d.ts.map +1 -0
  12. package/dist/src/cluster/certified-claims.js +200 -0
  13. package/dist/src/cluster/certified-claims.js.map +1 -0
  14. package/dist/src/cluster/client-signature-verifier.d.ts +23 -0
  15. package/dist/src/cluster/client-signature-verifier.d.ts.map +1 -0
  16. package/dist/src/cluster/client-signature-verifier.js +33 -0
  17. package/dist/src/cluster/client-signature-verifier.js.map +1 -0
  18. package/dist/src/cluster/cluster-policy.d.ts +9 -3
  19. package/dist/src/cluster/cluster-policy.d.ts.map +1 -1
  20. package/dist/src/cluster/cluster-policy.js +111 -27
  21. package/dist/src/cluster/cluster-policy.js.map +1 -1
  22. package/dist/src/cluster/cluster-repo.d.ts +140 -11
  23. package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
  24. package/dist/src/cluster/cluster-repo.js +485 -29
  25. package/dist/src/cluster/cluster-repo.js.map +1 -1
  26. package/dist/src/cluster/commit-proof.d.ts +134 -0
  27. package/dist/src/cluster/commit-proof.d.ts.map +1 -0
  28. package/dist/src/cluster/commit-proof.js +263 -0
  29. package/dist/src/cluster/commit-proof.js.map +1 -0
  30. package/dist/src/cluster/quorum-restore.d.ts +95 -8
  31. package/dist/src/cluster/quorum-restore.d.ts.map +1 -1
  32. package/dist/src/cluster/quorum-restore.js +113 -14
  33. package/dist/src/cluster/quorum-restore.js.map +1 -1
  34. package/dist/src/cluster/rebalance-monitor.d.ts +84 -0
  35. package/dist/src/cluster/rebalance-monitor.d.ts.map +1 -1
  36. package/dist/src/cluster/rebalance-monitor.js +207 -5
  37. package/dist/src/cluster/rebalance-monitor.js.map +1 -1
  38. package/dist/src/cluster/reconcile-block.d.ts +27 -7
  39. package/dist/src/cluster/reconcile-block.d.ts.map +1 -1
  40. package/dist/src/cluster/reconcile-block.js +179 -38
  41. package/dist/src/cluster/reconcile-block.js.map +1 -1
  42. package/dist/src/cluster/service.d.ts +13 -4
  43. package/dist/src/cluster/service.d.ts.map +1 -1
  44. package/dist/src/cluster/service.js +17 -18
  45. package/dist/src/cluster/service.js.map +1 -1
  46. package/dist/src/cluster/spread-on-churn.d.ts +8 -2
  47. package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
  48. package/dist/src/cluster/spread-on-churn.js +7 -7
  49. package/dist/src/cluster/spread-on-churn.js.map +1 -1
  50. package/dist/src/cohort-topic/host.d.ts.map +1 -1
  51. package/dist/src/cohort-topic/host.js +8 -7
  52. package/dist/src/cohort-topic/host.js.map +1 -1
  53. package/dist/src/cohort-topic/stream-util.d.ts +7 -6
  54. package/dist/src/cohort-topic/stream-util.d.ts.map +1 -1
  55. package/dist/src/cohort-topic/stream-util.js +14 -41
  56. package/dist/src/cohort-topic/stream-util.js.map +1 -1
  57. package/dist/src/dispute/cascade.d.ts +7 -8
  58. package/dist/src/dispute/cascade.d.ts.map +1 -1
  59. package/dist/src/dispute/cascade.js +24 -7
  60. package/dist/src/dispute/cascade.js.map +1 -1
  61. package/dist/src/dispute/dispute-service.d.ts +5 -0
  62. package/dist/src/dispute/dispute-service.d.ts.map +1 -1
  63. package/dist/src/dispute/dispute-service.js +13 -3
  64. package/dist/src/dispute/dispute-service.js.map +1 -1
  65. package/dist/src/dispute/invalidation.d.ts +33 -15
  66. package/dist/src/dispute/invalidation.d.ts.map +1 -1
  67. package/dist/src/dispute/invalidation.js +127 -34
  68. package/dist/src/dispute/invalidation.js.map +1 -1
  69. package/dist/src/dispute/service.d.ts.map +1 -1
  70. package/dist/src/dispute/service.js +2 -1
  71. package/dist/src/dispute/service.js.map +1 -1
  72. package/dist/src/index.d.ts +7 -0
  73. package/dist/src/index.d.ts.map +1 -1
  74. package/dist/src/index.js +7 -0
  75. package/dist/src/index.js.map +1 -1
  76. package/dist/src/libp2p-key-network.d.ts +14 -10
  77. package/dist/src/libp2p-key-network.d.ts.map +1 -1
  78. package/dist/src/libp2p-key-network.js +28 -58
  79. package/dist/src/libp2p-key-network.js.map +1 -1
  80. package/dist/src/libp2p-node-base.d.ts +38 -7
  81. package/dist/src/libp2p-node-base.d.ts.map +1 -1
  82. package/dist/src/libp2p-node-base.js +148 -63
  83. package/dist/src/libp2p-node-base.js.map +1 -1
  84. package/dist/src/network/open-protocol-stream.d.ts +56 -0
  85. package/dist/src/network/open-protocol-stream.d.ts.map +1 -0
  86. package/dist/src/network/open-protocol-stream.js +60 -0
  87. package/dist/src/network/open-protocol-stream.js.map +1 -0
  88. package/dist/src/network/register-protocol-handler.d.ts +66 -0
  89. package/dist/src/network/register-protocol-handler.d.ts.map +1 -0
  90. package/dist/src/network/register-protocol-handler.js +51 -0
  91. package/dist/src/network/register-protocol-handler.js.map +1 -0
  92. package/dist/src/peer-address-book.d.ts +60 -2
  93. package/dist/src/peer-address-book.d.ts.map +1 -1
  94. package/dist/src/peer-address-book.js +89 -1
  95. package/dist/src/peer-address-book.js.map +1 -1
  96. package/dist/src/pend-validation.d.ts +65 -0
  97. package/dist/src/pend-validation.d.ts.map +1 -0
  98. package/dist/src/pend-validation.js +69 -0
  99. package/dist/src/pend-validation.js.map +1 -0
  100. package/dist/src/reactivity/notify-transport.d.ts.map +1 -1
  101. package/dist/src/reactivity/notify-transport.js +2 -1
  102. package/dist/src/reactivity/notify-transport.js.map +1 -1
  103. package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -1
  104. package/dist/src/reactivity/push-state-gossip.js +2 -1
  105. package/dist/src/reactivity/push-state-gossip.js.map +1 -1
  106. package/dist/src/repo/cluster-coordinator.d.ts +32 -6
  107. package/dist/src/repo/cluster-coordinator.d.ts.map +1 -1
  108. package/dist/src/repo/cluster-coordinator.js +44 -10
  109. package/dist/src/repo/cluster-coordinator.js.map +1 -1
  110. package/dist/src/repo/coordinator-repo.d.ts +181 -25
  111. package/dist/src/repo/coordinator-repo.d.ts.map +1 -1
  112. package/dist/src/repo/coordinator-repo.js +650 -62
  113. package/dist/src/repo/coordinator-repo.js.map +1 -1
  114. package/dist/src/repo/served-repo-proxy.d.ts +30 -0
  115. package/dist/src/repo/served-repo-proxy.d.ts.map +1 -0
  116. package/dist/src/repo/served-repo-proxy.js +50 -0
  117. package/dist/src/repo/served-repo-proxy.js.map +1 -0
  118. package/dist/src/repo/service.d.ts +16 -1
  119. package/dist/src/repo/service.d.ts.map +1 -1
  120. package/dist/src/repo/service.js +18 -16
  121. package/dist/src/repo/service.js.map +1 -1
  122. package/dist/src/reputation/types.d.ts +3 -1
  123. package/dist/src/reputation/types.d.ts.map +1 -1
  124. package/dist/src/reputation/types.js +3 -1
  125. package/dist/src/reputation/types.js.map +1 -1
  126. package/dist/src/rn.d.ts +24 -2
  127. package/dist/src/rn.d.ts.map +1 -1
  128. package/dist/src/rn.js +33 -4
  129. package/dist/src/rn.js.map +1 -1
  130. package/dist/src/storage/block-archive.d.ts +153 -0
  131. package/dist/src/storage/block-archive.d.ts.map +1 -0
  132. package/dist/src/storage/block-archive.js +194 -0
  133. package/dist/src/storage/block-archive.js.map +1 -0
  134. package/dist/src/storage/block-latch.d.ts +92 -0
  135. package/dist/src/storage/block-latch.d.ts.map +1 -0
  136. package/dist/src/storage/block-latch.js +132 -0
  137. package/dist/src/storage/block-latch.js.map +1 -0
  138. package/dist/src/storage/block-storage.d.ts +169 -12
  139. package/dist/src/storage/block-storage.d.ts.map +1 -1
  140. package/dist/src/storage/block-storage.js +415 -152
  141. package/dist/src/storage/block-storage.js.map +1 -1
  142. package/dist/src/storage/cached-raw-storage.d.ts +5 -1
  143. package/dist/src/storage/cached-raw-storage.d.ts.map +1 -1
  144. package/dist/src/storage/cached-raw-storage.js +16 -1
  145. package/dist/src/storage/cached-raw-storage.js.map +1 -1
  146. package/dist/src/storage/cached-store-driver.d.ts +14 -4
  147. package/dist/src/storage/cached-store-driver.d.ts.map +1 -1
  148. package/dist/src/storage/cached-store-driver.js +39 -5
  149. package/dist/src/storage/cached-store-driver.js.map +1 -1
  150. package/dist/src/storage/i-block-storage.d.ts +70 -19
  151. package/dist/src/storage/i-block-storage.d.ts.map +1 -1
  152. package/dist/src/storage/i-block-storage.js +21 -1
  153. package/dist/src/storage/i-block-storage.js.map +1 -1
  154. package/dist/src/storage/i-raw-storage.d.ts +38 -0
  155. package/dist/src/storage/i-raw-storage.d.ts.map +1 -1
  156. package/dist/src/storage/kv-raw-storage.d.ts +14 -8
  157. package/dist/src/storage/kv-raw-storage.d.ts.map +1 -1
  158. package/dist/src/storage/kv-raw-storage.js +29 -9
  159. package/dist/src/storage/kv-raw-storage.js.map +1 -1
  160. package/dist/src/storage/memory-store-driver.d.ts +4 -1
  161. package/dist/src/storage/memory-store-driver.d.ts.map +1 -1
  162. package/dist/src/storage/memory-store-driver.js +22 -2
  163. package/dist/src/storage/memory-store-driver.js.map +1 -1
  164. package/dist/src/storage/raw-store-codec.js +2 -2
  165. package/dist/src/storage/raw-store-driver.d.ts +44 -3
  166. package/dist/src/storage/raw-store-driver.d.ts.map +1 -1
  167. package/dist/src/storage/shared-cache-pool.d.ts +60 -3
  168. package/dist/src/storage/shared-cache-pool.d.ts.map +1 -1
  169. package/dist/src/storage/shared-cache-pool.js +68 -4
  170. package/dist/src/storage/shared-cache-pool.js.map +1 -1
  171. package/dist/src/storage/storage-repo.d.ts +204 -26
  172. package/dist/src/storage/storage-repo.d.ts.map +1 -1
  173. package/dist/src/storage/storage-repo.js +422 -119
  174. package/dist/src/storage/storage-repo.js.map +1 -1
  175. package/dist/src/storage/store-identity.d.ts +21 -0
  176. package/dist/src/storage/store-identity.d.ts.map +1 -0
  177. package/dist/src/storage/store-identity.js +33 -0
  178. package/dist/src/storage/store-identity.js.map +1 -0
  179. package/dist/src/storage/struct.d.ts +15 -0
  180. package/dist/src/storage/struct.d.ts.map +1 -1
  181. package/dist/src/storage/with-read-cache.d.ts +92 -0
  182. package/dist/src/storage/with-read-cache.d.ts.map +1 -0
  183. package/dist/src/storage/with-read-cache.js +132 -0
  184. package/dist/src/storage/with-read-cache.js.map +1 -0
  185. package/dist/src/sync/service.d.ts +13 -3
  186. package/dist/src/sync/service.d.ts.map +1 -1
  187. package/dist/src/sync/service.js +7 -30
  188. package/dist/src/sync/service.js.map +1 -1
  189. package/dist/src/testing/mesh-harness.d.ts +75 -2
  190. package/dist/src/testing/mesh-harness.d.ts.map +1 -1
  191. package/dist/src/testing/mesh-harness.js +193 -81
  192. package/dist/src/testing/mesh-harness.js.map +1 -1
  193. package/dist/src/testing/raw-storage-conformance.d.ts +8 -0
  194. package/dist/src/testing/raw-storage-conformance.d.ts.map +1 -1
  195. package/dist/src/testing/raw-storage-conformance.js +97 -2
  196. package/dist/src/testing/raw-storage-conformance.js.map +1 -1
  197. package/package.json +5 -6
  198. package/src/cluster/block-transfer-service.ts +528 -312
  199. package/src/cluster/block-transfer.ts +547 -424
  200. package/src/cluster/certified-claims.ts +319 -0
  201. package/src/cluster/client-signature-verifier.ts +34 -0
  202. package/src/cluster/cluster-policy.ts +294 -203
  203. package/src/cluster/cluster-repo.ts +2501 -2034
  204. package/src/cluster/commit-proof.ts +344 -0
  205. package/src/cluster/quorum-restore.ts +348 -223
  206. package/src/cluster/rebalance-monitor.ts +539 -254
  207. package/src/cluster/reconcile-block.ts +404 -203
  208. package/src/cluster/service.ts +23 -20
  209. package/src/cluster/spread-on-churn.ts +352 -346
  210. package/src/cohort-topic/host.ts +8 -7
  211. package/src/cohort-topic/stream-util.ts +14 -43
  212. package/src/dispute/cascade.ts +31 -15
  213. package/src/dispute/dispute-service.ts +706 -696
  214. package/src/dispute/invalidation.ts +162 -52
  215. package/src/dispute/service.ts +126 -125
  216. package/src/index.ts +7 -0
  217. package/src/libp2p-key-network.ts +1204 -1235
  218. package/src/libp2p-node-base.ts +185 -70
  219. package/src/network/open-protocol-stream.ts +87 -0
  220. package/src/network/register-protocol-handler.ts +85 -0
  221. package/src/peer-address-book.ts +96 -2
  222. package/src/pend-validation.ts +89 -0
  223. package/src/reactivity/notify-transport.ts +2 -1
  224. package/src/reactivity/push-state-gossip.ts +2 -1
  225. package/src/repo/cluster-coordinator.ts +65 -11
  226. package/src/repo/coordinator-repo.ts +729 -71
  227. package/src/repo/served-repo-proxy.ts +55 -0
  228. package/src/repo/service.ts +25 -16
  229. package/src/reputation/types.ts +3 -1
  230. package/src/rn.ts +34 -4
  231. package/src/storage/block-archive.ts +242 -0
  232. package/src/storage/block-latch.ts +144 -0
  233. package/src/storage/block-storage.ts +787 -498
  234. package/src/storage/cached-raw-storage.ts +21 -1
  235. package/src/storage/cached-store-driver.ts +898 -859
  236. package/src/storage/i-block-storage.ts +172 -116
  237. package/src/storage/i-raw-storage.ts +40 -0
  238. package/src/storage/kv-raw-storage.ts +34 -9
  239. package/src/storage/memory-store-driver.ts +26 -2
  240. package/src/storage/raw-store-codec.ts +42 -42
  241. package/src/storage/raw-store-driver.ts +45 -3
  242. package/src/storage/shared-cache-pool.ts +516 -452
  243. package/src/storage/storage-repo.ts +1421 -1014
  244. package/src/storage/store-identity.ts +41 -0
  245. package/src/storage/struct.ts +52 -34
  246. package/src/storage/with-read-cache.ts +182 -0
  247. package/src/sync/service.ts +178 -198
  248. package/src/testing/mesh-harness.ts +524 -344
  249. package/src/testing/raw-storage-conformance.ts +114 -2
@@ -1,5 +1,8 @@
1
+ import { canonicalBlockHash } from "@optimystic/db-core";
2
+ import { maxArchiveRevision } from "../storage/block-archive.js";
1
3
  import { PenaltyReason } from "../reputation/types.js";
2
- import { selectQuorumRev, selectQuorumBlock, canonicalBlockHash, corroboratorCapacity, quorumSize } from "./quorum-restore.js";
4
+ import { selectQuorumRev, selectQuorumBlock, corroboratorCapacity, quorumSize, certifiedEquivocation, certifiedContentEquivocation } from "./quorum-restore.js";
5
+ import { certifyClaim, certifyContent, isAttributableProofFailure, proofThresholds } from "./certified-claims.js";
3
6
  import { createLogger } from '../logger.js';
4
7
  const log = createLogger('reconcile-block');
5
8
  /**
@@ -9,35 +12,22 @@ const log = createLogger('reconcile-block');
9
12
  * path (`CoordinatorRepo.restoreCorroborated` — a stall there holds up a caller's `get`).
10
13
  */
11
14
  export const RECONCILE_TIMEOUT_MS = 5000;
12
- /**
13
- * Highest revision an archive covers. Keys arrive as strings off the wire from an untrusted peer,
14
- * so a non-numeric one is skipped rather than poisoning the maximum with `NaN`; folding instead of
15
- * `Math.max(...keys)` also keeps a wide archive off the argument-count limit.
16
- */
17
- function maxRevision(revisions) {
18
- let max;
19
- for (const key of Object.keys(revisions)) {
20
- const rev = Number(key);
21
- if (Number.isFinite(rev) && (max === undefined || rev > max))
22
- max = rev;
23
- }
24
- return max;
25
- }
26
15
  /**
27
16
  * The claim a peer's archive makes: its highest revision, provided that revision is at least the
28
- * one we committed. `undefined` when the peer served nothing usable (unreachable, empty archive,
29
- * or only revisions older than the commit we are healing).
17
+ * one we committed. `undefined` when the archive carries only revisions older than the commit we are
18
+ * healing, or no usable action at its highest.
30
19
  */
31
20
  function toCandidate(peerId, archive, committedRev) {
32
- if (!archive)
33
- return undefined;
34
- const maxRev = maxRevision(archive.revisions);
21
+ const maxRev = maxArchiveRevision(archive.revisions);
35
22
  if (maxRev === undefined || maxRev < committedRev)
36
23
  return undefined;
37
24
  const data = archive.revisions[maxRev];
38
25
  if (!data?.action)
39
26
  return undefined;
40
- return { peerId, rev: maxRev, actionId: data.action.actionId, block: data.block };
27
+ return {
28
+ peerId, rev: maxRev, actionId: data.action.actionId, block: data.block,
29
+ ...(data.proof ? { proof: data.proof } : {})
30
+ };
41
31
  }
42
32
  /**
43
33
  * One peer's answer, isolated. `fetchArchive` is contracted to answer `undefined` for an
@@ -45,25 +35,117 @@ function toCandidate(peerId, archive, committedRev) {
45
35
  * discard the answers every other peer already gave — turning a heal the cohort could complete
46
36
  * into a decline. One peer's failure costs only that peer's vote.
47
37
  */
48
- async function fetchCandidate(deps, peerId, blockId, committedRev) {
38
+ async function fetchAnswer(deps, peerId, blockId, committedRev) {
39
+ let archive;
49
40
  try {
50
- return toCandidate(peerId, await deps.fetchArchive(peerId, blockId), committedRev);
41
+ archive = await deps.fetchArchive(peerId, blockId);
51
42
  }
52
43
  catch (err) {
53
44
  log('reconcile:fetch-error', { blockId, peerId, error: err.message });
54
- return undefined;
45
+ return { kind: 'error' };
55
46
  }
47
+ if (!archive)
48
+ return { kind: 'no-archive' };
49
+ const candidate = toCandidate(peerId, archive, committedRev);
50
+ return candidate ? { kind: 'claim', candidate } : { kind: 'behind' };
56
51
  }
57
52
  /**
58
- * Hash the block bytes of every candidate that both corroborates `selected` and actually carried content.
53
+ * Run every proof-carrying candidate through the shared certification layer
54
+ * (`cluster/certified-claims.ts`) and inject the verdicts, BEFORE selection reads the claim set.
55
+ * Mirrors the read path's certifyClaim pass (`CoordinatorRepo.queryClusterForLatest`) — same
56
+ * thresholds, same failure logging, same penalty discipline:
57
+ *
58
+ * - A candidate whose claim half fails stays an ORDINARY uncertified corroborator (its vote is
59
+ * never dropped — a peer that could fabricate a bad proof could equally have sent none), and
60
+ * only an attributable failure (`isAttributableProofFailure`) penalizes the serving peer.
61
+ * - `digest-mismatch` is the one content-side rejection: the served bytes provably contradict
62
+ * the proof's declared digest, so the candidate is dropped from the content quorum and the
63
+ * server penalized — while its (genuinely verified) rev claim still counts.
64
+ * - `no-digest-declared` leaves the content an ordinary uncertified carrier: the cohort declared
65
+ * nothing to compare against, which is a verdict, never misbehavior.
66
+ *
67
+ * NOTE: cost is one verification pass per proof-carrying answer per reconcile, each bounded by
68
+ * MAX_PROOF_SIGNERS (256, the shared layer's cap) signature checks × cohort width — fine at
69
+ * deployment cohort sizes (~10).
70
+ */
71
+ async function certifyCandidates(deps, blockId, candidates) {
72
+ // Shared with the read path, so the two cannot drift on what the members actually enforced —
73
+ // see `proofThresholds` for why the simple-majority term is not deps.simpleMajorityThreshold.
74
+ const thresholds = proofThresholds(deps.superMajorityThreshold);
75
+ await Promise.all(candidates.map(async (c) => {
76
+ if (!c.proof)
77
+ return;
78
+ const claim = { blockId, rev: c.rev, actionId: c.actionId };
79
+ if (c.block) {
80
+ const verdict = await certifyContent(c.proof, claim, c.block, thresholds, deps.anchoring);
81
+ if (verdict.revCertified) {
82
+ c.revCertified = true;
83
+ if (verdict.contentCertified) {
84
+ c.contentCertified = true;
85
+ }
86
+ else if (verdict.failure === 'digest-mismatch') {
87
+ // The claim half genuinely passed; the bytes provably lie. Drop them from the
88
+ // content quorum and penalize the server — repair continues on the other holders.
89
+ c.contentRejected = true;
90
+ log('reconcile:content-rejected', { blockId, peerId: c.peerId, rev: c.rev });
91
+ penalizeProofService(deps.reputation, c.peerId, blockId);
92
+ }
93
+ // no-digest-declared: content stays an ordinary uncertified carrier, no penalty.
94
+ return;
95
+ }
96
+ logUncertified(blockId, c, verdict.failure);
97
+ if (isAttributableProofFailure(verdict.failure)) {
98
+ penalizeProofService(deps.reputation, c.peerId, blockId);
99
+ }
100
+ return;
101
+ }
102
+ const verdict = await certifyClaim(c.proof, claim, thresholds, deps.anchoring);
103
+ if (verdict.certified) {
104
+ c.revCertified = true;
105
+ return;
106
+ }
107
+ logUncertified(blockId, c, verdict.failure);
108
+ if (isAttributableProofFailure(verdict.failure)) {
109
+ penalizeProofService(deps.reputation, c.peerId, blockId);
110
+ }
111
+ }));
112
+ }
113
+ /** Mirror of `cluster-fetch:proof-uncertified` on the read path — same fields, reconcile-side name. */
114
+ function logUncertified(blockId, c, failure) {
115
+ log('reconcile:proof-uncertified', { blockId, peerId: c.peerId, rev: c.rev, failure });
116
+ }
117
+ /**
118
+ * Best-effort penalty for a peer whose served proof (or the bytes served under it) provably lies.
119
+ * Mirrors `CoordinatorRepo.penalizeProofService` — never throws.
120
+ */
121
+ function penalizeProofService(reputation, peerId, blockId) {
122
+ if (!reputation)
123
+ return;
124
+ try {
125
+ reputation.reportPeer(peerId, PenaltyReason.InvalidRestoration, `reconcile:${blockId}`);
126
+ }
127
+ catch (err) {
128
+ log('reconcile:penalize-error', { blockId, error: err.message });
129
+ }
130
+ }
131
+ /**
132
+ * Hash the block bytes of every candidate that both corroborates `selected` and actually carried
133
+ * content — minus any whose bytes were rejected against their own proof's digest
134
+ * (`contentRejected`). A carrier whose content CERTIFIED carries its `certified` flag into the
135
+ * selector and its proof alongside: that is the only proof safe to persist, because it was
136
+ * verified against these exact bytes.
59
137
  *
60
138
  * NOTE: this canonical-JSON-serializes and sha256s every carrier's whole block on every reconcile.
61
139
  * Negligible at today's cohort widths and block sizes; if blocks grow large or cohorts wide enough
62
140
  * for this to show up on a commit-path profile, hash incrementally at receive time instead.
63
141
  */
64
142
  async function hashCarriers(candidates, selected) {
65
- const carriers = candidates.filter(c => c.rev === selected.rev && c.actionId === selected.actionId && c.block);
66
- return await Promise.all(carriers.map(async (c) => ({ peerId: c.peerId, hash: await canonicalBlockHash(c.block), block: c.block })));
143
+ const carriers = candidates.filter(c => c.rev === selected.rev && c.actionId === selected.actionId && c.block && !c.contentRejected);
144
+ return await Promise.all(carriers.map(async (c) => ({
145
+ peerId: c.peerId, hash: await canonicalBlockHash(c.block), block: c.block,
146
+ ...(c.contentCertified ? { certified: true } : {}),
147
+ ...(c.contentCertified && c.proof ? { proof: c.proof } : {})
148
+ })));
67
149
  }
68
150
  /** Report cohort members that served content contradicting the agreed hash. Best-effort; never throws. */
69
151
  function penalizeContradictingContent(reputation, candidates, agreedHash, blockId) {
@@ -88,9 +170,15 @@ function penalizeContradictingContent(reputation, candidates, agreedHash, blockI
88
170
  * corroboration rather than raw `Math.max` (a lone peer inflating its rev cannot steer
89
171
  * reconciliation), verifies the cohort agrees on the *content* at that revision, and persists it.
90
172
  *
91
- * Both quorums are capped by {@link corroboratorCapacity}: demanding two corroborators from a
92
- * cohort that contains exactly one other peer is a permanent deadlock, not a safety property
93
- * the node can never heal and stays unreadable forever.
173
+ * Peer-attached cohort commit proofs are verified first ({@link certifyCandidates}) and both gates
174
+ * weigh the verdicts: a claim and, separately, the bytes that a verified proof certifies is
175
+ * accepted with no second peer at any cohort size, and the proof that certified the bytes is
176
+ * persisted alongside them so the repaired replica serves it onward.
177
+ *
178
+ * Both quorums are capped by {@link corroboratorCapacity} for the claims that still need
179
+ * corroboration: demanding two corroborators from a cohort that contains exactly one other peer is
180
+ * a permanent deadlock, not a safety property — the node can never heal and stays unreadable
181
+ * forever.
94
182
  *
95
183
  * **Exposure at capacity 1 (documented, not accidental).** Block ids are random 256-bit strings
96
184
  * (`db-core` `structs.ts`), NOT content-addressed, so nothing on the receive path can re-derive
@@ -98,8 +186,12 @@ function penalizeContradictingContent(reputation, candidates, agreedHash, blockI
98
186
  * against `blockId`. A sole cohort peer's content is therefore believed on its word. That adds no
99
187
  * trust the cohort had not already extended — the same peer's `(rev, actionId)` claim is likewise
100
188
  * uncorroborable at that size (see `selectQuorumRev`'s capacity note), and a two-member cohort has
101
- * no honest majority to appeal to in the first place. Closing it needs commit-cert verification,
102
- * tracked by backlog `debt-read-repair-commit-cert-verification`.
189
+ * no honest majority to appeal to in the first place. It is closed for a candidate that carries a
190
+ * verified cohort commit proof — {@link certifyCandidates} binds the proof's declared digest to the
191
+ * served bytes, which is a check against the *cohort's own signatures* rather than against other
192
+ * peers, so a certified carrier wins the content gate outright and this exposure never applies to
193
+ * it. It remains open for a proof-less candidate, and for the residual that layer 1 proves only
194
+ * that the listed signers signed (`feat-cluster-membership-threshold-cert-anchoring`).
103
195
  *
104
196
  * Declines are cheap and retryable: nothing is persisted, nothing is marked, and the next commit
105
197
  * or churn/rebalance pass tries again.
@@ -109,25 +201,61 @@ export function createReconcileBlock(deps) {
109
201
  const targets = cohortPeerIds.filter(id => id !== deps.selfPeerId);
110
202
  if (targets.length === 0)
111
203
  return;
112
- const fetched = await Promise.all(targets.map(peerId => fetchCandidate(deps, peerId, blockId, committed.rev)));
113
- const candidates = fetched.filter((c) => c !== undefined);
204
+ const answers = await Promise.all(targets.map(peerId => fetchAnswer(deps, peerId, blockId, committed.rev)));
205
+ const candidates = answers.flatMap(a => a.kind === 'claim' ? [a.candidate] : []);
206
+ const tally = (kind) => answers.filter(a => a.kind === kind).length;
114
207
  const capacity = corroboratorCapacity(targets.length, deps.repairCorroborationClusterSize);
115
- const revClaims = candidates.map(({ peerId, rev, actionId }) => ({ peerId, rev, actionId }));
208
+ await certifyCandidates(deps, blockId, candidates);
209
+ const revClaims = candidates.map(({ peerId, rev, actionId, revCertified }) => ({
210
+ peerId, rev, actionId, ...(revCertified ? { certified: true } : {})
211
+ }));
116
212
  const selected = selectQuorumRev(revClaims, deps.simpleMajorityThreshold, capacity);
117
213
  if (!selected) {
214
+ // Asked ONLY on a decline: a certified-vs-certified conflict can coexist with a successful
215
+ // selection (a corroborated pair strictly above the top certified rev wins), so a
216
+ // non-undefined answer here explains THIS decline, nothing more. Two verified proofs for
217
+ // distinct actions at one revision means the cohort (or whoever holds its keys) provably
218
+ // signed both sides — an incident, not a shortage of answers; neither claimant is
219
+ // penalized, because which side is wrong is exactly what this node cannot know.
220
+ const equivocation = certifiedEquivocation(revClaims);
221
+ if (equivocation) {
222
+ log('reconcile:certified-equivocation', {
223
+ blockId, rev: equivocation.rev, actionIds: equivocation.actionIds
224
+ });
225
+ }
118
226
  // Leave the block behind; churn/rebalance and the next commit retry.
119
227
  log('reconcile:no-rev-quorum', {
120
228
  blockId,
121
229
  rev: committed.rev,
122
- responders: revClaims.length,
230
+ cohortPeers: targets.length,
231
+ holders: revClaims.length,
232
+ behind: tally('behind'),
233
+ noArchive: tally('no-archive'),
234
+ fetchErrors: tally('error'),
123
235
  required: quorumSize(revClaims.length, deps.simpleMajorityThreshold, capacity),
124
236
  repairCorroborationClusterSize: deps.repairCorroborationClusterSize
125
237
  });
126
238
  return;
127
239
  }
240
+ if (selected.certified) {
241
+ // Which rule won matters when reading a repair log: a certified selection may rest on a
242
+ // SINGLE claimant whose corroboration is the cohort's signature set, not other voters.
243
+ log('reconcile:certified-selected', {
244
+ blockId, rev: selected.rev, claimants: selected.supporters.length
245
+ });
246
+ }
128
247
  const hashCandidates = await hashCarriers(candidates, selected);
129
248
  const agreed = selectQuorumBlock(hashCandidates, deps.simpleMajorityThreshold, capacity);
130
249
  if (!agreed) {
250
+ // Two certified hashes at one (rev, actionId) means the cohort's keys signed two digests
251
+ // into one revision — a provable compromise an operator must be able to tell apart from a
252
+ // routine carrier shortfall; without this line the two declines log identically.
253
+ const equivocation = certifiedContentEquivocation(hashCandidates);
254
+ if (equivocation) {
255
+ log('reconcile:certified-content-equivocation', {
256
+ blockId, rev: selected.rev, hashes: equivocation.hashes
257
+ });
258
+ }
131
259
  log('reconcile:no-content-quorum', {
132
260
  blockId,
133
261
  rev: selected.rev,
@@ -137,8 +265,21 @@ export function createReconcileBlock(deps) {
137
265
  });
138
266
  return;
139
267
  }
140
- penalizeContradictingContent(deps.reputation, hashCandidates, agreed.hash, blockId);
141
- await deps.saveReplicatedBlock(blockId, agreed.block, { actionId: selected.actionId, rev: selected.rev });
268
+ // Detection is sound: selectQuorumBlock's certified branch fires iff exactly one distinct
269
+ // certified hash exists, so a defined `agreed` with a certified carrier at `agreed.hash`
270
+ // the certified rule won.
271
+ const certifiedCarrier = hashCandidates.find(c => c.certified === true && c.hash === agreed.hash);
272
+ // Contradicting-content penalties run ONLY on a corroborated win, mirroring the read path's
273
+ // rule (CoordinatorRepo.penalizeContradictingRevClaims): an unanchored proof must not be able
274
+ // to convict the honest cohort — anyone holding N keys can mint a proof that verifies, and
275
+ // penalizing dissenters against it would hand a forged proof a reputation lever. Revisit when
276
+ // certification is anchored to the block's derived cohort
277
+ // (`feat-cluster-membership-threshold-cert-anchoring`).
278
+ if (!certifiedCarrier) {
279
+ penalizeContradictingContent(deps.reputation, hashCandidates, agreed.hash, blockId);
280
+ }
281
+ // A corroboration-won heal with no certified carrier persists no proof — today's behavior.
282
+ await deps.saveReplicatedBlock(blockId, agreed.block, { actionId: selected.actionId, rev: selected.rev }, certifiedCarrier?.proof);
142
283
  log('reconcile:restored', { blockId, rev: selected.rev, actionId: selected.actionId });
143
284
  };
144
285
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile-block.js","sourceRoot":"","sources":["../../../src/cluster/reconcile-block.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reconcile-block.js","sourceRoot":"","sources":["../../../src/cluster/reconcile-block.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAGjE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACN,eAAe,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,UAAU,EACpE,qBAAqB,EAAE,4BAA4B,EAEnD,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,YAAY,EAAE,cAAc,EAAE,0BAA0B,EAAE,eAAe,EACzE,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,iBAAiB,CAAC,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAmFzC;;;;GAIG;AACH,SAAS,WAAW,CAAC,MAAc,EAAE,OAAqB,EAAE,YAAoB;IAC/E,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACrD,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,GAAG,YAAY;QAAE,OAAO,SAAS,CAAC;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,EAAE,MAAM;QAAE,OAAO,SAAS,CAAC;IACpC,OAAO;QACN,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK;QACtE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5C,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,WAAW,CACzB,IAAwB,EACxB,MAAc,EACd,OAAgB,EAChB,YAAoB;IAEpB,IAAI,OAAiC,CAAC;IACtC,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,uBAAuB,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QACjF,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC;IAC5C,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;IAC7D,OAAO,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACtE,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,KAAK,UAAU,iBAAiB,CAAC,IAAwB,EAAE,OAAgB,EAAE,UAAgC;IAC5G,6FAA6F;IAC7F,8FAA8F;IAC9F,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAChE,MAAM,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE;QAC1C,IAAI,CAAC,CAAC,CAAC,KAAK;YAAE,OAAO;QACrB,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAoB,EAAE,CAAC;QACxE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1F,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBAC1B,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC;gBACtB,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;oBAC9B,CAAC,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC3B,CAAC;qBAAM,IAAI,OAAO,CAAC,OAAO,KAAK,iBAAiB,EAAE,CAAC;oBAClD,8EAA8E;oBAC9E,kFAAkF;oBAClF,CAAC,CAAC,eAAe,GAAG,IAAI,CAAC;oBACzB,GAAG,CAAC,4BAA4B,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;oBAC7E,oBAAoB,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC1D,CAAC;gBACD,iFAAiF;gBACjF,OAAO;YACR,CAAC;YACD,cAAc,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,0BAA0B,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjD,oBAAoB,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC1D,CAAC;YACD,OAAO;QACR,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/E,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACvB,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC;YACtB,OAAO;QACR,CAAC;QACD,cAAc,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,0BAA0B,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,oBAAoB,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1D,CAAC;IACF,CAAC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,uGAAuG;AACvG,SAAS,cAAc,CAAC,OAAgB,EAAE,CAAqB,EAAE,OAAe;IAC/E,GAAG,CAAC,6BAA6B,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;AACxF,CAAC;AAED;;;GAGG;AACH,SAAS,oBAAoB,CAC5B,UAA2D,EAAE,MAAc,EAAE,OAAgB;IAE7F,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,IAAI,CAAC;QACJ,UAAU,CAAC,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,kBAAkB,EAAE,aAAa,OAAO,EAAE,CAAC,CAAC;IACzF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,0BAA0B,EAAE,EAAE,OAAO,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;AACF,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UAAU,YAAY,CAC1B,UAAgC,EAAE,QAAmB;IAErD,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACtC,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IAC9F,OAAO,MAAM,OAAO,CAAC,GAAG,CACvB,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAC,CAAC,EAAC,EAAE,CAAC,CAAC;QACxB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC,CAAC,CAAC,KAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAM;QAC3E,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,GAAG,CAAC,CAAC,CAAC,gBAAgB,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5D,CAAC,CAAC,CACH,CAAC;AACH,CAAC;AAED,0GAA0G;AAC1G,SAAS,4BAA4B,CACpC,UAA2D,EAC3D,UAAgC,EAChC,UAAkB,EAClB,OAAgB;IAEhB,IAAI,CAAC,UAAU;QAAE,OAAO;IACxB,IAAI,CAAC;QACJ,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC3B,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,kBAAkB,EAAE,aAAa,OAAO,EAAE,CAAC,CAAC;YAC3F,CAAC;QACF,CAAC;IACF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,0BAA0B,EAAE,EAAE,OAAO,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAwB;IAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,EAAE;QAClD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC;QACnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEjC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CACxE,CAAC;QACF,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACjF,MAAM,KAAK,GAAG,CAAC,IAAwB,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;QACxF,MAAM,QAAQ,GAAG,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,8BAA8B,CAAC,CAAC;QAE3F,MAAM,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAEnD,MAAM,SAAS,GAAe,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;YAC1F,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC,CAAC,CAAC;QACJ,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC;QACpF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,2FAA2F;YAC3F,kFAAkF;YAClF,yFAAyF;YACzF,yFAAyF;YACzF,kFAAkF;YAClF,gFAAgF;YAChF,MAAM,YAAY,GAAG,qBAAqB,CAAC,SAAS,CAAC,CAAC;YACtD,IAAI,YAAY,EAAE,CAAC;gBAClB,GAAG,CAAC,kCAAkC,EAAE;oBACvC,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,CAAC,SAAS;iBACjE,CAAC,CAAC;YACJ,CAAC;YACD,qEAAqE;YACrE,GAAG,CAAC,yBAAyB,EAAE;gBAC9B,OAAO;gBACP,GAAG,EAAE,SAAS,CAAC,GAAG;gBAClB,WAAW,EAAE,OAAO,CAAC,MAAM;gBAC3B,OAAO,EAAE,SAAS,CAAC,MAAM;gBACzB,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC;gBACvB,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;gBAC9B,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC;gBAC3B,QAAQ,EAAE,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,uBAAuB,EAAE,QAAQ,CAAC;gBAC9E,8BAA8B,EAAE,IAAI,CAAC,8BAA8B;aACnE,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACxB,wFAAwF;YACxF,uFAAuF;YACvF,GAAG,CAAC,8BAA8B,EAAE;gBACnC,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC,MAAM;aACjE,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,YAAY,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC;QACzF,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,yFAAyF;YACzF,0FAA0F;YAC1F,iFAAiF;YACjF,MAAM,YAAY,GAAG,4BAA4B,CAAC,cAAc,CAAC,CAAC;YAClE,IAAI,YAAY,EAAE,CAAC;gBAClB,GAAG,CAAC,0CAA0C,EAAE;oBAC/C,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM;iBACvD,CAAC,CAAC;YACJ,CAAC;YACD,GAAG,CAAC,6BAA6B,EAAE;gBAClC,OAAO;gBACP,GAAG,EAAE,QAAQ,CAAC,GAAG;gBACjB,QAAQ,EAAE,cAAc,CAAC,MAAM;gBAC/B,QAAQ,EAAE,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,uBAAuB,EAAE,QAAQ,CAAC;gBACnF,8BAA8B,EAAE,IAAI,CAAC,8BAA8B;aACnE,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,0FAA0F;QAC1F,2FAA2F;QAC3F,0BAA0B;QAC1B,MAAM,gBAAgB,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC;QAElG,4FAA4F;QAC5F,8FAA8F;QAC9F,2FAA2F;QAC3F,8FAA8F;QAC9F,0DAA0D;QAC1D,wDAAwD;QACxD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACvB,4BAA4B,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACrF,CAAC;QAED,2FAA2F;QAC3F,MAAM,IAAI,CAAC,mBAAmB,CAC7B,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;QACrG,GAAG,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxF,CAAC,CAAC;AACH,CAAC"}
@@ -20,10 +20,13 @@ export interface ClusterServiceComponents extends BaseComponents {
20
20
  */
21
21
  peerId?: PeerId;
22
22
  /**
23
- * Optional resolver for a peer's dialable multiaddrs, used as a fallback when
24
- * a redirect target has no multiaddrs embedded in `record.peers`.
23
+ * Optional resolver for the addresses this node may publish for a peer, used as a fallback
24
+ * when a redirect target has no multiaddrs embedded in `record.peers`. Async because the
25
+ * answer includes the peer's own advertised addresses, which live in the peerStore — see
26
+ * `publishableAddrsForPeer`. A synchronous `string[]` is still accepted so an embedder's
27
+ * connections-only stub keeps working.
25
28
  */
26
- getConnectionAddrs?: (peerId: PeerId) => string[];
29
+ getConnectionAddrs?: (peerId: PeerId) => string[] | Promise<string[]>;
27
30
  /**
28
31
  * Optional sink for dialable addresses carried by an inbound cluster record, so this
29
32
  * node can later dial a cohort sibling it has never had a connection to. Omitted →
@@ -82,6 +85,12 @@ export declare class ClusterService implements Startable {
82
85
  */
83
86
  private getLibp2p;
84
87
  private getSelfId;
88
+ /**
89
+ * The addresses this node may publish for `id` in a redirect payload, when the record carried
90
+ * none. A redirect goes to a THIRD party, so it asks `publishableAddrsForPeer` — the one
91
+ * definition, shared with `RepoService` and `findCluster` — rather than reading connections
92
+ * alone: a cohort sibling that only ever dialed US has its real address in the peerStore only.
93
+ */
85
94
  private getPeerAddrs;
86
95
  /**
87
96
  * Decide whether this node should redirect a cluster update instead of
@@ -98,7 +107,7 @@ export declare class ClusterService implements Startable {
98
107
  * when the update should be processed locally (we are a member, the mesh is too
99
108
  * small to scope, or we lack the identity/peer set to make a decision).
100
109
  */
101
- checkRedirect(record: ClusterRecord): RedirectPayload | null;
110
+ checkRedirect(record: ClusterRecord): Promise<RedirectPayload | null>;
102
111
  start(): Promise<void>;
103
112
  stop(): Promise<void>;
104
113
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/cluster/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/cluster/service.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,11 @@ import { decode as lpDecode, encode as lpEncode } from 'it-length-prefixed';
3
3
  import { peerIdFromString } from '@libp2p/peer-id';
4
4
  import { encodePeers } from '../repo/redirect.js';
5
5
  import { toClusterErrorEnvelope } from './cluster-error.js';
6
- import { mergeRecordPeerAddresses, publishableConnectionAddr } from '../peer-address-book.js';
6
+ import { mergeRecordPeerAddresses, publishableAddrsForPeer } from '../peer-address-book.js';
7
7
  import { MAX_CONTROL_MESSAGE_BYTES } from '../protocol-limits.js';
8
8
  import { createLogger } from '../logger.js';
9
9
  import { createInboundStreamAuthorization } from '../inbound-authorization.js';
10
+ import { registerProtocolHandler } from '../network/register-protocol-handler.js';
10
11
  export function clusterService(init = {}) {
11
12
  return (components) => new ClusterService(components, init);
12
13
  }
@@ -66,7 +67,13 @@ export class ClusterService {
66
67
  return this.components.peerId;
67
68
  return this.getLibp2p()?.peerId;
68
69
  }
69
- getPeerAddrs(id) {
70
+ /**
71
+ * The addresses this node may publish for `id` in a redirect payload, when the record carried
72
+ * none. A redirect goes to a THIRD party, so it asks `publishableAddrsForPeer` — the one
73
+ * definition, shared with `RepoService` and `findCluster` — rather than reading connections
74
+ * alone: a cohort sibling that only ever dialed US has its real address in the peerStore only.
75
+ */
76
+ async getPeerAddrs(id) {
70
77
  let pid;
71
78
  try {
72
79
  pid = peerIdFromString(id);
@@ -75,20 +82,12 @@ export class ClusterService {
75
82
  return [];
76
83
  }
77
84
  if (this.components.getConnectionAddrs)
78
- return this.components.getConnectionAddrs(pid);
85
+ return await this.components.getConnectionAddrs(pid);
79
86
  const libp2p = this.getLibp2p();
80
87
  if (!libp2p?.getConnections)
81
88
  return [];
82
- // A redirect payload goes to a THIRD party, so only an outbound connection's remoteAddr
83
- // qualifies — see `publishableConnectionAddr`.
84
89
  const conns = libp2p.getConnections(pid) ?? [];
85
- const addrs = [];
86
- for (const c of conns) {
87
- const addr = publishableConnectionAddr(c, this.addressLog);
88
- if (addr !== undefined)
89
- addrs.push(addr);
90
- }
91
- return addrs;
90
+ return await publishableAddrsForPeer(libp2p, conns, pid, this.addressLog);
92
91
  }
93
92
  /**
94
93
  * Decide whether this node should redirect a cluster update instead of
@@ -105,7 +104,7 @@ export class ClusterService {
105
104
  * when the update should be processed locally (we are a member, the mesh is too
106
105
  * small to scope, or we lack the identity/peer set to make a decision).
107
106
  */
108
- checkRedirect(record) {
107
+ async checkRedirect(record) {
109
108
  const selfId = this.getSelfId();
110
109
  if (!selfId)
111
110
  return null; // no identity → can't scope, process locally
@@ -118,11 +117,11 @@ export class ClusterService {
118
117
  const smallMesh = peerIds.length < this.responsibilityK;
119
118
  if (!smallMesh && !isMember) {
120
119
  const others = peerIds.filter(id => id !== selfStr);
121
- return encodePeers(others.map(id => {
120
+ return encodePeers(await Promise.all(others.map(async (id) => {
122
121
  const recAddrs = peers[id]?.multiaddrs ?? [];
123
- const addrs = recAddrs.length > 0 ? recAddrs : this.getPeerAddrs(id);
122
+ const addrs = recAddrs.length > 0 ? recAddrs : await this.getPeerAddrs(id);
124
123
  return { id, addrs };
125
- }));
124
+ })));
126
125
  }
127
126
  return null;
128
127
  }
@@ -130,7 +129,7 @@ export class ClusterService {
130
129
  if (this.running) {
131
130
  return;
132
131
  }
133
- await this.components.registrar.handle(this.protocol, this.handleIncomingStream.bind(this), {
132
+ await registerProtocolHandler(this.components.registrar, this.protocol, this.handleIncomingStream.bind(this), {
134
133
  maxInboundStreams: this.maxInboundStreams,
135
134
  maxOutboundStreams: this.maxOutboundStreams
136
135
  });
@@ -163,7 +162,7 @@ export class ClusterService {
163
162
  this.learnPeerAddresses(message.record);
164
163
  // Scope consensus to responsible peers: redirect when we are not a
165
164
  // member of the record's authoritative peer set, otherwise process.
166
- const redirect = this.checkRedirect(message.record);
165
+ const redirect = await this.checkRedirect(message.record);
167
166
  return redirect ?? await this.cluster.update(message.record);
168
167
  }
169
168
  throw new Error(`Unknown operation: ${message.operation}`);
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/cluster/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EAAE,WAAW,EAAwB,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAA+C,MAAM,yBAAyB,CAAC;AAC3I,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,gCAAgC,EAAwE,MAAM,6BAA6B,CAAC;AAgDrJ,MAAM,UAAU,cAAc,CAAC,OAA2B,EAAE;IAC3D,OAAO,CAAC,UAAoC,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACvF,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,cAAc;IACT,QAAQ,CAAS;IACjB,iBAAiB,CAAS;IAC1B,kBAAkB,CAAS;IAC3B,GAAG,CAAS;IAC7B;;;;;;OAMG;IACc,UAAU,CAAa;IACvB,OAAO,CAAW;IAClB,UAAU,CAA2B;IAC9C,OAAO,CAAU;IACzB,4EAA4E;IAC3D,eAAe,CAAS;IACzC,2FAA2F;IAC1E,aAAa,CAAyC;IAEvE,YAAY,UAAoC,EAAE,OAA2B,EAAE;QAC9E,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,SAAS,CAAC,GAAG,gBAAgB,CAAC;QACvF,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,IAAI,EAAE,CAAC;QACtD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,IAAI,EAAE,CAAC;QACxD,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,IAAI,gBAAgB,CAAC,CAAC;QAC9E,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC,mBAAmB,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,gCAAgC,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IAC5H,CAAC;IAEQ,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,iBAAiB,CAAC;IAElD;;;;;;OAMG;IACK,SAAS;QAChB,IAAI,CAAC;YACJ,OAAQ,IAAI,CAAC,UAAkB,CAAC,MAAM,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAEO,SAAS;QAChB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAC1D,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,MAA4B,CAAC;IACvD,CAAC;IAEO,YAAY,CAAC,EAAU;QAC9B,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACJ,GAAG,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,CAAC;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,kBAAkB;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACvF,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,EAAE,cAAc;YAAE,OAAO,EAAE,CAAC;QACvC,wFAAwF;QACxF,+CAA+C;QAC/C,MAAM,KAAK,GAA4B,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACxE,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,yBAAyB,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3D,IAAI,IAAI,KAAK,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,MAAqB;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,CAAK,6CAA6C;QAE3E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAE,6CAA6C;QAErF,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC;QAExD,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;YACpD,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC,EAAE,UAAU,IAAI,EAAE,CAAC;gBAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;gBACrE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;YACtB,CAAC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,KAAK;QACV,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO;QACR,CAAC;QAED,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC3F,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI;QACT,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO;QACR,CAAC;QAED,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACtB,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,gBAAgB,CAAC,OAAqD;QAC3E,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YACpC,6EAA6E;YAC7E,gFAAgF;YAChF,gFAAgF;YAChF,0EAA0E;YAC1E,qCAAqC;YACrC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACxC,mEAAmE;YACnE,oEAAoE;YACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACpD,OAAO,QAAQ,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,sBAAsB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;;;;OAQG;IACK,kBAAkB,CAAC,MAAqB;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;QACjD,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,wBAAwB,CACvB,MAAM,CAAC,KAAK,EACZ,IAAI,EACJ,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,CAC5B,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,MAAc,EAAE,UAAuB;QACnE,MAAM,MAAM,GAAG,UAAU,EAAE,UAAU,CAAC;QAEtC,MAAM,aAAa,GAAG,KAAK,SAAS,CAAC,EAAwB,MAAqC;YACjG,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;gBAChC,qEAAqE;gBACrE,mEAAmE;gBACnE,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACzD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAiD,CAAC;gBAEpF,wEAAwE;gBACxE,uEAAuE;gBACvE,yEAAyE;gBACzE,uEAAuE;gBACvE,oEAAoE;gBACpE,IAAI,QAAiB,CAAC;gBACtB,IAAI,CAAC;oBACJ,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;gBACjD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,0CAA0C,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;oBAC3F,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;gBACxC,CAAC;gBAED,gCAAgC;gBAChC,MAAM,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzD,qEAAqE;gBACrE,wEAAwE;gBACxE,sEAAsE;gBACtE,0DAA0D;gBAC1D,OAAO;YACR,CAAC;QACF,CAAC,CAAC;QAEF,KAAK,CAAC,KAAK,IAAI,EAAE;YAChB,IAAI,CAAC;gBACJ,iFAAiF;gBACjF,8DAA8D;gBAC9D,IAAI,IAAI,CAAC,aAAa,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAAE,OAAO;gBAC5F,MAAM,SAAS,GAAG,IAAI,CACrB,MAAM,EACN,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,yBAAyB,EAAE,CAAC,EAC1E,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EACxB,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC5B,CAAC;gBACF,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;oBACrC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC;gBACD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sDAAsD,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;gBACpF,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACnE,CAAC;QACF,CAAC,CAAC,EAAE,CAAC;IACN,CAAC;CACD"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/cluster/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGnD,OAAO,EAAE,WAAW,EAAwB,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAA+C,MAAM,yBAAyB,CAAC;AACzI,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,gCAAgC,EAAwE,MAAM,6BAA6B,CAAC;AACrJ,OAAO,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAmDlF,MAAM,UAAU,cAAc,CAAC,OAA2B,EAAE;IAC3D,OAAO,CAAC,UAAoC,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACvF,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,cAAc;IACT,QAAQ,CAAS;IACjB,iBAAiB,CAAS;IAC1B,kBAAkB,CAAS;IAC3B,GAAG,CAAS;IAC7B;;;;;;OAMG;IACc,UAAU,CAAa;IACvB,OAAO,CAAW;IAClB,UAAU,CAA2B;IAC9C,OAAO,CAAU;IACzB,4EAA4E;IAC3D,eAAe,CAAS;IACzC,2FAA2F;IAC1E,aAAa,CAAyC;IAEvE,YAAY,UAAoC,EAAE,OAA2B,EAAE;QAC9E,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,SAAS,CAAC,GAAG,gBAAgB,CAAC;QACvF,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,IAAI,EAAE,CAAC;QACtD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,IAAI,EAAE,CAAC;QACxD,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,IAAI,gBAAgB,CAAC,CAAC;QAC9E,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC,mBAAmB,EAAE,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,gCAAgC,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IAC5H,CAAC;IAEQ,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,iBAAiB,CAAC;IAElD;;;;;;OAMG;IACK,SAAS;QAChB,IAAI,CAAC;YACJ,OAAQ,IAAI,CAAC,UAAkB,CAAC,MAAM,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAEO,SAAS;QAChB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAC1D,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,MAA4B,CAAC;IACvD,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,YAAY,CAAC,EAAU;QACpC,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACJ,GAAG,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,EAAE,CAAC;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,kBAAkB;YAAE,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAC7F,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM,EAAE,cAAc;YAAE,OAAO,EAAE,CAAC;QACvC,MAAM,KAAK,GAA4B,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACxE,OAAO,MAAM,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3E,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,aAAa,CAAC,MAAqB;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,CAAK,6CAA6C;QAE3E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,CAAE,6CAA6C;QAErF,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC;QAExD,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;YACpD,OAAO,WAAW,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAC,EAAE,EAAC,EAAE;gBAC1D,MAAM,QAAQ,GAAG,KAAK,CAAC,EAAE,CAAC,EAAE,UAAU,IAAI,EAAE,CAAC;gBAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;gBAC3E,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;YACtB,CAAC,CAAC,CAAC,CAAC,CAAC;QACN,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,KAAK;QACV,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO;QACR,CAAC;QAED,MAAM,uBAAuB,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YAC7G,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI;QACT,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO;QACR,CAAC;QAED,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACtB,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,gBAAgB,CAAC,OAAqD;QAC3E,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YACpC,6EAA6E;YAC7E,gFAAgF;YAChF,gFAAgF;YAChF,0EAA0E;YAC1E,qCAAqC;YACrC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACxC,mEAAmE;YACnE,oEAAoE;YACpE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC1D,OAAO,QAAQ,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,sBAAsB,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;;;;;;;OAQG;IACK,kBAAkB,CAAC,MAAqB;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;QACjD,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,wBAAwB,CACvB,MAAM,CAAC,KAAK,EACZ,IAAI,EACJ,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,CAC5B,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,MAAc,EAAE,UAAuB;QACnE,MAAM,MAAM,GAAG,UAAU,EAAE,UAAU,CAAC;QAEtC,MAAM,aAAa,GAAG,KAAK,SAAS,CAAC,EAAwB,MAAqC;YACjG,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;gBAChC,qEAAqE;gBACrE,mEAAmE;gBACnE,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACzD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAiD,CAAC;gBAEpF,wEAAwE;gBACxE,uEAAuE;gBACvE,yEAAyE;gBACzE,uEAAuE;gBACvE,oEAAoE;gBACpE,IAAI,QAAiB,CAAC;gBACtB,IAAI,CAAC;oBACJ,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;gBACjD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,0CAA0C,EAAE,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;oBAC3F,QAAQ,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;gBACxC,CAAC;gBAED,gCAAgC;gBAChC,MAAM,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzD,qEAAqE;gBACrE,wEAAwE;gBACxE,sEAAsE;gBACtE,0DAA0D;gBAC1D,OAAO;YACR,CAAC;QACF,CAAC,CAAC;QAEF,KAAK,CAAC,KAAK,IAAI,EAAE;YAChB,IAAI,CAAC;gBACJ,iFAAiF;gBACjF,8DAA8D;gBAC9D,IAAI,IAAI,CAAC,aAAa,IAAI,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAAE,OAAO;gBAC5F,MAAM,SAAS,GAAG,IAAI,CACrB,MAAM,EACN,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,yBAAyB,EAAE,CAAC,EAC1E,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EACxB,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC5B,CAAC;gBACF,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;oBACrC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC;gBACD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sDAAsD,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;gBACpF,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACnE,CAAC;QACF,CAAC,CAAC,EAAE,CAAC;IACN,CAAC;CACD"}
@@ -1,7 +1,8 @@
1
1
  import type { Startable, Libp2p } from '@libp2p/interface';
2
- import type { IRepo, IPeerNetwork } from '@optimystic/db-core';
2
+ import type { IPeerNetwork } from '@optimystic/db-core';
3
3
  import type { FretService } from 'p2p-fret';
4
4
  import type { PartitionDetector } from './partition-detector.js';
5
+ import type { ProofRetainingRepo } from '../storage/block-archive.js';
5
6
  export interface SpreadOnChurnConfig {
6
7
  /** Enable the churn-resilient spread protocol. Default: true */
7
8
  enabled: boolean;
@@ -33,7 +34,12 @@ export interface SpreadOnChurnDeps {
33
34
  libp2p: Libp2p;
34
35
  fret: FretService;
35
36
  partitionDetector: PartitionDetector;
36
- repo: IRepo;
37
+ /**
38
+ * The node's OWN store, proof accessor REQUIRED — see the same requirement on
39
+ * `BlockTransferCoordinator`: a repo without it spreads meta-only pushes that every
40
+ * default-configured receiver refuses, with no type error to say so.
41
+ */
42
+ repo: ProofRetainingRepo;
37
43
  peerNetwork: IPeerNetwork;
38
44
  clusterSize: number;
39
45
  protocolPrefix?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"spread-on-churn.d.ts","sourceRoot":"","sources":["../../../src/cluster/spread-on-churn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAShE,MAAM,WAAW,mBAAmB;IACnC,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAA;IAChB,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAA;IACtB,sEAAsE;IACtE,qBAAqB,EAAE,OAAO,CAAA;IAC9B,kFAAkF;IAClF,eAAe,EAAE,MAAM,CAAA;IACvB,kEAAkE;IAClE,mBAAmB,EAAE,MAAM,CAAA;IAC3B,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,qBAAqB,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,WAAW,CAAA;IACjB,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,IAAI,EAAE,KAAK,CAAA;IACX,WAAW,EAAE,YAAY,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC3B;AAED,MAAM,WAAW,WAAW;IAC3B,8BAA8B;IAC9B,MAAM,EAAE,KAAK,CAAC;QACb,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,EAAE,CAAA;QACjB,SAAS,EAAE,MAAM,EAAE,CAAA;QACnB,MAAM,EAAE,MAAM,EAAE,CAAA;KAChB,CAAC,CAAA;IACF,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAA;CACnB;AAED,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;AAiBjD,qBAAa,oBAAqB,YAAW,SAAS;IAYpD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAXtB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAa;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,aAAa,CAA6C;IAClE,OAAO,CAAC,mBAAmB,CAAe;IAC1C,OAAO,CAAC,kBAAkB,CAAI;IAE9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAY;gBAG5B,IAAI,EAAE,iBAAiB,EACxC,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM;IAWpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAItC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAInC,oBAAoB,IAAI,MAAM;IAI9B,4DAA4D;IACtD,QAAQ,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAM7C,OAAO,CAAC,eAAe;YA2BT,aAAa;IAkH3B,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,SAAS;CASjB"}
1
+ {"version":3,"file":"spread-on-churn.d.ts","sourceRoot":"","sources":["../../../src/cluster/spread-on-churn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAEvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AASrE,MAAM,WAAW,mBAAmB;IACnC,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAA;IAChB,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAA;IACtB,sEAAsE;IACtE,qBAAqB,EAAE,OAAO,CAAA;IAC9B,kFAAkF;IAClF,eAAe,EAAE,MAAM,CAAA;IACvB,kEAAkE;IAClE,mBAAmB,EAAE,MAAM,CAAA;IAC3B,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,qBAAqB,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,WAAW,CAAA;IACjB,iBAAiB,EAAE,iBAAiB,CAAA;IACpC;;;;OAIG;IACH,IAAI,EAAE,kBAAkB,CAAA;IACxB,WAAW,EAAE,YAAY,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC3B;AAED,MAAM,WAAW,WAAW;IAC3B,8BAA8B;IAC9B,MAAM,EAAE,KAAK,CAAC;QACb,OAAO,EAAE,MAAM,CAAA;QACf,OAAO,EAAE,MAAM,EAAE,CAAA;QACjB,SAAS,EAAE,MAAM,EAAE,CAAA;QACnB,MAAM,EAAE,MAAM,EAAE,CAAA;KAChB,CAAC,CAAA;IACF,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAA;CACnB;AAED,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;AAiBjD,qBAAa,oBAAqB,YAAW,SAAS;IAYpD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAXtB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAa;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,aAAa,CAA6C;IAClE,OAAO,CAAC,mBAAmB,CAAe;IAC1C,OAAO,CAAC,kBAAkB,CAAI;IAE9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAY;gBAG5B,IAAI,EAAE,iBAAiB,EACxC,MAAM,GAAE,OAAO,CAAC,mBAAmB,CAAM;IAWpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAItC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAInC,oBAAoB,IAAI,MAAM;IAI9B,4DAA4D;IACtD,QAAQ,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAM7C,OAAO,CAAC,eAAe;YA2BT,aAAa;IAkH3B,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,SAAS;CASjB"}
@@ -1,6 +1,6 @@
1
1
  import { hashKey } from 'p2p-fret';
2
2
  import { peerIdFromString } from '@libp2p/peer-id';
3
- import { BlockTransferClient } from './block-transfer-service.js';
3
+ import { BlockTransferClient, sourceBlockCertification } from './block-transfer-service.js';
4
4
  import { createLogger } from '../logger.js';
5
5
  const log = createLogger('spread-on-churn');
6
6
  const textEncoder = new TextEncoder();
@@ -143,11 +143,11 @@ export class SpreadOnChurnMonitor {
143
143
  }
144
144
  const blockData = textEncoder.encode(JSON.stringify(blockResult.block));
145
145
  // Carry the source's revision metadata so the replica's `latest` matches the
146
- // source instead of being fabricated as rev 1 on the receiver.
147
- const latest = blockResult.state?.latest;
148
- const blockMeta = latest
149
- ? { [blockId]: { rev: latest.rev, actionId: latest.actionId } }
150
- : undefined;
146
+ // source instead of being fabricated as rev 1 on the receiver, plus the cohort commit
147
+ // proof for that same revision — a receiver running the default `requirePushCertificate`
148
+ // rejects an uncertified push, so a block this node holds no proof for simply fails to
149
+ // spread (logged by the receiver as `push:reject-uncertified`) rather than being planted.
150
+ const certification = await sourceBlockCertification(this.deps.repo, blockId, blockResult);
151
151
  // Push to each target
152
152
  const succeeded = [];
153
153
  const failed = [];
@@ -159,7 +159,7 @@ export class SpreadOnChurnMonitor {
159
159
  // never replies would otherwise hang this sequential loop forever during
160
160
  // churn (exactly when slow/dying peers are common); the deadline makes the
161
161
  // push throw, which the catch below records as `failed` so the pass advances.
162
- const response = await client.pushBlocks([blockId], [blockData], 'replication', blockMeta, {
162
+ const response = await client.pushBlocks([blockId], [blockData], 'replication', certification, {
163
163
  dialTimeoutMs: this.config.pushDialTimeoutMs,
164
164
  responseTimeoutMs: this.config.pushResponseTimeoutMs,
165
165
  });