@optimystic/db-p2p 0.13.5 → 0.14.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 (342) hide show
  1. package/README.md +6 -6
  2. package/dist/src/cluster/block-transfer-service.d.ts +67 -8
  3. package/dist/src/cluster/block-transfer-service.d.ts.map +1 -1
  4. package/dist/src/cluster/block-transfer-service.js +101 -62
  5. package/dist/src/cluster/block-transfer-service.js.map +1 -1
  6. package/dist/src/cluster/client.d.ts +18 -1
  7. package/dist/src/cluster/client.d.ts.map +1 -1
  8. package/dist/src/cluster/client.js +55 -39
  9. package/dist/src/cluster/client.js.map +1 -1
  10. package/dist/src/cluster/cluster-error.d.ts +38 -0
  11. package/dist/src/cluster/cluster-error.d.ts.map +1 -0
  12. package/dist/src/cluster/cluster-error.js +51 -0
  13. package/dist/src/cluster/cluster-error.js.map +1 -0
  14. package/dist/src/cluster/cluster-repo.d.ts +135 -3
  15. package/dist/src/cluster/cluster-repo.d.ts.map +1 -1
  16. package/dist/src/cluster/cluster-repo.js +333 -58
  17. package/dist/src/cluster/cluster-repo.js.map +1 -1
  18. package/dist/src/cluster/commit-cert.d.ts +63 -0
  19. package/dist/src/cluster/commit-cert.d.ts.map +1 -0
  20. package/dist/src/cluster/commit-cert.js +108 -0
  21. package/dist/src/cluster/commit-cert.js.map +1 -0
  22. package/dist/src/cluster/service.d.ts +46 -11
  23. package/dist/src/cluster/service.d.ts.map +1 -1
  24. package/dist/src/cluster/service.js +97 -33
  25. package/dist/src/cluster/service.js.map +1 -1
  26. package/dist/src/cluster/spread-on-churn.d.ts +13 -0
  27. package/dist/src/cluster/spread-on-churn.d.ts.map +1 -1
  28. package/dist/src/cluster/spread-on-churn.js +34 -4
  29. package/dist/src/cluster/spread-on-churn.js.map +1 -1
  30. package/dist/src/cohort-topic/bootstrap-evidence-builder.d.ts +59 -0
  31. package/dist/src/cohort-topic/bootstrap-evidence-builder.d.ts.map +1 -0
  32. package/dist/src/cohort-topic/bootstrap-evidence-builder.js +79 -0
  33. package/dist/src/cohort-topic/bootstrap-evidence-builder.js.map +1 -0
  34. package/dist/src/cohort-topic/bootstrap-evidence-verifiers.d.ts +81 -0
  35. package/dist/src/cohort-topic/bootstrap-evidence-verifiers.d.ts.map +1 -0
  36. package/dist/src/cohort-topic/bootstrap-evidence-verifiers.js +93 -0
  37. package/dist/src/cohort-topic/bootstrap-evidence-verifiers.js.map +1 -0
  38. package/dist/src/cohort-topic/bootstrap-parent-reference.d.ts +108 -0
  39. package/dist/src/cohort-topic/bootstrap-parent-reference.d.ts.map +1 -0
  40. package/dist/src/cohort-topic/bootstrap-parent-reference.js +108 -0
  41. package/dist/src/cohort-topic/bootstrap-parent-reference.js.map +1 -0
  42. package/dist/src/cohort-topic/change-bridge.d.ts +65 -0
  43. package/dist/src/cohort-topic/change-bridge.d.ts.map +1 -0
  44. package/dist/src/cohort-topic/change-bridge.js +76 -0
  45. package/dist/src/cohort-topic/change-bridge.js.map +1 -0
  46. package/dist/src/cohort-topic/cohort-gossip-driver.d.ts +74 -0
  47. package/dist/src/cohort-topic/cohort-gossip-driver.d.ts.map +1 -0
  48. package/dist/src/cohort-topic/cohort-gossip-driver.js +87 -0
  49. package/dist/src/cohort-topic/cohort-gossip-driver.js.map +1 -0
  50. package/dist/src/cohort-topic/cohort-gossip-transport.d.ts +42 -0
  51. package/dist/src/cohort-topic/cohort-gossip-transport.d.ts.map +1 -0
  52. package/dist/src/cohort-topic/cohort-gossip-transport.js +57 -0
  53. package/dist/src/cohort-topic/cohort-gossip-transport.js.map +1 -0
  54. package/dist/src/cohort-topic/fret-trust-anchor.d.ts +100 -0
  55. package/dist/src/cohort-topic/fret-trust-anchor.d.ts.map +1 -0
  56. package/dist/src/cohort-topic/fret-trust-anchor.js +115 -0
  57. package/dist/src/cohort-topic/fret-trust-anchor.js.map +1 -0
  58. package/dist/src/cohort-topic/host.d.ts +573 -0
  59. package/dist/src/cohort-topic/host.d.ts.map +1 -0
  60. package/dist/src/cohort-topic/host.js +1460 -0
  61. package/dist/src/cohort-topic/host.js.map +1 -0
  62. package/dist/src/cohort-topic/index.d.ts +14 -0
  63. package/dist/src/cohort-topic/index.d.ts.map +1 -0
  64. package/dist/src/cohort-topic/index.js +14 -0
  65. package/dist/src/cohort-topic/index.js.map +1 -0
  66. package/dist/src/cohort-topic/membership-publish-sink.d.ts +14 -0
  67. package/dist/src/cohort-topic/membership-publish-sink.d.ts.map +1 -0
  68. package/dist/src/cohort-topic/membership-publish-sink.js +17 -0
  69. package/dist/src/cohort-topic/membership-publish-sink.js.map +1 -0
  70. package/dist/src/cohort-topic/membership-source.d.ts +36 -0
  71. package/dist/src/cohort-topic/membership-source.d.ts.map +1 -0
  72. package/dist/src/cohort-topic/membership-source.js +58 -0
  73. package/dist/src/cohort-topic/membership-source.js.map +1 -0
  74. package/dist/src/cohort-topic/peer-codec.d.ts +18 -0
  75. package/dist/src/cohort-topic/peer-codec.d.ts.map +1 -0
  76. package/dist/src/cohort-topic/peer-codec.js +26 -0
  77. package/dist/src/cohort-topic/peer-codec.js.map +1 -0
  78. package/dist/src/cohort-topic/peer-sig.d.ts +52 -0
  79. package/dist/src/cohort-topic/peer-sig.d.ts.map +1 -0
  80. package/dist/src/cohort-topic/peer-sig.js +83 -0
  81. package/dist/src/cohort-topic/peer-sig.js.map +1 -0
  82. package/dist/src/cohort-topic/protocols.d.ts +49 -0
  83. package/dist/src/cohort-topic/protocols.d.ts.map +1 -0
  84. package/dist/src/cohort-topic/protocols.js +58 -0
  85. package/dist/src/cohort-topic/protocols.js.map +1 -0
  86. package/dist/src/cohort-topic/reactivity-membership-gate.d.ts +49 -0
  87. package/dist/src/cohort-topic/reactivity-membership-gate.d.ts.map +1 -0
  88. package/dist/src/cohort-topic/reactivity-membership-gate.js +42 -0
  89. package/dist/src/cohort-topic/reactivity-membership-gate.js.map +1 -0
  90. package/dist/src/cohort-topic/size-estimator.d.ts +16 -0
  91. package/dist/src/cohort-topic/size-estimator.d.ts.map +1 -0
  92. package/dist/src/cohort-topic/size-estimator.js +16 -0
  93. package/dist/src/cohort-topic/size-estimator.js.map +1 -0
  94. package/dist/src/cohort-topic/stream-util.d.ts +19 -0
  95. package/dist/src/cohort-topic/stream-util.d.ts.map +1 -0
  96. package/dist/src/cohort-topic/stream-util.js +76 -0
  97. package/dist/src/cohort-topic/stream-util.js.map +1 -0
  98. package/dist/src/cohort-topic/threshold-crypto.d.ts +94 -0
  99. package/dist/src/cohort-topic/threshold-crypto.d.ts.map +1 -0
  100. package/dist/src/cohort-topic/threshold-crypto.js +178 -0
  101. package/dist/src/cohort-topic/threshold-crypto.js.map +1 -0
  102. package/dist/src/cohort-topic/topic-router.d.ts +41 -0
  103. package/dist/src/cohort-topic/topic-router.d.ts.map +1 -0
  104. package/dist/src/cohort-topic/topic-router.js +63 -0
  105. package/dist/src/cohort-topic/topic-router.js.map +1 -0
  106. package/dist/src/dispute/cascade.d.ts +179 -0
  107. package/dist/src/dispute/cascade.d.ts.map +1 -0
  108. package/dist/src/dispute/cascade.js +315 -0
  109. package/dist/src/dispute/cascade.js.map +1 -0
  110. package/dist/src/dispute/client.d.ts +2 -1
  111. package/dist/src/dispute/client.d.ts.map +1 -1
  112. package/dist/src/dispute/client.js +12 -3
  113. package/dist/src/dispute/client.js.map +1 -1
  114. package/dist/src/dispute/dispute-service.d.ts +41 -1
  115. package/dist/src/dispute/dispute-service.d.ts.map +1 -1
  116. package/dist/src/dispute/dispute-service.js +147 -21
  117. package/dist/src/dispute/dispute-service.js.map +1 -1
  118. package/dist/src/dispute/index.d.ts +2 -0
  119. package/dist/src/dispute/index.d.ts.map +1 -1
  120. package/dist/src/dispute/index.js +2 -0
  121. package/dist/src/dispute/index.js.map +1 -1
  122. package/dist/src/dispute/invalidation.d.ts +266 -0
  123. package/dist/src/dispute/invalidation.d.ts.map +1 -0
  124. package/dist/src/dispute/invalidation.js +405 -0
  125. package/dist/src/dispute/invalidation.js.map +1 -0
  126. package/dist/src/dispute/types.d.ts +14 -0
  127. package/dist/src/dispute/types.d.ts.map +1 -1
  128. package/dist/src/dispute/types.js.map +1 -1
  129. package/dist/src/index.d.ts +4 -0
  130. package/dist/src/index.d.ts.map +1 -1
  131. package/dist/src/index.js +4 -0
  132. package/dist/src/index.js.map +1 -1
  133. package/dist/src/libp2p-key-network.d.ts +7 -0
  134. package/dist/src/libp2p-key-network.d.ts.map +1 -1
  135. package/dist/src/libp2p-key-network.js +49 -5
  136. package/dist/src/libp2p-key-network.js.map +1 -1
  137. package/dist/src/libp2p-node-base.d.ts +45 -3
  138. package/dist/src/libp2p-node-base.d.ts.map +1 -1
  139. package/dist/src/libp2p-node-base.js +522 -5
  140. package/dist/src/libp2p-node-base.js.map +1 -1
  141. package/dist/src/matchmaking/aggregate-counts.d.ts +67 -0
  142. package/dist/src/matchmaking/aggregate-counts.d.ts.map +1 -0
  143. package/dist/src/matchmaking/aggregate-counts.js +60 -0
  144. package/dist/src/matchmaking/aggregate-counts.js.map +1 -0
  145. package/dist/src/matchmaking/index.d.ts +20 -0
  146. package/dist/src/matchmaking/index.d.ts.map +1 -0
  147. package/dist/src/matchmaking/index.js +20 -0
  148. package/dist/src/matchmaking/index.js.map +1 -0
  149. package/dist/src/matchmaking/module.d.ts +181 -0
  150. package/dist/src/matchmaking/module.d.ts.map +1 -0
  151. package/dist/src/matchmaking/module.js +221 -0
  152. package/dist/src/matchmaking/module.js.map +1 -0
  153. package/dist/src/matchmaking/protocols.d.ts +37 -0
  154. package/dist/src/matchmaking/protocols.d.ts.map +1 -0
  155. package/dist/src/matchmaking/protocols.js +42 -0
  156. package/dist/src/matchmaking/protocols.js.map +1 -0
  157. package/dist/src/matchmaking/provider-manager.d.ts +52 -0
  158. package/dist/src/matchmaking/provider-manager.d.ts.map +1 -0
  159. package/dist/src/matchmaking/provider-manager.js +74 -0
  160. package/dist/src/matchmaking/provider-manager.js.map +1 -0
  161. package/dist/src/matchmaking/query-handler.d.ts +34 -0
  162. package/dist/src/matchmaking/query-handler.d.ts.map +1 -0
  163. package/dist/src/matchmaking/query-handler.js +62 -0
  164. package/dist/src/matchmaking/query-handler.js.map +1 -0
  165. package/dist/src/matchmaking/query-transport.d.ts +180 -0
  166. package/dist/src/matchmaking/query-transport.d.ts.map +1 -0
  167. package/dist/src/matchmaking/query-transport.js +315 -0
  168. package/dist/src/matchmaking/query-transport.js.map +1 -0
  169. package/dist/src/matchmaking/seeker-manager.d.ts +39 -0
  170. package/dist/src/matchmaking/seeker-manager.d.ts.map +1 -0
  171. package/dist/src/matchmaking/seeker-manager.js +49 -0
  172. package/dist/src/matchmaking/seeker-manager.js.map +1 -0
  173. package/dist/src/matchmaking/seeker-walk-client.d.ts +127 -0
  174. package/dist/src/matchmaking/seeker-walk-client.d.ts.map +1 -0
  175. package/dist/src/matchmaking/seeker-walk-client.js +189 -0
  176. package/dist/src/matchmaking/seeker-walk-client.js.map +1 -0
  177. package/dist/src/matchmaking/traffic-validation.d.ts +128 -0
  178. package/dist/src/matchmaking/traffic-validation.d.ts.map +1 -0
  179. package/dist/src/matchmaking/traffic-validation.js +105 -0
  180. package/dist/src/matchmaking/traffic-validation.js.map +1 -0
  181. package/dist/src/network/network-manager-service.d.ts +4 -2
  182. package/dist/src/network/network-manager-service.d.ts.map +1 -1
  183. package/dist/src/network/network-manager-service.js +9 -3
  184. package/dist/src/network/network-manager-service.js.map +1 -1
  185. package/dist/src/protocol-client.d.ts +13 -0
  186. package/dist/src/protocol-client.d.ts.map +1 -1
  187. package/dist/src/protocol-client.js +74 -2
  188. package/dist/src/protocol-client.js.map +1 -1
  189. package/dist/src/reactivity/forwarder-host.d.ts +198 -0
  190. package/dist/src/reactivity/forwarder-host.d.ts.map +1 -0
  191. package/dist/src/reactivity/forwarder-host.js +355 -0
  192. package/dist/src/reactivity/forwarder-host.js.map +1 -0
  193. package/dist/src/reactivity/index.d.ts +19 -0
  194. package/dist/src/reactivity/index.d.ts.map +1 -0
  195. package/dist/src/reactivity/index.js +19 -0
  196. package/dist/src/reactivity/index.js.map +1 -0
  197. package/dist/src/reactivity/notify-transport.d.ts +70 -0
  198. package/dist/src/reactivity/notify-transport.d.ts.map +1 -0
  199. package/dist/src/reactivity/notify-transport.js +111 -0
  200. package/dist/src/reactivity/notify-transport.js.map +1 -0
  201. package/dist/src/reactivity/origination-manager.d.ts +110 -0
  202. package/dist/src/reactivity/origination-manager.d.ts.map +1 -0
  203. package/dist/src/reactivity/origination-manager.js +129 -0
  204. package/dist/src/reactivity/origination-manager.js.map +1 -0
  205. package/dist/src/reactivity/protocols.d.ts +43 -0
  206. package/dist/src/reactivity/protocols.d.ts.map +1 -0
  207. package/dist/src/reactivity/protocols.js +50 -0
  208. package/dist/src/reactivity/protocols.js.map +1 -0
  209. package/dist/src/reactivity/push-state-gossip.d.ts +132 -0
  210. package/dist/src/reactivity/push-state-gossip.d.ts.map +1 -0
  211. package/dist/src/reactivity/push-state-gossip.js +231 -0
  212. package/dist/src/reactivity/push-state-gossip.js.map +1 -0
  213. package/dist/src/reactivity/recover-transport.d.ts +167 -0
  214. package/dist/src/reactivity/recover-transport.d.ts.map +1 -0
  215. package/dist/src/reactivity/recover-transport.js +308 -0
  216. package/dist/src/reactivity/recover-transport.js.map +1 -0
  217. package/dist/src/reactivity/rotation-rereg-scheduler.d.ts +142 -0
  218. package/dist/src/reactivity/rotation-rereg-scheduler.d.ts.map +1 -0
  219. package/dist/src/reactivity/rotation-rereg-scheduler.js +223 -0
  220. package/dist/src/reactivity/rotation-rereg-scheduler.js.map +1 -0
  221. package/dist/src/reactivity/subscriber-registry.d.ts +47 -0
  222. package/dist/src/reactivity/subscriber-registry.d.ts.map +1 -0
  223. package/dist/src/reactivity/subscriber-registry.js +87 -0
  224. package/dist/src/reactivity/subscriber-registry.js.map +1 -0
  225. package/dist/src/reactivity/subscription-manager.d.ts +221 -0
  226. package/dist/src/reactivity/subscription-manager.d.ts.map +1 -0
  227. package/dist/src/reactivity/subscription-manager.js +302 -0
  228. package/dist/src/reactivity/subscription-manager.js.map +1 -0
  229. package/dist/src/reactivity/topic-bytes.d.ts +32 -0
  230. package/dist/src/reactivity/topic-bytes.d.ts.map +1 -0
  231. package/dist/src/reactivity/topic-bytes.js +34 -0
  232. package/dist/src/reactivity/topic-bytes.js.map +1 -0
  233. package/dist/src/repo/client.d.ts.map +1 -1
  234. package/dist/src/repo/client.js +51 -23
  235. package/dist/src/repo/client.js.map +1 -1
  236. package/dist/src/repo/service.d.ts +46 -1
  237. package/dist/src/repo/service.d.ts.map +1 -1
  238. package/dist/src/repo/service.js +79 -45
  239. package/dist/src/repo/service.js.map +1 -1
  240. package/dist/src/rpc-deadline.d.ts +37 -0
  241. package/dist/src/rpc-deadline.d.ts.map +1 -0
  242. package/dist/src/rpc-deadline.js +31 -0
  243. package/dist/src/rpc-deadline.js.map +1 -0
  244. package/dist/src/storage/block-storage.d.ts +2 -0
  245. package/dist/src/storage/block-storage.d.ts.map +1 -1
  246. package/dist/src/storage/block-storage.js +95 -2
  247. package/dist/src/storage/block-storage.js.map +1 -1
  248. package/dist/src/storage/i-block-storage.d.ts +25 -0
  249. package/dist/src/storage/i-block-storage.d.ts.map +1 -1
  250. package/dist/src/storage/storage-repo.d.ts +53 -2
  251. package/dist/src/storage/storage-repo.d.ts.map +1 -1
  252. package/dist/src/storage/storage-repo.js +193 -9
  253. package/dist/src/storage/storage-repo.js.map +1 -1
  254. package/dist/src/sync/client.d.ts +4 -1
  255. package/dist/src/sync/client.d.ts.map +1 -1
  256. package/dist/src/sync/client.js +5 -2
  257. package/dist/src/sync/client.js.map +1 -1
  258. package/dist/src/testing/cohort-topic-mesh-harness.d.ts +219 -0
  259. package/dist/src/testing/cohort-topic-mesh-harness.d.ts.map +1 -0
  260. package/dist/src/testing/cohort-topic-mesh-harness.js +467 -0
  261. package/dist/src/testing/cohort-topic-mesh-harness.js.map +1 -0
  262. package/dist/src/testing/matchmaking-mesh-harness.d.ts +187 -0
  263. package/dist/src/testing/matchmaking-mesh-harness.d.ts.map +1 -0
  264. package/dist/src/testing/matchmaking-mesh-harness.js +358 -0
  265. package/dist/src/testing/matchmaking-mesh-harness.js.map +1 -0
  266. package/dist/src/testing/mesh-harness.d.ts.map +1 -1
  267. package/dist/src/testing/mesh-harness.js +23 -1
  268. package/dist/src/testing/mesh-harness.js.map +1 -1
  269. package/dist/src/testing/reactivity-mesh-harness.d.ts +298 -0
  270. package/dist/src/testing/reactivity-mesh-harness.d.ts.map +1 -0
  271. package/dist/src/testing/reactivity-mesh-harness.js +663 -0
  272. package/dist/src/testing/reactivity-mesh-harness.js.map +1 -0
  273. package/package.json +7 -4
  274. package/src/cluster/block-transfer-service.ts +133 -68
  275. package/src/cluster/client.ts +64 -45
  276. package/src/cluster/cluster-error.ts +64 -0
  277. package/src/cluster/cluster-repo.ts +405 -55
  278. package/src/cluster/commit-cert.ts +139 -0
  279. package/src/cluster/service.ts +116 -44
  280. package/src/cluster/spread-on-churn.ts +328 -285
  281. package/src/cohort-topic/bootstrap-evidence-builder.ts +122 -0
  282. package/src/cohort-topic/bootstrap-evidence-verifiers.ts +132 -0
  283. package/src/cohort-topic/bootstrap-parent-reference.ts +159 -0
  284. package/src/cohort-topic/change-bridge.ts +109 -0
  285. package/src/cohort-topic/cohort-gossip-driver.ts +144 -0
  286. package/src/cohort-topic/cohort-gossip-transport.ts +74 -0
  287. package/src/cohort-topic/fret-trust-anchor.ts +153 -0
  288. package/src/cohort-topic/host.ts +2175 -0
  289. package/src/cohort-topic/index.ts +13 -0
  290. package/src/cohort-topic/membership-publish-sink.ts +20 -0
  291. package/src/cohort-topic/membership-source.ts +68 -0
  292. package/src/cohort-topic/peer-codec.ts +31 -0
  293. package/src/cohort-topic/peer-sig.ts +86 -0
  294. package/src/cohort-topic/protocols.ts +71 -0
  295. package/src/cohort-topic/reactivity-membership-gate.ts +77 -0
  296. package/src/cohort-topic/size-estimator.ts +16 -0
  297. package/src/cohort-topic/stream-util.ts +87 -0
  298. package/src/cohort-topic/threshold-crypto.ts +239 -0
  299. package/src/cohort-topic/topic-router.ts +77 -0
  300. package/src/dispute/cascade.ts +517 -0
  301. package/src/dispute/client.ts +12 -2
  302. package/src/dispute/dispute-service.ts +171 -24
  303. package/src/dispute/index.ts +42 -0
  304. package/src/dispute/invalidation.ts +587 -0
  305. package/src/dispute/types.ts +14 -0
  306. package/src/index.ts +4 -0
  307. package/src/libp2p-key-network.ts +49 -6
  308. package/src/libp2p-node-base.ts +620 -12
  309. package/src/matchmaking/aggregate-counts.ts +104 -0
  310. package/src/matchmaking/index.ts +20 -0
  311. package/src/matchmaking/module.ts +363 -0
  312. package/src/matchmaking/protocols.ts +51 -0
  313. package/src/matchmaking/provider-manager.ts +95 -0
  314. package/src/matchmaking/query-handler.ts +88 -0
  315. package/src/matchmaking/query-transport.ts +483 -0
  316. package/src/matchmaking/seeker-manager.ts +64 -0
  317. package/src/matchmaking/seeker-walk-client.ts +293 -0
  318. package/src/matchmaking/traffic-validation.ts +195 -0
  319. package/src/network/network-manager-service.ts +9 -2
  320. package/src/protocol-client.ts +64 -3
  321. package/src/reactivity/forwarder-host.ts +438 -0
  322. package/src/reactivity/index.ts +19 -0
  323. package/src/reactivity/notify-transport.ts +144 -0
  324. package/src/reactivity/origination-manager.ts +192 -0
  325. package/src/reactivity/protocols.ts +61 -0
  326. package/src/reactivity/push-state-gossip.ts +291 -0
  327. package/src/reactivity/recover-transport.ts +408 -0
  328. package/src/reactivity/rotation-rereg-scheduler.ts +256 -0
  329. package/src/reactivity/subscriber-registry.ts +96 -0
  330. package/src/reactivity/subscription-manager.ts +450 -0
  331. package/src/reactivity/topic-bytes.ts +37 -0
  332. package/src/repo/client.ts +54 -23
  333. package/src/repo/service.ts +90 -42
  334. package/src/rpc-deadline.ts +45 -0
  335. package/src/storage/block-storage.ts +106 -3
  336. package/src/storage/i-block-storage.ts +27 -0
  337. package/src/storage/storage-repo.ts +209 -13
  338. package/src/sync/client.ts +5 -2
  339. package/src/testing/cohort-topic-mesh-harness.ts +613 -0
  340. package/src/testing/matchmaking-mesh-harness.ts +475 -0
  341. package/src/testing/mesh-harness.ts +22 -2
  342. package/src/testing/reactivity-mesh-harness.ts +922 -0
@@ -0,0 +1,573 @@
1
+ /**
2
+ * Cohort-topic FRET host (`docs/cohort-topic.md` §FRET integration L768-803).
3
+ *
4
+ * Composes the db-core substrate (participant-facing {@link CohortTopicService} + cohort-side
5
+ * {@link CohortMemberEngine}) over the FRET + libp2p ports and runs it as a service on one node:
6
+ *
7
+ * - registers the four `/optimystic/cohort-topic/1.0.0/*` protocols on the libp2p node;
8
+ * - sets FRET's activity handler so a `RouteAndMaybeAct`-routed `RegisterV1` runs the cohort decision;
9
+ * - binds the db-core ports to the FRET-backed adapters (router, gossip, membership, size estimator).
10
+ *
11
+ * **Per-served-coord scoping.** A topic's responsible cohort sits at `coord_0(_, topicId)` (and at
12
+ * `coord_d(P, topicId)` for `d ≥ 1`), which is unrelated to any node's own ring position. A node
13
+ * genuinely belongs to *many* cohorts — one per coord FRET routes to it — so this host keeps a lazy
14
+ * {@link CoordRegistry}: a `Map<servedCoord, CoordEngine>` where each {@link CoordEngine} owns the
15
+ * per-coord slice of state (its own store, gossip bus, willingness/traffic/renewal/cold-start, a
16
+ * {@link PromotionLifecycle} with coord-derived tier inputs, a {@link CohortMemberEngine}, its own
17
+ * {@link MembershipCertPublisher}, and its own real `k − x` threshold signer) and threshold-signs with
18
+ * the FRET cohort *around the served coord*. The node-wide collaborators (`hash`, `slots`, `barometer`,
19
+ * the FRET ports, the participant-facing service, and the verify-only verifier signer) stay singletons
20
+ * and are injected into each engine. The host recomputes the served coord from each decoded `RegisterV1`
21
+ * (`addressing.coord(treeTier, participantCoord, topicId)`), so both the activity callback and the direct
22
+ * `register` protocol handler dispatch to the right cohort.
23
+ *
24
+ * **Real threshold signatures.** Each coord engine assembles a genuine `k − x` cohort signature
25
+ * (a collected per-member Ed25519 multisig) over the new `/sign` protocol — see
26
+ * {@link FretCohortThresholdCrypto} — and drives a {@link MembershipCertPublisher}, so a remote
27
+ * `MembershipVerifier` can verify the served `MembershipCertV1` for real. Assembly needs the node's
28
+ * `options.privateKey`; key-less hosts compose but cannot threshold-sign (the publisher/promotion paths
29
+ * are simply not driven). The periodic membership refresh is exposed as the per-engine
30
+ * {@link CoordEngine.pumpMembership} / {@link CoordEngine.onStabilized} hooks for the gossip-cadence
31
+ * driver to call.
32
+ *
33
+ * **Anti-DoS + cold-start (gaps 6–7).** Each {@link CoordEngine} is injected its own per-coord anti-DoS
34
+ * guards — a `RegisterRateLimiter` (4/min per peer-topic), a `CorrelationReplayGuard` (60 s freshness),
35
+ * and a `TopicBudget` (2048 topics, LRU) — so a budget/limit at one coord is independent of another. The
36
+ * node-level {@link BootstrapEvidence} policy (one tier→verifier policy, no per-coord state) is built once
37
+ * and shared. db-core embeds no PoW / reputation scheme, so the host supplies the real verifiers
38
+ * ({@link createPoWVerifier} / {@link createReputationVerifier}) and the participant-side PoW minter
39
+ * ({@link createBootstrapEvidenceBuilder}): once configured, a node gates cold-root `bootstrap: true` at
40
+ * T2/T3 (PoW, or a referee reputation endorsement when offered, or a signed parent reference) and at T0/T1
41
+ * once a committed-existence backing is wired (a signed parent reference); a configured node with no such
42
+ * backing keeps T0/T1 permissive-but-logged so cold-root origination is not blocked
43
+ * (`cohort-topic-bootstrap-coldstart-origination-regression`), and an entirely unconfigured host stays
44
+ * permissive-but-logged at every tier (never an undefined gate). A cold-started tier-`d > 0` forwarder registers with
45
+ * its tier-`(d − 1)` parent by routing a forwarder-link frame over the router (gap 7), staying
46
+ * `awaiting_parent` until the ack.
47
+ *
48
+ * **Scope.** `followOn` derivation for a promoted-redirect arrival is parked in backlog
49
+ * (`cohort-topic-followon-derivation`); this milestone serves a **single tier-0 cohort**, so `followOn`
50
+ * stays `false` and tier-0 bootstrap instantiation goes through the `bootstrap: true` path. The
51
+ * behavioral substrate is validated at mock-tier by `test/cohort-topic/service.spec.ts` and end-to-end
52
+ * across a real multi-node cohort (real Ed25519 keys, mock transport routing the five protocols + FRET
53
+ * `routeAct`/`assembleCohort`) by `test/cohort-topic/live-tier.spec.ts`.
54
+ */
55
+ import type { Libp2p } from "libp2p";
56
+ import type { PrivateKey } from "@libp2p/interface";
57
+ import type { FretService } from "p2p-fret";
58
+ import { LruMap, type BootstrapEvidenceDeps, type CohortGossipV1, type CohortTopicService, type CohortMemberEngine, type CohortSnapshotView, type CohortView, type CorrelationReplayGuardConfig, type DemotionNoticeV1, type Forwarder, type MembershipCertV1, type MembershipVerifier, type NodeProfile, type PromotionConfig, type PromotionNoticeV1, type RegisterRateLimiter, type RegisterRateLimiterConfig, type RegistrationRecord, type RenewReplyV1, type RenewV1, type RingCoord, type SignReplyV1, type SignRequestV1, type TopicBudgetConfig, type TopicTrafficV1, type TrustRoot } from "@optimystic/db-core";
59
+ import { FretCohortGossipTransport } from "./cohort-gossip-transport.js";
60
+ import { type BootstrapReputationView } from "./bootstrap-evidence-verifiers.js";
61
+ import { type BootstrapParentTopicView } from "./bootstrap-parent-reference.js";
62
+ import { type CohortTopicProtocols } from "./protocols.js";
63
+ export interface CohortTopicHostOptions {
64
+ /** Per-node tier profile. Default {@link coreProfile}. */
65
+ readonly profile?: NodeProfile;
66
+ /** Network name (namespaces the four protocol IDs); default uses the canonical IDs. */
67
+ readonly protocols?: CohortTopicProtocols;
68
+ /** Requested cohort size `wantK`. Default 16. */
69
+ readonly wantK?: number;
70
+ /** Threshold signers `minSigs = k − x`. Default {@link DEFAULT_MIN_SIGS}. */
71
+ readonly minSigs?: number;
72
+ /** Fan-out per tier `F`. Default 16. */
73
+ readonly fanout?: number;
74
+ /** Per-frame ceiling. Default {@link DEFAULT_STREAM_MAX_BYTES}. */
75
+ readonly maxBytes?: number;
76
+ /**
77
+ * Gossip-round cadence in ms (the periodic driver tick). Default {@link DEFAULT_GOSSIP_INTERVAL_MS}
78
+ * (~one round). Each tick drives every live {@link CoordEngine}'s gossip broadcast, TTL sweep,
79
+ * membership-cert refresh, and demotion check; the refresh (5 min) and demotion hysteresis (5 min)
80
+ * self-gate on elapsed time, so a fast tick is safe.
81
+ */
82
+ readonly gossipIntervalMs?: number;
83
+ /**
84
+ * The node's libp2p Ed25519 private key. Required for the live participant signer: register/renew
85
+ * bodies are peer-key-signed over their canonical image, and inbound register/`reattach` signatures
86
+ * are verified against the participant's claimed peer id. libp2p does not expose the key off
87
+ * `node.peerId`, so it is threaded explicitly (mirrors `clusterMember` / `DisputeService`, sourced
88
+ * from `options.privateKey ?? generateKeyPair('Ed25519')` in `libp2p-node-base.ts`). When omitted,
89
+ * the host falls back to the interim empty-string signer (one-time warn) and does **not** enforce
90
+ * inbound participant-signature verification, so unit tests compose without a key.
91
+ */
92
+ readonly privateKey?: PrivateKey;
93
+ /**
94
+ * Anti-DoS guard wiring (gap 6). The per-{@link CoordEngine} guards (rate limiter, replay guard,
95
+ * topic budget) and the node-level bootstrap-evidence policy are always constructed with documented
96
+ * defaults; this lets a caller (or a test) tune them. Omit for production defaults.
97
+ */
98
+ readonly antiDos?: CohortTopicAntiDosOptions;
99
+ /**
100
+ * Promotion / demotion lifecycle tuning (`cap_promote`, hysteresis windows, slope lookahead) applied
101
+ * to every {@link CoordEngine}'s {@link PromotionLifecycle}. Omit for the production defaults
102
+ * (`cap_promote = 64`, …); supply a lowered `capPromote` to drive promotion with a small participant
103
+ * count (the live-tier e2e). The single-cohort milestone never overrides `childCohortCount` / `treeTier`
104
+ * — those stay coord-derived — so only the count/load thresholds are tunable here.
105
+ */
106
+ readonly promotion?: PromotionConfig;
107
+ /**
108
+ * Optional committed-state existence reader backing the **committed-tier (T0/T1)** parent-reference
109
+ * bootstrap-evidence check (`cohort-topic-bootstrap-parent-reference`). Given `coord_0(parentTopicId)`,
110
+ * returns whether the node locally knows the parent topic's committed cohort exists. Threaded from
111
+ * node-base when a coord-keyed committed-membership index is available; when omitted, T0/T1 parent-ref
112
+ * existence fails closed (a FRET-cached cert must not vouch for committed-tier existence — committed-tier
113
+ * integrity) while T2/T3 parent-ref still consults the FRET membership cache. See
114
+ * {@link createDefaultParentTopicView}.
115
+ */
116
+ readonly committedParentTopicReader?: (coord: RingCoord) => boolean;
117
+ /**
118
+ * The participant's initial trust roots: the genesis-block-related cohorts, validated against the
119
+ * genesis block hash **out-of-band by the caller before seeding** (`docs/cohort-topic.md`
120
+ * §Bootstrapping trust). They are the base case of every attestation chain — a cert matching a root by
121
+ * `(coord, epoch, member-set)` is trusted directly, ahead of the FRET-ring direct anchor — so a forged
122
+ * cert for a genesis cohort is rejected even before the ring is consulted. Threaded straight into
123
+ * `createMembershipVerifier({ trustRoots })`.
124
+ *
125
+ * **Network-config, empty by default.** The concrete genesis-cohort set is a property of a specific
126
+ * network's genesis block; this is the typed seam, not a fabricated value. Omitted (the default `[]`)
127
+ * the verifier behaves exactly as with no roots — the chain bottoms out at the direct anchor / TOFU, so
128
+ * a network with no genesis cohort configured is never broken. Do **not** seed fake roots here.
129
+ */
130
+ readonly genesisTrustRoots?: readonly TrustRoot[];
131
+ /**
132
+ * Wall clock (ms) the `/sign` membership endorser uses for its `stabilizedAt` far-future sanity bound
133
+ * (a member refuses to co-sign a cert whose `stabilizedAt` is more than a few seconds ahead of its own
134
+ * clock — `cohort-topic-sign-endorsement-payload-binding`). Defaults to {@link Date.now}, the right
135
+ * choice for a production node. A **virtual-time** test harness (which drives publish `stabilizedAt`
136
+ * from arbitrary explicit timestamps rather than wall clock) injects a clock that does not trip the
137
+ * bound — e.g. `() => Number.POSITIVE_INFINITY` — so its synthetic future timestamps are not rejected.
138
+ */
139
+ readonly now?: () => number;
140
+ }
141
+ export type { BootstrapReputationView } from "./bootstrap-evidence-verifiers.js";
142
+ /**
143
+ * Anti-DoS wiring overrides for a {@link CohortTopicHost} (`docs/cohort-topic.md` §Anti-DoS).
144
+ *
145
+ * The rate limiter, replay guard, and topic budget are **per-served-coord** (they key on
146
+ * `(peer, topic)` / per-cohort topic state, which is coord-scoped) — one set is built per
147
+ * {@link CoordEngine} from these configs. The bootstrap-evidence policy is **node-level** (a
148
+ * tier→verifier policy with no per-coord state) and is shared by every engine.
149
+ */
150
+ export interface CohortTopicAntiDosOptions {
151
+ /** Per-`(peer, topic)` register rate limiter. Default `register_rate_per_peer = 4 / 60 s`, exponential back-off. */
152
+ readonly rateLimiter?: RegisterRateLimiterConfig;
153
+ /** Correlation-id freshness + replay guard. Default `maxAge = 60 s`, `futureSkew = 5 s`. */
154
+ readonly replayGuard?: CorrelationReplayGuardConfig;
155
+ /** Per-cohort forwarder-state budget. Default `topics_max = 2048`, LRU by participant count. */
156
+ readonly topicBudget?: TopicBudgetConfig;
157
+ /**
158
+ * Bootstrap-evidence verifiers for cold-root instantiation. db-core embeds no PoW / reputation /
159
+ * committed-work scheme; inject the real checks here. Any verifier supplied wins over the defaults
160
+ * below; the gate is **never** left undefined (an unset gate means cold-root bootstrap is
161
+ * unauthenticated — `docs/cohort-topic.md` §Anti-DoS).
162
+ */
163
+ readonly bootstrapEvidence?: BootstrapEvidenceDeps;
164
+ /**
165
+ * Optional peer-reputation view backing the **reputation-endorsement** evidence path: a *referee*
166
+ * peer-key-signs the bootstrap bound image, and the cohort admits it iff the signature verifies and
167
+ * the referee is sufficiently reputable here (not banned **and** below the deprioritize threshold).
168
+ * `PeerReputationService` satisfies this `{ isBanned, getScore }` shape directly. Supplying it (or any
169
+ * `bootstrapEvidence` override) makes the gate **configured**: the real PoW verifier runs, the referee
170
+ * verifier backs the reputation path, the real signed-parent-reference verifier backs the parent-ref path
171
+ * (permissive-but-logged only at T0/T1 when this host has no committed-existence backing — see
172
+ * {@link createBootstrapEvidencePolicy}), and any otherwise-unfilled verifier fails closed — so a
173
+ * banned/low-rep referee cannot slip the T2/T3 `PoW || reputation || parent-ref` disjunction. When omitted
174
+ * (and no `bootstrapEvidence` verifier is supplied), the gate is permissive-but-logged (the
175
+ * entirely-unconfigured interim node).
176
+ */
177
+ readonly reputation?: BootstrapReputationView;
178
+ /**
179
+ * Proof-of-work difficulty (leading zero bits) the real PoW verifier requires. Default the db-core
180
+ * `DEFAULT_POW_DIFFICULTY_BITS`. A low value (e.g. `0`) keeps minting fast/deterministic in tests.
181
+ * Applies to both the cohort-side PoW verifier and this node's participant-side PoW builder.
182
+ */
183
+ readonly powDifficultyBits?: number;
184
+ /**
185
+ * Strict "sufficient reputation" cutoff for a bootstrap referee — a referee with `getScore < this` is
186
+ * accepted. Default the reputation service's `deprioritize` threshold.
187
+ */
188
+ readonly deprioritizeThreshold?: number;
189
+ /**
190
+ * Existence view backing the **signed parent-reference** evidence path (`verifyParentReference`). A test
191
+ * seam: when supplied it overrides *which* existence view the real verifier consults (the host default is
192
+ * built from the FRET membership cache + addressing + the optional
193
+ * {@link CohortTopicHostOptions.committedParentTopicReader}). It does **not** by itself make the gate
194
+ * "configured" — only a `reputation` view or a `bootstrapEvidence` override flips that (see
195
+ * {@link createBootstrapEvidencePolicy}); an unconfigured host stays permissive and never consults this
196
+ * view. Pair it with `reputation`/`bootstrapEvidence` to exercise the real parent-reference verifier. See
197
+ * {@link createDefaultParentTopicView} / {@link createParentReferenceVerifier}.
198
+ */
199
+ readonly parentTopicView?: BootstrapParentTopicView;
200
+ }
201
+ /**
202
+ * One cohort the node serves, bound to a FRET-routed coordinate. Owns the per-coord slice of cohort
203
+ * state; the node-wide collaborators are injected (see {@link CoordEngineContext}).
204
+ */
205
+ export interface CoordEngine {
206
+ /** The served ring coordinate this engine is the cohort for. */
207
+ readonly servedCoord: RingCoord;
208
+ /** Tree tier `d` the served coord was instantiated at (fixed by the first register). */
209
+ readonly treeTier: number;
210
+ /** Cohort-side register/renew/sweep engine driven by the protocol handlers + activity callback. */
211
+ readonly engine: CohortMemberEngine;
212
+ /** The FRET-assembled cohort around {@link servedCoord} (self prepended, deduped) + epoch. */
213
+ cohort(): CohortSnapshotView;
214
+ /**
215
+ * The cohort member peer-id strings this engine served under `epoch` (the **current** or the
216
+ * immediately-**prior** observed epoch), or `undefined` if it tracked no such epoch. Drives the `/sign`
217
+ * `"rotation"` endorsement gate: a member endorses a hand-off from `prevEpoch` only when it was a member
218
+ * of the cohort at that epoch. Returns `undefined` past the two-deep history (a rapid double rotation —
219
+ * the requester then re-anchors). See `cohort-topic-trust-anchor-rotation-production`.
220
+ */
221
+ cohortIdentityAt(epoch: Uint8Array): readonly string[] | undefined;
222
+ /** True iff this engine currently holds any registration record (a cold probe leaves it empty). */
223
+ hasState(): boolean;
224
+ /** True iff this engine holds the record for `(topicId, participantId)` — the renewal lookup key. */
225
+ holds(topicId: Uint8Array, participantId: Uint8Array): boolean;
226
+ /**
227
+ * This cohort's locally-known direct registration records for `topicId` (the cohort-side read the
228
+ * matchmaking `QueryV1` handler / aggregate-count producer serve from — `docs/matchmaking.md`
229
+ * §Seeker query). A renewed record is live; a TTL-swept one is gone after the next `gossipRound`.
230
+ */
231
+ records(topicId: Uint8Array): readonly RegistrationRecord[];
232
+ /**
233
+ * This cohort's current gossip-derived traffic barometer for `topicId` (own last-published counts +
234
+ * siblings' last-gossiped summaries + `directParticipants` from the store). The matchmaking `QueryV1`
235
+ * reply attaches it and the seeker hang-out decision consumes it (`docs/matchmaking.md` §Hang-out vs.
236
+ * continue). Non-mutating — a synchronous read over the same in-memory state a `gossipRound` mutates,
237
+ * lagging at most one gossip round (it reflects the last frozen summaries, never raw mid-round counts).
238
+ */
239
+ topicTraffic(topicId: Uint8Array): TopicTrafficV1;
240
+ /**
241
+ * Publish a fresh threshold-signed `MembershipCertV1` on a cohort-membership-change / stabilization
242
+ * event (republishes only when the first `k − x` members changed). Returns the cert if published.
243
+ * Resolves `undefined` if no republish was needed or the quorum was unreachable this round.
244
+ */
245
+ onStabilized(now: number): Promise<MembershipCertV1 | undefined>;
246
+ /**
247
+ * Periodic membership-cert refresh hook for the gossip-cadence driver to call (republishes once
248
+ * `T_membership_refresh` has elapsed). Returns the cert if (re)published, else `undefined`.
249
+ */
250
+ pumpMembership(now: number): Promise<MembershipCertV1 | undefined>;
251
+ /**
252
+ * One gossip round: TTL-sweep stale records (firing the `evicted` deltas), freeze the per-topic
253
+ * traffic summaries, drain the accumulated record/eviction deltas, and broadcast a signed
254
+ * {@link CohortGossipV1} (willingness/load/traffic + deltas) to the cohort. Returns the broadcast
255
+ * frame, or `undefined` when the engine is idle (no resident topics and no deltas → nothing to send).
256
+ */
257
+ gossipRound(now: number): Promise<CohortGossipV1 | undefined>;
258
+ /**
259
+ * Time-driven demotion check across this engine's resident topics; broadcasts any threshold-signed
260
+ * {@link DemotionNoticeV1} the lifecycle returns (root tier-0 cohorts never demote). No-op without a
261
+ * signing key (the verify-only per-coord signer cannot assemble a notice).
262
+ */
263
+ demotionTick(now: number): Promise<void>;
264
+ /** The merged per-member gossip view (willingness / load / per-topic summaries) for this cohort. */
265
+ cohortView(): CohortView;
266
+ /** True iff this engine currently serves `topicId` (holds a record or a cold-start forwarder for it). */
267
+ servesTopic(topicId: Uint8Array): boolean;
268
+ /**
269
+ * Whether `topicId` currently occupies a slot in this coord's anti-DoS topic budget. A drained topic
270
+ * stays resident-but-cold (`{@link budgetParticipantCount} === 0`) until a new topic reuses its slot;
271
+ * after that reuse `budgetHasTopic` is `false`. Test/diagnostic introspection over the per-coord budget
272
+ * (distinct from {@link servesTopic}, which a never-demoted cold-start forwarder keeps `true`).
273
+ */
274
+ budgetHasTopic(topicId: Uint8Array): boolean;
275
+ /**
276
+ * The direct-participant count the topic budget last recorded for a resident `topicId` (its LRU
277
+ * eviction key), or `undefined` when `topicId` holds no budget slot. A resident reporting `0` has
278
+ * drained and is the next coldest-evictable candidate. Test/diagnostic introspection.
279
+ */
280
+ budgetParticipantCount(topicId: Uint8Array): number | undefined;
281
+ /**
282
+ * The cold-start {@link Forwarder} this engine instantiated for `topicId`, or `undefined` if none.
283
+ * Exposes the parent-link lifecycle (`awaiting_parent` → `serving`) for the cold-start wiring (gap 7).
284
+ */
285
+ forwarder(topicId: Uint8Array): Forwarder | undefined;
286
+ /** Whether `topicId` is in promoted mode here — reflects both locally-originated and remotely-applied state. */
287
+ isPromoted(topicId: Uint8Array): boolean;
288
+ /** Adopt a verified promotion notice into this cohort's local state (see {@link NoticeApplyTarget}). */
289
+ applyPromotionNotice(notice: PromotionNoticeV1, now: number): void;
290
+ /** Adopt a verified demotion notice into this cohort's local state (see {@link NoticeApplyTarget}). */
291
+ applyDemotionNotice(notice: DemotionNoticeV1, now: number): void;
292
+ /** Tear down the per-coord gossip subscription. */
293
+ close(): void;
294
+ }
295
+ /** Lazy `servedCoord → CoordEngine` registry: one engine per coord FRET routes to this node. */
296
+ export interface CoordRegistry {
297
+ /**
298
+ * The {@link CoordEngine} for `coord`, creating + caching it on first touch. `treeTier` and
299
+ * `participantCoord` seed a freshly-created engine's coord-derived tier inputs (ignored if the
300
+ * engine already exists). Synchronous, so concurrent activity callbacks for the same coord share
301
+ * one engine without a second being constructed.
302
+ */
303
+ forCoord(coord: RingCoord, treeTier: number, participantCoord: Uint8Array): CoordEngine;
304
+ /** The engine holding the record for `(topicId, participantId)`, or `undefined` (renewal dispatch). */
305
+ findHolder(topicId: Uint8Array, participantId: Uint8Array): CoordEngine | undefined;
306
+ /**
307
+ * The already-instantiated engine for `coord`, or `undefined` — a pure lookup that (unlike
308
+ * {@link forCoord}) never creates one. The `/sign` `"rotation"` endorsement gate uses it to consult this
309
+ * node's prior-epoch membership for the requested coord without spuriously instantiating a cohort it
310
+ * does not serve.
311
+ */
312
+ findByCoord(coord: RingCoord): CoordEngine | undefined;
313
+ /**
314
+ * The engine serving `topicId` at `treeTier`, or `undefined` (inbound promote/demote notice dispatch).
315
+ * A served coord embeds `(tier, topic)`, so at most one engine matches — the cohort the notice's
316
+ * signers belong to. `undefined` means this node serves no such cohort (e.g. a demotion arriving at a
317
+ * parent that does not track the child), so the notice is dropped rather than applied.
318
+ */
319
+ findServing(topicId: Uint8Array, treeTier: number): CoordEngine | undefined;
320
+ /** Every live engine (stop + sweep). */
321
+ all(): readonly CoordEngine[];
322
+ /** Close every engine's gossip subscription. */
323
+ close(): void;
324
+ }
325
+ /** A running cohort-topic node: the participant service plus the per-coord cohort registry, on one FRET node. */
326
+ export interface CohortTopicHost {
327
+ /** Participant-facing substrate API (node scope, not a coord). */
328
+ readonly service: CohortTopicService;
329
+ /** Per-served-coord cohort engines (driven by the protocol handlers + activity callback). */
330
+ readonly registry: CoordRegistry;
331
+ /** The four registered protocol IDs. */
332
+ readonly protocols: CohortTopicProtocols;
333
+ /**
334
+ * The node's effective {@link NodeProfile} (Edge / Core). Exposed so a layered application (reactivity)
335
+ * can apply the same profile gate the host configured its engines with (e.g. Edge ⇒ subscriber-only).
336
+ */
337
+ readonly profile: NodeProfile;
338
+ /**
339
+ * The intra-cohort gossip transport. Exposed so a layered application (reactivity push-state gossip) can
340
+ * ride its `broadcastOver` seam — the same one the promote-notice broadcast reuses — rather than standing
341
+ * up a second transport with duplicate cohort peer resolution.
342
+ */
343
+ readonly gossipTransport: FretCohortGossipTransport;
344
+ /**
345
+ * The node-level `promote`-handler anti-abuse gate (per-`(peer, topic)` rate limiter + per-`(topic, tier)`
346
+ * `effectiveAt` high-water). Exposed for test/diagnostic introspection over its bounded-memory state — the
347
+ * limiter's `size` and the `highWater` `LruMap` — and so the gossip-cadence sweep wiring is observable.
348
+ */
349
+ readonly promoteGate: PromoteGate;
350
+ /** Unregister the four protocols and tear down every coord engine. */
351
+ stop(): Promise<void>;
352
+ }
353
+ /**
354
+ * Build and start a {@link CohortTopicHost} on `node` over `fret`. Registers the four protocols and
355
+ * sets FRET's activity handler. Async because the node's ring coordinate is derived via FRET's
356
+ * `hashPeerId`.
357
+ */
358
+ export declare function createCohortTopicHost(node: Libp2p, fret: FretService, options?: CohortTopicHostOptions): Promise<CohortTopicHost>;
359
+ /**
360
+ * Resolve an inbound `RenewV1` to the coord engine holding its record and run the renewal. A `RenewV1`
361
+ * carries no `treeTier`, so the held record — not a recomputed coord — names the cohort. If no engine
362
+ * on this host holds it (cross-node renewal, post-restart eviction, or replication lag), reply
363
+ * `unknown_registration` so the participant's failover loop tries its backups and ultimately re-runs
364
+ * the `d_max` lookup (§TTL and renewal) — never throw.
365
+ */
366
+ export declare function resolveRenew(registry: CoordRegistry, renew: RenewV1, now: number): RenewReplyV1;
367
+ /** Dependencies for the `/sign` endorsement policy ({@link handleSignRequest}). */
368
+ export interface SignEndorsementDeps {
369
+ /** The node's libp2p key (signs the endorsement). Absent → every request is refused (no key to sign with). */
370
+ readonly privateKey: PrivateKey | undefined;
371
+ /** Self's dialable member id (UTF-8 peer-id string bytes). */
372
+ readonly selfMember: Uint8Array;
373
+ /** Cohort member peer-id strings around `coord` (self included). */
374
+ readonly cohortMembersAround: (coord: RingCoord) => string[];
375
+ /** Current cohort epoch (raw bytes) for `coord`. */
376
+ readonly currentEpoch: (coord: RingCoord) => Uint8Array;
377
+ /**
378
+ * For a `"rotation"` request: the cohort member peer-id strings this node served under `epoch` (the
379
+ * predecessor epoch carried as `request.cohortEpoch`), or `undefined` if it tracked no such epoch. The
380
+ * host wires it to the served coord's {@link CoordEngine.cohortIdentityAt}; absent → rotation
381
+ * endorsement is unavailable (a node with no per-coord rotation history refuses the hand-off).
382
+ */
383
+ readonly priorCohortMembersAt?: (coord: RingCoord, epoch: Uint8Array) => readonly string[] | undefined;
384
+ /**
385
+ * The endorser's own canonical `MembershipCertV1` signable fields for `coord` at its **current** epoch,
386
+ * re-derived from its own cohort snapshot ({@link membershipCertSignable} with `stabilizedAt`
387
+ * omitted/ignored). Binds a `membership` endorsement to the endorser's independent view so a cohort
388
+ * insider cannot collect honest signatures over a cert the cohort never agreed to (falsified `members`
389
+ * or `cohortCoord`). `cohortEpoch` here MUST equal `bytesToB64url(currentEpoch(coord))`; `members` is the
390
+ * ascending-sorted base64url cohort set (the cert / sharding order). Absent → a `membership` request is
391
+ * refused (no view to bind the cert against). See `cohort-topic-sign-endorsement-payload-binding`.
392
+ */
393
+ readonly expectedMembershipFields?: (coord: RingCoord) => {
394
+ cohortCoord: string;
395
+ cohortEpoch: string;
396
+ members: string[];
397
+ };
398
+ /**
399
+ * Wall clock (ms) for the `stabilizedAt` far-future sanity bound on a `membership` payload. The host
400
+ * wires {@link Date.now}; tests inject a fixed clock. Absent → the far-future bound is skipped (only
401
+ * finiteness is enforced), keeping minimal / key-less composition working.
402
+ */
403
+ readonly now?: () => number;
404
+ }
405
+ /**
406
+ * The `/sign` endorsement policy: decide whether to endorse a {@link SignRequestV1} and, if so, return
407
+ * this node's Ed25519 peer-key signature over the **exact** request payload. A member endorses only when
408
+ * both it and the requester are members of the cohort around `coord` under the request's epoch, **and**
409
+ * the payload bytes re-derive to something this node independently agrees to attest — so it never signs
410
+ * for outsiders and never blindly signs requester-supplied bytes. It still signs the exact image (no
411
+ * re-canonicalization), so the assembled signature verifies against what the requester collected.
412
+ *
413
+ * **Payload binding (cohort-topic-sign-endorsement-payload-binding).** The cohort + wire-epoch gates never
414
+ * inspect `request.payload`; without binding it an insider could collect honest signatures over a cert the
415
+ * cohort never agreed to. After those gates the endorser decodes the canonical signable image
416
+ * (`sig/payloads.ts` — a `JSON.parse`d array, NOT a `CohortMessageV1`) and refuses unless:
417
+ *
418
+ * - **all kinds** — the image tag matches the kind (`membership`→`MembershipCertV1`, etc.) and the
419
+ * payload-internal `cohortEpoch` equals this node's current epoch for `coord`; and
420
+ * - **`membership`** — `cohortCoord`, the full `members` list (deep-equal to the endorser's own ascending
421
+ * re-derived set), and a finite, not-far-future `stabilizedAt` all match its independent view
422
+ * ({@link SignEndorsementDeps.expectedMembershipFields}). Because epoch = H(members) in this host, the
423
+ * members and internal-epoch checks are mutually reinforcing: a forged member list cannot also carry the
424
+ * honest epoch. The participant verifier still independently re-checks `signers ⊆ cert.members`.
425
+ *
426
+ * The kind-specific **hot/cold** refinement for `promotion` / `demotion` (the endorser additionally
427
+ * requiring its own replicated `directParticipants` to be hot / cold) remains deferred: it needs a
428
+ * per-topic binding the `(payload, minSigs)` port can't carry and gossip record replication that is still
429
+ * interim. Parked in `cohort-topic-sign-endorsement-hotcold-refinement` (backlog).
430
+ *
431
+ * **`"rotation"` (epoch hand-off).** A rotation request carries the **prior** epoch as `cohortEpoch` and
432
+ * asks the outgoing cohort to sign the *successor* cert. The gate therefore checks **prior**-epoch
433
+ * membership instead of current: the endorser must have served the cohort at `prevEpoch`, and the
434
+ * requester must have been a member of that prior cohort too (the genuinely outgoing set). The verifier
435
+ * still independently re-checks `rotationSigners ⊆ predecessor-cert.members`, so this gate is the
436
+ * load-shedding sanity check, not the trust root. See `cohort-topic-trust-anchor-rotation-production`.
437
+ */
438
+ export declare function handleSignRequest(request: SignRequestV1, fromPeerStr: string, deps: SignEndorsementDeps): Promise<SignReplyV1>;
439
+ /** A decoded `promote`-protocol frame, tagged by which notice it is. */
440
+ export type InboundNotice = {
441
+ readonly kind: "promotion";
442
+ readonly notice: PromotionNoticeV1;
443
+ } | {
444
+ readonly kind: "demotion";
445
+ readonly notice: DemotionNoticeV1;
446
+ };
447
+ /** Outcome of {@link verifyAndApplyNotice}. */
448
+ export type NoticeOutcome = "applied" | "untrusted" | "dropped";
449
+ /**
450
+ * Outcome of {@link handleInboundNotice} — the {@link NoticeOutcome}s plus the cheap pre-verify drops the
451
+ * anti-abuse gate adds before any signature work runs:
452
+ *
453
+ * - `"undecodable"` — the frame is neither a promotion nor a demotion notice.
454
+ * - `"rate-limited"` — the dialing `(peer, topic)` is over its `register_rate_per_peer` ceiling.
455
+ * - `"stale"` — the notice's `effectiveAt` is at or below the last *applied* notice for its
456
+ * `(topic, tier)` (a replay / out-of-order frame); dropped before `verifyMessage`.
457
+ */
458
+ export type InboundNoticeResult = NoticeOutcome | "undecodable" | "rate-limited" | "stale";
459
+ /**
460
+ * Node-level anti-abuse state for the `promote` handler (`cohort-topic-promote-handler-verify-amplification`).
461
+ * The handler is node-level (one per node, not per coord), so unlike the per-{@link CoordEngine} register-path
462
+ * guards it owns its own instances here.
463
+ */
464
+ export interface PromoteGate {
465
+ /**
466
+ * Per-`(peer, topic)` inbound-notice rate limiter (reuses the register-path limiter). A peer streaming
467
+ * forged notices at one topic is dropped once it exceeds the ceiling, before any verify / membership work.
468
+ */
469
+ readonly rateLimiter: RegisterRateLimiter;
470
+ /**
471
+ * Per-`(topicId, tier)` high-water of the last *applied* notice's `effectiveAt`. A notice at or below the
472
+ * water is a replay / out-of-order frame and is dropped before verification. Updated **only** on an
473
+ * `"applied"` outcome (never on an unverified frame), so a forged notice carrying `effectiveAt = Infinity`
474
+ * cannot poison the water and lock out legitimate notices.
475
+ *
476
+ * **Bounded.** An {@link LruMap} capped at {@link PROMOTE_HIGHWATER_MAX_KEYS} so the retain-forever shape
477
+ * cannot leak on a long-lived node. Unlike the limiter this is *not* attacker-growable (it is written only
478
+ * on an `"applied"` outcome, which needs a verified `≥ minSigs` cohort signature — reads of forged
479
+ * `topicId`s via `.get` create nothing), so it never evicts under legitimate load; the cap is the
480
+ * belt-and-suspenders bound. Evicting an entry is safe: the engine's {@link PromotionLifecycle} is
481
+ * independently idempotent and `effectiveAt`-ordered (`PromotionState.lastEffectiveAt`), so an
482
+ * evicted-then-replayed older notice re-verifies (one bounded, rate-capped `verifyMessage`) and then
483
+ * **no-ops at the engine** rather than (re-)applying. Water absence only *opens* the gate, never closes it.
484
+ */
485
+ readonly highWater: LruMap<string, number>;
486
+ }
487
+ /**
488
+ * Hard cap on tracked `(topicId, tier)` high-water entries; the least-recently-touched are evicted beyond
489
+ * this. A modest bound is plenty — only verified applies grow the map, so it never evicts under legitimate
490
+ * load — but it caps the otherwise retain-forever shape on a long-lived node.
491
+ */
492
+ export declare const PROMOTE_HIGHWATER_MAX_KEYS = 8192;
493
+ /** Build the default {@link PromoteGate} from the (optional) anti-DoS rate-limiter config. */
494
+ export declare function createPromoteGate(rateLimiterConfig?: RegisterRateLimiterConfig): PromoteGate;
495
+ /**
496
+ * The slice of a {@link CoordEngine} the inbound notice path needs: the cohort coord the signers should
497
+ * belong to (for verification) and the apply hooks. {@link CoordEngine} satisfies this; tests can pass a
498
+ * minimal stand-in.
499
+ */
500
+ export interface NoticeApplyTarget {
501
+ readonly servedCoord: RingCoord;
502
+ applyPromotionNotice(notice: PromotionNoticeV1, now: number): void;
503
+ applyDemotionNotice(notice: DemotionNoticeV1, now: number): void;
504
+ }
505
+ /**
506
+ * Decode a `promote`-protocol frame as a {@link PromotionNoticeV1} or {@link DemotionNoticeV1} (try one,
507
+ * then the other), or `undefined` if it is neither. The two shapes are disjoint — a promotion carries
508
+ * `fromTier`/`toTier`, a demotion carries `parentCohortCoord` — so the structural validators cleanly
509
+ * discriminate.
510
+ */
511
+ export declare function decodeInboundNotice(frame: Uint8Array, maxBytes?: number): InboundNotice | undefined;
512
+ /**
513
+ * Per-coord minimum interval (ms) between membership refetches on the inbound `promote` path. Caps the
514
+ * amplification a flood of forged notices can drive: a stream of verify-misses triggers at most one
515
+ * `source.fetch()` per coord per this window, while a cold cache / membership rotation still re-fetches
516
+ * once it elapses (eventual refetch preserved). 60 s mirrors the anti-DoS rate window.
517
+ */
518
+ export declare const PROMOTE_REFETCH_MIN_INTERVAL_MS = 60000;
519
+ /**
520
+ * Verify an inbound notice's threshold signature against the cohort `MembershipCertV1` for
521
+ * `target.servedCoord` and, on success, apply it to the target's promotion lifecycle. Returns:
522
+ *
523
+ * - `"dropped"` — no local engine serves the notice's `(topic, tier)` (e.g. a demotion arriving at a
524
+ * parent that does not track the child); nothing to apply to.
525
+ * - `"untrusted"` — the `signers` are not a `≥ minSigs` subset of the cohort cert, or the multisig does
526
+ * not verify (a forged single-signer / short-quorum notice); local state is left unchanged.
527
+ * - `"applied"` — verified and applied.
528
+ *
529
+ * The payload is rebuilt with the canonical `sig/payloads` image the signer used — never re-canonicalized
530
+ * independently. The verifier owns the cert lookup; this function never re-verifies inside the apply step
531
+ * (db-core trusts this gate).
532
+ *
533
+ * **Bounded refetch (anti-amplification).** Both verify calls pass a {@link PROMOTE_REFETCH_MIN_INTERVAL_MS}
534
+ * refetch bound, so a stream of forged notices drives at most **one** membership `source.fetch()` per coord
535
+ * per interval rather than one dial per message. Eventual refetch is preserved (full suppression was
536
+ * rejected: a legitimate sibling-adopt / demotion-to-parent notice whose cohort cert is not yet locally
537
+ * cached must still be able to fetch it once — see `live-tier.spec.ts` test 4). A node that has cached its
538
+ * own cohort cert via `onCertPublished` verifies a sibling-adopt notice from cache with zero fetches; a
539
+ * cold-cache receiver pays one bounded fetch. Per `cohort-topic-promote-handler-verify-amplification`.
540
+ */
541
+ export declare function verifyAndApplyNotice(inbound: InboundNotice, target: NoticeApplyTarget | undefined, verifier: MembershipVerifier, now: number): Promise<NoticeOutcome>;
542
+ /**
543
+ * Full inbound `promote`-frame pipeline with the anti-abuse gate, exported so it is unit-testable without a
544
+ * live node (`cohort-topic-promote-handler-verify-amplification`). Runs the cheapest checks first — each
545
+ * step strictly cheaper than the next — so a flood of forged frames is shed before any signature / network
546
+ * work:
547
+ *
548
+ * ```
549
+ * decode → per-(peer,topic) rate limit → findServing → effectiveAt high-water → verify+apply
550
+ * ```
551
+ *
552
+ * - **Rate limit** (`gate.rateLimiter`) keys on `(from, topicId)`; an over-rate peer is dropped before the
553
+ * `findServing` map scan and the verify, so a peer cannot amplify junk into verify/network work.
554
+ * - **High-water** (`gate.highWater`, per `(topicId, tier)`) drops a notice whose `effectiveAt` is at or
555
+ * below the last *applied* one — a replay / out-of-order frame — before `verifyMessage`. It is advanced
556
+ * **only** on an `"applied"` outcome, so a forged frame (which never verifies) cannot poison it.
557
+ * - The receiver-side `cohortEpoch` is intentionally **not** gated on: the epoch rotates on every
558
+ * membership change, so a legitimately in-flight notice can briefly carry the prior epoch right after a
559
+ * rotation — making an epoch check a brittle, false-positive-prone filter. The rate limiter + high-water
560
+ * are the load-bearing defenses; the bounded refetch (in {@link verifyAndApplyNotice}) caps the network
561
+ * amplification on the verify itself.
562
+ *
563
+ * `from` is the dialing peer's substrate bytes ({@link peerIdToBytes}); the node handler converts the
564
+ * libp2p `PeerId` before calling. One-way contract: the caller sends no ack regardless of outcome.
565
+ */
566
+ export declare function handleInboundNotice(frame: Uint8Array, from: Uint8Array, registry: CoordRegistry, verifier: MembershipVerifier, gate: PromoteGate, now: number, maxBytes?: number): Promise<InboundNoticeResult>;
567
+ /**
568
+ * The cohort coords a notice is broadcast to over the `promote` protocol: always the cohort around
569
+ * `servedCoord` (siblings adopt the state); for a demotion, additionally the parent cohort coord (so the
570
+ * parent's `childCohortCount` bookkeeping converges). Pure — exported for testing the fan-out targets.
571
+ */
572
+ export declare function noticeBroadcastCoords(notice: PromotionNoticeV1 | DemotionNoticeV1, servedCoord: RingCoord): RingCoord[];
573
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../../src/cohort-topic/host.ts"],"names":[],"mappings":"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"}