@optimystic/db-p2p 0.24.2 → 0.25.1

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,7 +1,9 @@
1
1
  import type { Startable } from '@libp2p/interface';
2
- import type { IRepo, PeerId, IPeerNetwork, ActionId, ActionRev, IBlock, BlockId } from '@optimystic/db-core';
2
+ import type { IRepo, PeerId, IPeerNetwork, ActionId, ActionRev, GetBlockResult, IBlock, BlockId } from '@optimystic/db-core';
3
3
  import { ProtocolClient } from '../protocol-client.js';
4
4
  import { type InboundStreamAuthorizationInit } from '../inbound-authorization.js';
5
+ import type { BlockCommitProof } from './commit-proof.js';
6
+ import { type ArchiveServingRepo } from '../storage/block-archive.js';
5
7
  export declare const buildBlockTransferProtocol: (protocolPrefix?: string) => string;
6
8
  /** Request to transfer blocks */
7
9
  export interface BlockTransferRequest {
@@ -22,7 +24,76 @@ export interface BlockTransferRequest {
22
24
  rev: number;
23
25
  actionId: ActionId;
24
26
  }>;
27
+ /**
28
+ * For push: the cohort's commit proof for each block's revision. Verified against the pushed
29
+ * bytes AND against the declared {@link blockMeta} before anything is persisted — one
30
+ * `certifyContent` call covers the signatures and thresholds, the claim matching the declared
31
+ * `(rev, actionId)`, and the declared digest matching the pushed bytes.
32
+ *
33
+ * Optional on the wire so an un-upgraded sender still parses; whether a proof-less push is
34
+ * ACCEPTED is the receiver's `requirePushCertificate` decision (default: reject).
35
+ */
36
+ blockProofs?: Record<string, BlockCommitProof>;
25
37
  }
38
+ /**
39
+ * The `blockMeta` a pusher sends alongside one block: the source's own `state.latest`, so the
40
+ * replica lands at the source's `(rev, actionId)` rather than a fabricated one. That match is what
41
+ * later lets the replica CORROBORATE the source in a read-repair quorum vote — a fabricated action
42
+ * id never matches the source's claim, so the vote sees one claimant, not two.
43
+ *
44
+ * `undefined` when the source repo reports no `latest`; the receiver then falls back to its
45
+ * deterministic rev-1 replica (see `IBlockStorage.saveReplica`).
46
+ *
47
+ * Every push path (rebalance confirm/push, spread-on-churn) builds it here so the wire shape stays
48
+ * defined in one place alongside {@link BlockTransferRequest.blockMeta}.
49
+ *
50
+ * The caller must read the block UNPINNED (no `BlockGets.context`). `state.latest` is the newest
51
+ * revision the source holds, while `block` is the revision `materialized` names; those agree only
52
+ * for an unpinned read. Pairing pinned (older) content with `latest` would label content with a
53
+ * revision it is not — so the pairing is guarded below and drops the meta rather than lying.
54
+ *
55
+ * Dropping, rather than labelling the older content with its own (now known) `materialized`
56
+ * revision, is deliberate: a push is "here is my latest replica" — the receiver lands it as its
57
+ * replica and the source's `latest` is what the cohort corroborates — and no push path reads
58
+ * pinned, so a mismatch here is a caller bug, not a historical serve. A repair fetch of an older
59
+ * revision is a different wire (`serveBlockArchive`), and that one DOES label from `materialized`.
60
+ */
61
+ export declare function sourceBlockMeta(blockId: BlockId, result: Pick<GetBlockResult, 'state' | 'materialized'> | undefined): Record<string, ActionRev> | undefined;
62
+ /**
63
+ * Everything a push carries ABOUT the blocks it pushes, as one value: the source's revision
64
+ * metadata and the cohort commit proof for that same revision. One parameter rather than two so a
65
+ * caller cannot attach a proof for one revision beside metadata for another — the two are built
66
+ * together by {@link sourceBlockCertification} from a single unpinned read, or not at all.
67
+ */
68
+ export type PushCertification = {
69
+ blockMeta?: Record<string, ActionRev>;
70
+ blockProofs?: Record<string, BlockCommitProof>;
71
+ };
72
+ /**
73
+ * Build a push's {@link PushCertification} for ONE block from a single unpinned read: the
74
+ * {@link sourceBlockMeta} for the source's `state.latest`, plus the locally-retained
75
+ * {@link BlockCommitProof} for exactly that revision.
76
+ *
77
+ * The proof comes from {@link servableProof} — the same accessor that decides what a peer attaches
78
+ * to a served repair archive — so a push and a repair fetch can never disagree about which proof
79
+ * pairs with which revision. It fails closed on every unhappy path (repo with no proof accessor, a
80
+ * throwing lookup, a stored proof whose message names a different `(blockId, rev, actionId)`), so a
81
+ * mis-paired artifact is never pushed.
82
+ *
83
+ * **A proof is never attached without its meta.** Without the declared `(rev, actionId)` a receiver
84
+ * has no claim to verify the proof against, and it rejects the block (see
85
+ * `BlockTransferService.handlePush`).
86
+ *
87
+ * **Meta IS still attached when no proof exists.** That is the pre-proof push, unchanged: a
88
+ * receiver running the default `requirePushCertificate: true` rejects it either way, and one
89
+ * migrating with the flag `false` needs the meta to land the replica at the source's revision
90
+ * instead of a fabricated rev 1. Dropping the meta alongside the missing proof would regress the
91
+ * legacy path without making the strict path any stricter.
92
+ *
93
+ * Like `sourceBlockMeta`, the caller must have read the block UNPINNED, so `block`, the meta and
94
+ * the proof all describe the same revision.
95
+ */
96
+ export declare function sourceBlockCertification(repo: ArchiveServingRepo, blockId: BlockId, result: Pick<GetBlockResult, 'state' | 'materialized'> | undefined): Promise<PushCertification>;
26
97
  /** Response with block data */
27
98
  export interface BlockTransferResponse {
28
99
  /** Blocks successfully transferred: blockId → base64-encoded data */
@@ -42,11 +113,36 @@ export interface IBlockReplicaStore extends IRepo {
42
113
  * Seeds metadata if absent, advances `latest` monotonically, and makes the block
43
114
  * durably servable via `get`. Idempotent for a fixed `(rev, actionId)`; a no-op
44
115
  * (still durable) when an equal-or-newer revision is already present.
116
+ *
117
+ * `verifiedProof` MUST already have been verified against these exact bytes and this exact
118
+ * `source` (`certifyContent` — the digest check is what binds a proof to the content). It is
119
+ * retained so the receiver can re-prove onward what it just verified, instead of becoming a
120
+ * holder that can only corroborate.
45
121
  */
46
- saveReplicatedBlock(blockId: BlockId, block: IBlock, source?: ActionRev): Promise<void>;
122
+ saveReplicatedBlock(blockId: BlockId, block: IBlock, source?: ActionRev, verifiedProof?: BlockCommitProof): Promise<void>;
47
123
  }
48
124
  export interface BlockTransferServiceInit extends InboundStreamAuthorizationInit {
49
125
  protocolPrefix?: string;
126
+ /**
127
+ * Reject a pushed block that carries no verifying commit proof. Default `true`.
128
+ * A deployment holding pre-proof data sets this `false` during migration.
129
+ *
130
+ * **Why the strict default.** `handlePush` persists what a peer hands it, and
131
+ * `saveReplicatedBlock` advances `latest` monotonically — so an uncertified push makes the
132
+ * pusher's bytes this node's authoritative revision, after which this node *corroborates* the
133
+ * pusher in a later read-repair vote. That is how a peer manufactures its own corroborators.
134
+ *
135
+ * The failure mode of `true` is that legacy blocks stop gaining new holders via push — visible
136
+ * in a `push:reject-uncertified` log line, and those blocks stay readable while two or more
137
+ * holders remain. The failure mode of `false` is silent acceptance of forged content. Pre-proof
138
+ * blocks can never be certified (the signatures no longer exist), but any block written again
139
+ * under the current code gets a proof, so only cold, never-updated blocks stay uncertified.
140
+ *
141
+ * With the flag `false` an uncertified push falls back to the pre-proof behaviour, logged as
142
+ * `push:accept-uncertified`. A push carrying a proof that FAILS verification is rejected
143
+ * regardless of the flag — that is not a legacy block, it is a bad one.
144
+ */
145
+ requirePushCertificate?: boolean;
50
146
  }
51
147
  export interface BlockTransferServiceComponents {
52
148
  registrar: {
@@ -54,6 +150,20 @@ export interface BlockTransferServiceComponents {
54
150
  unhandle: (...args: any[]) => Promise<void>;
55
151
  };
56
152
  repo: IBlockReplicaStore;
153
+ /**
154
+ * The cohort's configured super-majority fraction, used to verify a pushed block's commit proof.
155
+ *
156
+ * REQUIRED rather than defaulted: the node factory must hand this down from the single resolved
157
+ * `consensusConfig` every other consensus consumer reads (`libp2p-node-base.ts`, which already
158
+ * fail-fast asserts member/coordinator coupling on exactly this value). A local default here
159
+ * would be a third copy that silently disagrees with a deployment that tuned the threshold.
160
+ *
161
+ * The simple-majority half of {@link ProofThresholds} is deliberately NOT threaded: it must
162
+ * mirror what members actually enforce (`count > total / 2`), not the configured 0.51 — see
163
+ * `proofThresholds` in `certified-claims.ts`, the one helper every proof-verifying path builds
164
+ * its thresholds with.
165
+ */
166
+ superMajorityThreshold: number;
57
167
  /**
58
168
  * Optional libp2p component logger. Supplied by the node factory so authorization denials
59
169
  * land on the same `logger.forComponent(...).error` sink as the repo/cluster/sync services;
@@ -78,6 +188,10 @@ export declare class BlockTransferService implements Startable {
78
188
  private readonly registrar;
79
189
  /** Optional embedder authorization gate; `undefined` (the default) means no check runs. */
80
190
  private readonly authorization;
191
+ /** Built once from the node's configured super-majority — see {@link BlockTransferServiceComponents.superMajorityThreshold}. */
192
+ private readonly proofThresholds;
193
+ /** See {@link BlockTransferServiceInit.requirePushCertificate}. */
194
+ private readonly requirePushCertificate;
81
195
  constructor(components: BlockTransferServiceComponents, init?: BlockTransferServiceInit);
82
196
  start(): Promise<void>;
83
197
  stop(): Promise<void>;
@@ -86,8 +200,18 @@ export declare class BlockTransferService implements Startable {
86
200
  /**
87
201
  * Persist pushed blocks into local storage so the new owner holds a durable
88
202
  * replica after churn. A block is reported `accepted` only if it was both
89
- * received (parseable) AND successfully persisted; a parse or persist failure
203
+ * received (parseable) AND successfully persisted; a parse, certification or persist failure
90
204
  * surfaces it as `missing` so the sender does not falsely treat it as replicated.
205
+ *
206
+ * **Certification.** A pushed block is content this node will serve — and, because
207
+ * `saveReplicatedBlock` advances `latest`, content it will later CORROBORATE in a read-repair
208
+ * vote. So by default the pusher must show the cohort's commit proof for the revision it
209
+ * declares, verified here against both the declared `(rev, actionId)` and the pushed bytes. See
210
+ * {@link BlockTransferServiceInit.requirePushCertificate} for the migration flag and its
211
+ * rationale.
212
+ *
213
+ * Decisions are strictly PER BLOCK: in a multi-block push a block that verifies is accepted
214
+ * beside one that does not. `handlePull` is unaffected — it serves this node's own storage.
91
215
  */
92
216
  private handlePush;
93
217
  }
@@ -115,9 +239,11 @@ export declare class BlockTransferClient extends ProtocolClient {
115
239
  /**
116
240
  * Push blocks to the remote peer.
117
241
  *
118
- * @param blockMeta Optional per-block source revision metadata (the sender's
119
- * `state.latest`). When provided, the receiver replicates at the source's
120
- * `(rev, actionId)`; when omitted, it falls back to a deterministic rev-1 replica.
242
+ * @param certification What this push claims about the blocks — the source's revision metadata
243
+ * and the cohort commit proof for that same revision, built as one unit by
244
+ * {@link sourceBlockCertification}. Without a proof the receiver rejects the block under its
245
+ * default `requirePushCertificate: true`; without metadata it replicates at a deterministic
246
+ * rev-1 (and rejects any proof, which then covers nothing).
121
247
  * @param options Optional per-call deadlines/cancellation forwarded to the
122
248
  * underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
123
249
  * bounds waiting for the reply once connected (so a peer that connects but goes
@@ -125,10 +251,7 @@ export declare class BlockTransferClient extends ProtocolClient {
125
251
  * cancels the whole request. Omitting all of them preserves the previous
126
252
  * uncapped behavior.
127
253
  */
128
- pushBlocks(blockIds: string[], blockDataBuffers: Uint8Array[], reason?: BlockTransferRequest['reason'], blockMeta?: Record<string, {
129
- rev: number;
130
- actionId: ActionId;
131
- }>, options?: {
254
+ pushBlocks(blockIds: string[], blockDataBuffers: Uint8Array[], reason?: BlockTransferRequest['reason'], certification?: PushCertification, options?: {
132
255
  signal?: AbortSignal;
133
256
  dialTimeoutMs?: number;
134
257
  responseTimeoutMs?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"block-transfer-service.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block-transfer-service.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
@@ -6,11 +6,85 @@ import { ProtocolClient } from '../protocol-client.js';
6
6
  import { MAX_BLOCK_MESSAGE_BYTES } from '../protocol-limits.js';
7
7
  import { createLogger } from '../logger.js';
8
8
  import { createInboundStreamAuthorization } from '../inbound-authorization.js';
9
+ import { certifyContent, proofThresholds } from './certified-claims.js';
10
+ import { servableProof } from '../storage/block-archive.js';
11
+ import { registerProtocolHandler } from '../network/register-protocol-handler.js';
9
12
  const log = createLogger('block-transfer-service');
10
13
  /** Protocol path */
11
14
  const BLOCK_TRANSFER_PREFIX = '/db-p2p/block-transfer/';
12
15
  const BLOCK_TRANSFER_VERSION = '1.0.0';
13
16
  export const buildBlockTransferProtocol = (protocolPrefix = '') => `${protocolPrefix}${BLOCK_TRANSFER_PREFIX}${BLOCK_TRANSFER_VERSION}`;
17
+ /**
18
+ * The `blockMeta` a pusher sends alongside one block: the source's own `state.latest`, so the
19
+ * replica lands at the source's `(rev, actionId)` rather than a fabricated one. That match is what
20
+ * later lets the replica CORROBORATE the source in a read-repair quorum vote — a fabricated action
21
+ * id never matches the source's claim, so the vote sees one claimant, not two.
22
+ *
23
+ * `undefined` when the source repo reports no `latest`; the receiver then falls back to its
24
+ * deterministic rev-1 replica (see `IBlockStorage.saveReplica`).
25
+ *
26
+ * Every push path (rebalance confirm/push, spread-on-churn) builds it here so the wire shape stays
27
+ * defined in one place alongside {@link BlockTransferRequest.blockMeta}.
28
+ *
29
+ * The caller must read the block UNPINNED (no `BlockGets.context`). `state.latest` is the newest
30
+ * revision the source holds, while `block` is the revision `materialized` names; those agree only
31
+ * for an unpinned read. Pairing pinned (older) content with `latest` would label content with a
32
+ * revision it is not — so the pairing is guarded below and drops the meta rather than lying.
33
+ *
34
+ * Dropping, rather than labelling the older content with its own (now known) `materialized`
35
+ * revision, is deliberate: a push is "here is my latest replica" — the receiver lands it as its
36
+ * replica and the source's `latest` is what the cohort corroborates — and no push path reads
37
+ * pinned, so a mismatch here is a caller bug, not a historical serve. A repair fetch of an older
38
+ * revision is a different wire (`serveBlockArchive`), and that one DOES label from `materialized`.
39
+ */
40
+ export function sourceBlockMeta(blockId, result) {
41
+ const latest = result?.state?.latest;
42
+ if (!latest)
43
+ return undefined;
44
+ const materialized = result?.materialized;
45
+ if (materialized !== undefined && materialized.rev !== latest.rev) {
46
+ log('meta:skip block=%s materialized=%d latest=%d (pinned read — refusing to mislabel content)', blockId, materialized.rev, latest.rev);
47
+ return undefined;
48
+ }
49
+ return { [blockId]: { rev: latest.rev, actionId: latest.actionId } };
50
+ }
51
+ /**
52
+ * Build a push's {@link PushCertification} for ONE block from a single unpinned read: the
53
+ * {@link sourceBlockMeta} for the source's `state.latest`, plus the locally-retained
54
+ * {@link BlockCommitProof} for exactly that revision.
55
+ *
56
+ * The proof comes from {@link servableProof} — the same accessor that decides what a peer attaches
57
+ * to a served repair archive — so a push and a repair fetch can never disagree about which proof
58
+ * pairs with which revision. It fails closed on every unhappy path (repo with no proof accessor, a
59
+ * throwing lookup, a stored proof whose message names a different `(blockId, rev, actionId)`), so a
60
+ * mis-paired artifact is never pushed.
61
+ *
62
+ * **A proof is never attached without its meta.** Without the declared `(rev, actionId)` a receiver
63
+ * has no claim to verify the proof against, and it rejects the block (see
64
+ * `BlockTransferService.handlePush`).
65
+ *
66
+ * **Meta IS still attached when no proof exists.** That is the pre-proof push, unchanged: a
67
+ * receiver running the default `requirePushCertificate: true` rejects it either way, and one
68
+ * migrating with the flag `false` needs the meta to land the replica at the source's revision
69
+ * instead of a fabricated rev 1. Dropping the meta alongside the missing proof would regress the
70
+ * legacy path without making the strict path any stricter.
71
+ *
72
+ * Like `sourceBlockMeta`, the caller must have read the block UNPINNED, so `block`, the meta and
73
+ * the proof all describe the same revision.
74
+ */
75
+ export async function sourceBlockCertification(repo, blockId, result) {
76
+ const blockMeta = sourceBlockMeta(blockId, result);
77
+ if (!blockMeta) {
78
+ return {};
79
+ }
80
+ const latest = result.state.latest;
81
+ const proof = await servableProof(repo, blockId, latest);
82
+ if (!proof) {
83
+ log('cert:no-local-proof block=%s rev=%d (pushing uncertified)', blockId, latest.rev);
84
+ return { blockMeta };
85
+ }
86
+ return { blockMeta, blockProofs: { [blockId]: proof } };
87
+ }
14
88
  /**
15
89
  * Libp2p service that handles incoming block transfer requests.
16
90
  *
@@ -24,17 +98,23 @@ export class BlockTransferService {
24
98
  registrar;
25
99
  /** Optional embedder authorization gate; `undefined` (the default) means no check runs. */
26
100
  authorization;
101
+ /** Built once from the node's configured super-majority — see {@link BlockTransferServiceComponents.superMajorityThreshold}. */
102
+ proofThresholds;
103
+ /** See {@link BlockTransferServiceInit.requirePushCertificate}. */
104
+ requirePushCertificate;
27
105
  constructor(components, init = {}) {
28
106
  this.protocol = buildBlockTransferProtocol(init.protocolPrefix ?? '');
29
107
  this.repo = components.repo;
30
108
  this.registrar = components.registrar;
109
+ this.proofThresholds = proofThresholds(components.superMajorityThreshold);
110
+ this.requirePushCertificate = init.requirePushCertificate ?? true;
31
111
  const componentLog = components.logger?.forComponent('db-p2p:block-transfer');
32
112
  this.authorization = createInboundStreamAuthorization(init, this.protocol, componentLog ? (msg, ...args) => componentLog.error(msg, ...args) : (msg, ...args) => log(msg, ...args));
33
113
  }
34
114
  async start() {
35
115
  if (this.running)
36
116
  return;
37
- await this.registrar.handle(this.protocol, async (data, connection) => {
117
+ await registerProtocolHandler(this.registrar, this.protocol, async (data, connection) => {
38
118
  // libp2p invokes the stream handler with the Stream as the FIRST positional argument
39
119
  // (see cluster/repo/dispute services, which all use `(stream, connection)`). The block-
40
120
  // transfer handler previously read `data.stream`, which is `undefined` for the positional
@@ -118,8 +198,18 @@ export class BlockTransferService {
118
198
  /**
119
199
  * Persist pushed blocks into local storage so the new owner holds a durable
120
200
  * replica after churn. A block is reported `accepted` only if it was both
121
- * received (parseable) AND successfully persisted; a parse or persist failure
201
+ * received (parseable) AND successfully persisted; a parse, certification or persist failure
122
202
  * surfaces it as `missing` so the sender does not falsely treat it as replicated.
203
+ *
204
+ * **Certification.** A pushed block is content this node will serve — and, because
205
+ * `saveReplicatedBlock` advances `latest`, content it will later CORROBORATE in a read-repair
206
+ * vote. So by default the pusher must show the cohort's commit proof for the revision it
207
+ * declares, verified here against both the declared `(rev, actionId)` and the pushed bytes. See
208
+ * {@link BlockTransferServiceInit.requirePushCertificate} for the migration flag and its
209
+ * rationale.
210
+ *
211
+ * Decisions are strictly PER BLOCK: in a multi-block push a block that verifies is accepted
212
+ * beside one that does not. `handlePull` is unaffected — it serves this node's own storage.
123
213
  */
124
214
  async handlePush(request) {
125
215
  const blocks = {};
@@ -150,10 +240,60 @@ export class BlockTransferService {
150
240
  missing.push(blockId);
151
241
  continue;
152
242
  }
243
+ // Certify BEFORE persisting: `saveReplicatedBlock` advances `latest`, so anything that
244
+ // reaches it becomes this node's authoritative revision.
245
+ const source = request.blockMeta?.[blockId];
246
+ const proof = request.blockProofs?.[blockId];
247
+ let verifiedProof;
248
+ if (proof !== undefined) {
249
+ if (!source) {
250
+ // No declared `(rev, actionId)` means no claim to verify the proof against, and
251
+ // `saveReplica` would fabricate a rev-1 replica the proof does not cover.
252
+ log('push:reject-uncertified block=%s reason=proof-without-meta', blockId);
253
+ missing.push(blockId);
254
+ continue;
255
+ }
256
+ // One call covers the signatures and thresholds, the claim matching the declared
257
+ // `(rev, actionId)`, and the declared digest matching these exact bytes. Routed through
258
+ // `certifyContent` rather than the raw verifier so the wire-facing signer cap
259
+ // (MAX_PROOF_SIGNERS) the verifier requires of its callers is applied before any
260
+ // signature work — this input comes from an unauthenticated peer.
261
+ //
262
+ // NOTE: no `ProofAnchoring` is threaded here, unlike the other two proof-verifying
263
+ // paths (`ReconcileBlockDeps.anchoring`, `CoordinatorRepo`'s). Nothing wires anchoring
264
+ // in production today, so all three behave identically; when
265
+ // `feat-cluster-membership-threshold-cert-anchoring` lands, this call needs the same
266
+ // optional dep or the push path becomes the one place the unanchored residual is
267
+ // neither compared nor surfaced.
268
+ //
269
+ // NOTE: verification cost per REQUEST is unbounded in a way per-proof caps do not
270
+ // cover — one inbound push frame is capped at MAX_BLOCK_MESSAGE_BYTES (8 MiB, not the
271
+ // 1 MiB control cap `MAX_PROOF_SIGNERS`' note reasons about) and may carry one proof
272
+ // per block id. Each proof is bounded (≤ 256 signers), but their number is the
273
+ // sender's choice. Acceptable today because the pre-proof path already did per-block
274
+ // parse + disk write on the same frame; if inbound push CPU ever shows up in a
275
+ // profile, bound the per-request proof count (or total proof bytes) here.
276
+ const verdict = await certifyContent(proof, { blockId, rev: source.rev, actionId: source.actionId }, block, this.proofThresholds);
277
+ if (!verdict.contentCertified) {
278
+ log('push:reject-uncertified block=%s rev=%d reason=%s', blockId, source.rev, verdict.failure);
279
+ missing.push(blockId);
280
+ continue;
281
+ }
282
+ verifiedProof = proof;
283
+ }
284
+ else if (this.requirePushCertificate) {
285
+ // The documented migration case: an un-upgraded sender, or a block committed before
286
+ // proofs existed. Diagnosable by this line alone.
287
+ log('push:reject-uncertified block=%s rev=%s reason=no-proof', blockId, source?.rev);
288
+ missing.push(blockId);
289
+ continue;
290
+ }
291
+ else {
292
+ log('push:accept-uncertified block=%s rev=%s (requirePushCertificate disabled)', blockId, source?.rev);
293
+ }
153
294
  // Persist locally. Only a received-AND-persisted block is reported accepted.
154
295
  try {
155
- const source = request.blockMeta?.[blockId];
156
- await this.repo.saveReplicatedBlock(blockId, block, source);
296
+ await this.repo.saveReplicatedBlock(blockId, block, source, verifiedProof);
157
297
  blocks[blockId] = data;
158
298
  }
159
299
  catch (error) {
@@ -191,9 +331,11 @@ export class BlockTransferClient extends ProtocolClient {
191
331
  /**
192
332
  * Push blocks to the remote peer.
193
333
  *
194
- * @param blockMeta Optional per-block source revision metadata (the sender's
195
- * `state.latest`). When provided, the receiver replicates at the source's
196
- * `(rev, actionId)`; when omitted, it falls back to a deterministic rev-1 replica.
334
+ * @param certification What this push claims about the blocks — the source's revision metadata
335
+ * and the cohort commit proof for that same revision, built as one unit by
336
+ * {@link sourceBlockCertification}. Without a proof the receiver rejects the block under its
337
+ * default `requirePushCertificate: true`; without metadata it replicates at a deterministic
338
+ * rev-1 (and rejects any proof, which then covers nothing).
197
339
  * @param options Optional per-call deadlines/cancellation forwarded to the
198
340
  * underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
199
341
  * bounds waiting for the reply once connected (so a peer that connects but goes
@@ -201,12 +343,16 @@ export class BlockTransferClient extends ProtocolClient {
201
343
  * cancels the whole request. Omitting all of them preserves the previous
202
344
  * uncapped behavior.
203
345
  */
204
- async pushBlocks(blockIds, blockDataBuffers, reason = 'rebalance', blockMeta, options) {
346
+ async pushBlocks(blockIds, blockDataBuffers, reason = 'rebalance', certification, options) {
205
347
  const blockData = {};
206
348
  for (let i = 0; i < blockIds.length; i++) {
207
349
  blockData[blockIds[i]] = Buffer.from(blockDataBuffers[i]).toString('base64');
208
350
  }
209
- const request = { type: 'push', blockIds, reason, blockData, ...(blockMeta ? { blockMeta } : {}) };
351
+ const request = {
352
+ type: 'push', blockIds, reason, blockData,
353
+ ...(certification?.blockMeta ? { blockMeta: certification.blockMeta } : {}),
354
+ ...(certification?.blockProofs ? { blockProofs: certification.blockProofs } : {})
355
+ };
210
356
  return await this.processMessage(request, this.protocol, { ...options, maxDataLength: MAX_BLOCK_MESSAGE_BYTES });
211
357
  }
212
358
  }
@@ -1 +1 @@
1
- {"version":3,"file":"block-transfer-service.js","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"block-transfer-service.js","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
- import type { IRepo, IPeerNetwork } from '@optimystic/db-core';
1
+ import type { IPeerNetwork } from '@optimystic/db-core';
2
2
  import type { PartitionDetector } from './partition-detector.js';
3
3
  import type { RestorationCoordinator } from '../storage/restoration-coordinator.js';
4
- import type { RebalanceEvent } from './rebalance-monitor.js';
4
+ import type { ProofRetainingRepo } from '../storage/block-archive.js';
5
+ import type { GrowthOutcome, RebalanceEvent } from './rebalance-monitor.js';
5
6
  export interface BlockTransferConfig {
6
7
  /** Max concurrent transfers. Default: 4 */
7
8
  maxConcurrency?: number;
@@ -26,6 +27,22 @@ export interface RebalanceReactionResult {
26
27
  released: string[];
27
28
  /** Lost blocks whose replication could not be confirmed — keep serving, retry later. */
28
29
  retained: string[];
30
+ /** Grown blocks confirmed pushed to every newly co-responsible peer (capped by the floor). */
31
+ replicated: string[];
32
+ /**
33
+ * Grown blocks that could not be confirmed on the new peers this pass. Nothing is released off
34
+ * this list — the node keeps the block either way. The retry lives in the monitor: the caller
35
+ * feeds each block's {@link GrowthOutcome} (in `growth`) back via
36
+ * `RebalanceMonitor.recordGrowthOutcome`, so an unconfirmed peer stays out of the seen set and
37
+ * the next check re-detects it.
38
+ */
39
+ underReplicated: string[];
40
+ /**
41
+ * Per-block feedback for the growth arm, keyed by block id. A block reported `grown` that the
42
+ * reaction had NO information about (its confirm was deduped against one already in flight) has
43
+ * no entry — the monitor must leave that block's state untouched.
44
+ */
45
+ growth: Map<string, GrowthOutcome>;
29
46
  }
30
47
  /**
31
48
  * Coordinates block transfers in response to rebalance events.
@@ -37,6 +54,13 @@ export interface RebalanceReactionResult {
37
54
  * via the BlockTransfer protocol.
38
55
  */
39
56
  export declare class BlockTransferCoordinator {
57
+ /**
58
+ * The node's OWN store, proof accessor REQUIRED (not the optional `ArchiveServingRepo`
59
+ * shape): every push this class makes is certified out of it, and a repo without the
60
+ * accessor would make `sourceBlockCertification` return meta-only for every block — so
61
+ * every push would be refused by a receiver running the default `requirePushCertificate`,
62
+ * silently and with no type error. Same reasoning as `createServedRepoProxy`'s.
63
+ */
40
64
  private readonly repo;
41
65
  private readonly peerNetwork;
42
66
  private readonly restorationCoordinator;
@@ -49,7 +73,15 @@ export declare class BlockTransferCoordinator {
49
73
  private inFlight;
50
74
  private concurrency;
51
75
  private readonly waitQueue;
52
- constructor(repo: IRepo, peerNetwork: IPeerNetwork, restorationCoordinator: RestorationCoordinator, partitionDetector: PartitionDetector, protocolPrefix?: string, config?: BlockTransferConfig);
76
+ constructor(
77
+ /**
78
+ * The node's OWN store, proof accessor REQUIRED (not the optional `ArchiveServingRepo`
79
+ * shape): every push this class makes is certified out of it, and a repo without the
80
+ * accessor would make `sourceBlockCertification` return meta-only for every block — so
81
+ * every push would be refused by a receiver running the default `requirePushCertificate`,
82
+ * silently and with no type error. Same reasoning as `createServedRepoProxy`'s.
83
+ */
84
+ repo: ProofRetainingRepo, peerNetwork: IPeerNetwork, restorationCoordinator: RestorationCoordinator, partitionDetector: PartitionDetector, protocolPrefix?: string, config?: BlockTransferConfig);
53
85
  /**
54
86
  * Pull blocks that this node has gained responsibility for.
55
87
  * Uses RestorationCoordinator to discover holders and fetch block data.
@@ -76,6 +108,27 @@ export declare class BlockTransferCoordinator {
76
108
  * hole (`docs/arachnode-ring-handoff.md` § Why the current code violates it #2).
77
109
  */
78
110
  handleRebalanceEvent(event: RebalanceEvent): Promise<RebalanceReactionResult>;
111
+ /**
112
+ * Push each GROWN block (still owned; new peers became co-responsible) to its newly
113
+ * co-responsible peers, reusing {@link executeConfirm} per block. The per-block floor is
114
+ * `min(event floor, new-peer count)`: passing the raw event floor would be wrong when fewer new
115
+ * peers exist than the floor — `executeConfirm` could then never reach the floor and would burn
116
+ * `maxRetries` re-pushing peers that already accepted. Nothing is released off this path (the
117
+ * node KEEPS the block either way); the confirmed/unconfirmed split is reporting only. The
118
+ * in-flight `confirm:<id>` key dedups against a concurrent lost-confirm for the same block —
119
+ * such a block gets NO `growth` entry (no information), so the monitor leaves it untouched.
120
+ * `enablePush` deliberately does not gate this (same rationale as the NOTE in
121
+ * {@link confirmReplicated}); the growth arm as a whole is gated by the `rebalance.enabled`
122
+ * wiring in `libp2p-node-base`.
123
+ *
124
+ * Per-block {@link GrowthOutcome} rules:
125
+ * - floor met → all reported peers satisfied, complete. Deliberately includes peers
126
+ * `executeConfirm` skipped once the floor was reached — the block is adequately replicated,
127
+ * and re-pushing the remainder on every check forever would be a live loop.
128
+ * - no local data → all reported peers satisfied, complete (nothing to replicate; see NOTE).
129
+ * - otherwise → only the peers that actually confirmed, incomplete (retried by the monitor).
130
+ */
131
+ private replicateGrown;
79
132
  /**
80
133
  * Confirm each block is replicated to at least `floor` qualifying owners — the gate the ring-shift
81
134
  * handoff (Phase B) and the rebalance release both open before a block may stop being served.
@@ -99,10 +152,17 @@ export declare class BlockTransferCoordinator {
99
152
  private executePull;
100
153
  private executePush;
101
154
  /**
102
- * Confirm one block replicated to ≥ `floor` distinct qualifying owners. Reads the local block once,
103
- * pushes to each candidate owner (stopping once the floor is reached), and counts distinct owners
104
- * that report holding it (not `missing`). Retries the whole round up to `maxRetries` before giving
105
- * up. Records the block in `confirmed` iff the floor was met, otherwise in `unconfirmed`.
155
+ * Confirm one block replicated to ≥ `floor` distinct qualifying owners. Reads the local block once
156
+ * per attempt, pushes to each candidate owner (stopping once the floor is reached), and counts
157
+ * distinct owners that report holding it (not `missing`). Retries the whole round up to
158
+ * `maxRetries` before giving up.
159
+ *
160
+ * Returns `null` when a confirm for this block is already in flight (no information — the caller
161
+ * must not record anything for it). Otherwise: `confirmed` iff the floor was met; `confirmedPeers`
162
+ * is the union of owners that confirmed across every attempt (a peer that accepted a push holds a
163
+ * replica even if a later round missed it — the floor decision itself stays per-round, unchanged);
164
+ * `noLocalData` marks the nothing-local-to-push case. The lost-block release path uses only
165
+ * `confirmed`; the growth arm consumes the other two.
106
166
  */
107
167
  private executeConfirm;
108
168
  private acquireSemaphore;
@@ -1 +1 @@
1
- {"version":3,"file":"block-transfer.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAEpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAK7D,MAAM,WAAW,mBAAmB;IACnC,2CAA2C;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,uBAAuB;IACvC,oEAAoE;IACpE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,wFAAwF;IACxF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,qBAAa,wBAAwB;IAUnC,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAbhC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;gBAGjC,IAAI,EAAE,KAAK,EACX,WAAW,EAAE,YAAY,EACzB,sBAAsB,EAAE,sBAAsB,EAC9C,iBAAiB,EAAE,iBAAiB,EACpC,cAAc,GAAE,MAAW,EAC5C,MAAM,GAAE,mBAAwB;IAQjC;;;OAGG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAgBxF;;OAEG;IACG,UAAU,CACf,QAAQ,EAAE,MAAM,EAAE,EAClB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAC9B,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAmBrD;;;;;;;;;OASG;IACG,oBAAoB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAsBnF;;;;;;;;;;;;;;;OAeG;IACG,iBAAiB,CACtB,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;YAyB5C,WAAW;YAyCX,WAAW;IA0EzB;;;;;OAKG;YACW,cAAc;YAgFd,gBAAgB;IAS9B,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,WAAW;CAMnB"}
1
+ {"version":3,"file":"block-transfer.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer.ts"],"names":[],"mappings":"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"}