@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
package/README.md CHANGED
@@ -93,9 +93,9 @@ graph TD
93
93
 
94
94
  %% Network communication
95
95
  B -.->|"/db-p2p/repo/1.0.0"| C
96
- E -.->|"/db-p2p/cluster/1.0.0"| G1
97
- E -.->|"/db-p2p/cluster/1.0.0"| G2
98
- E -.->|"/db-p2p/cluster/1.0.0"| G3
96
+ E -.->|"/optimystic/<network>/cluster/1.0.0"| G1
97
+ E -.->|"/optimystic/<network>/cluster/1.0.0"| G2
98
+ E -.->|"/optimystic/<network>/cluster/1.0.0"| G3
99
99
  ```
100
100
 
101
101
  ### Repo Layer: External Client Interface
@@ -203,7 +203,7 @@ Handles incoming consensus requests from coordinators:
203
203
 
204
204
  ```typescript
205
205
  class ClusterService implements Startable {
206
- // Protocol: /db-p2p/cluster/1.0.0
206
+ // Protocol: /optimystic/<network>/cluster/1.0.0 (built from protocolPrefix)
207
207
  // Handles ClusterRecord updates for consensus
208
208
  }
209
209
  ```
@@ -319,8 +319,8 @@ The package integrates deeply with libp2p for networking:
319
319
  // Node creation with integrated services
320
320
  const node = await createLibp2pNode({
321
321
  services: {
322
- repo: repoService({ protocol: '/db-p2p/repo/1.0.0' }),
323
- cluster: clusterService({ protocol: '/db-p2p/cluster/1.0.0' })
322
+ repo: repoService({ protocolPrefix: '/optimystic/<network>' }),
323
+ cluster: clusterService({ protocolPrefix: '/optimystic/<network>' })
324
324
  }
325
325
  });
326
326
 
@@ -1,5 +1,5 @@
1
1
  import type { Startable } from '@libp2p/interface';
2
- import type { IRepo, PeerId, IPeerNetwork } from '@optimystic/db-core';
2
+ import type { IRepo, PeerId, IPeerNetwork, ActionId, ActionRev, IBlock, BlockId } from '@optimystic/db-core';
3
3
  import { ProtocolClient } from '../protocol-client.js';
4
4
  export declare const buildBlockTransferProtocol: (protocolPrefix?: string) => string;
5
5
  /** Request to transfer blocks */
@@ -11,6 +11,16 @@ export interface BlockTransferRequest {
11
11
  reason: 'rebalance' | 'replication' | 'recovery';
12
12
  /** For push: base64-encoded block data per block ID */
13
13
  blockData?: Record<string, string>;
14
+ /**
15
+ * For push: the source's revision metadata per block ID. Carries the sender's
16
+ * `state.latest` so the replica's `latest` matches the source instead of being
17
+ * fabricated. Optional: an older sender omits it and the receiver falls back to a
18
+ * deterministic rev-1 replica (see {@link IBlockStorage.saveReplica}).
19
+ */
20
+ blockMeta?: Record<string, {
21
+ rev: number;
22
+ actionId: ActionId;
23
+ }>;
14
24
  }
15
25
  /** Response with block data */
16
26
  export interface BlockTransferResponse {
@@ -19,6 +29,21 @@ export interface BlockTransferResponse {
19
29
  /** Block IDs that couldn't be found/transferred */
20
30
  missing: string[];
21
31
  }
32
+ /**
33
+ * Repo capability the service needs: read access for `handlePull` plus a local
34
+ * "save replica" path for `handlePush`. The replica path must land in the node's
35
+ * *local* storage (not the cluster-coordinated repo), so it is a distinct method
36
+ * from the `IRepo` commit funnel. `StorageRepo` implements this.
37
+ */
38
+ export interface IBlockReplicaStore extends IRepo {
39
+ /**
40
+ * Persist a replica of a block received out-of-band (churn re-replication).
41
+ * Seeds metadata if absent, advances `latest` monotonically, and makes the block
42
+ * durably servable via `get`. Idempotent for a fixed `(rev, actionId)`; a no-op
43
+ * (still durable) when an equal-or-newer revision is already present.
44
+ */
45
+ saveReplicatedBlock(blockId: BlockId, block: IBlock, source?: ActionRev): Promise<void>;
46
+ }
22
47
  export interface BlockTransferServiceInit {
23
48
  protocolPrefix?: string;
24
49
  }
@@ -27,7 +52,7 @@ export interface BlockTransferServiceComponents {
27
52
  handle: (...args: any[]) => Promise<void>;
28
53
  unhandle: (...args: any[]) => Promise<void>;
29
54
  };
30
- repo: IRepo;
55
+ repo: IBlockReplicaStore;
31
56
  }
32
57
  /**
33
58
  * Libp2p service that handles incoming block transfer requests.
@@ -45,9 +70,13 @@ export declare class BlockTransferService implements Startable {
45
70
  stop(): Promise<void>;
46
71
  private handleRequest;
47
72
  private handlePull;
73
+ /**
74
+ * Persist pushed blocks into local storage so the new owner holds a durable
75
+ * replica after churn. A block is reported `accepted` only if it was both
76
+ * received (parseable) AND successfully persisted; a parse or persist failure
77
+ * surfaces it as `missing` so the sender does not falsely treat it as replicated.
78
+ */
48
79
  private handlePush;
49
- private readRequest;
50
- private sendResponse;
51
80
  }
52
81
  /** Factory for creating BlockTransferService following the libp2p service pattern. */
53
82
  export declare const blockTransferService: (init?: BlockTransferServiceInit) => (components: BlockTransferServiceComponents) => BlockTransferService;
@@ -57,9 +86,39 @@ export declare const blockTransferService: (init?: BlockTransferServiceInit) =>
57
86
  export declare class BlockTransferClient extends ProtocolClient {
58
87
  private readonly protocol;
59
88
  constructor(peerId: PeerId, peerNetwork: IPeerNetwork, protocolPrefix?: string);
60
- /** Pull blocks from the remote peer. */
61
- pullBlocks(blockIds: string[], reason?: BlockTransferRequest['reason']): Promise<BlockTransferResponse>;
62
- /** Push blocks to the remote peer. */
63
- pushBlocks(blockIds: string[], blockDataBuffers: Uint8Array[], reason?: BlockTransferRequest['reason']): Promise<BlockTransferResponse>;
89
+ /**
90
+ * Pull blocks from the remote peer.
91
+ *
92
+ * @param options Optional per-call deadlines/cancellation forwarded to the
93
+ * underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
94
+ * bounds waiting for the reply once connected; `signal` cancels the whole
95
+ * request. Omitting all of them preserves the previous uncapped behavior.
96
+ */
97
+ pullBlocks(blockIds: string[], reason?: BlockTransferRequest['reason'], options?: {
98
+ signal?: AbortSignal;
99
+ dialTimeoutMs?: number;
100
+ responseTimeoutMs?: number;
101
+ }): Promise<BlockTransferResponse>;
102
+ /**
103
+ * Push blocks to the remote peer.
104
+ *
105
+ * @param blockMeta Optional per-block source revision metadata (the sender's
106
+ * `state.latest`). When provided, the receiver replicates at the source's
107
+ * `(rev, actionId)`; when omitted, it falls back to a deterministic rev-1 replica.
108
+ * @param options Optional per-call deadlines/cancellation forwarded to the
109
+ * underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
110
+ * bounds waiting for the reply once connected (so a peer that connects but goes
111
+ * silent throws {@link ResponseTimeoutError} instead of hanging); `signal`
112
+ * cancels the whole request. Omitting all of them preserves the previous
113
+ * uncapped behavior.
114
+ */
115
+ pushBlocks(blockIds: string[], blockDataBuffers: Uint8Array[], reason?: BlockTransferRequest['reason'], blockMeta?: Record<string, {
116
+ rev: number;
117
+ actionId: ActionId;
118
+ }>, options?: {
119
+ signal?: AbortSignal;
120
+ dialTimeoutMs?: number;
121
+ responseTimeoutMs?: number;
122
+ }): Promise<BlockTransferResponse>;
64
123
  }
65
124
  //# sourceMappingURL=block-transfer-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"block-transfer-service.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAU,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKvE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AASvD,eAAO,MAAM,0BAA0B,GAAI,iBAAgB,MAAW,KAAG,MACJ,CAAC;AAEtE,iCAAiC;AACjC,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,0BAA0B;IAC1B,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;IACjD,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,+BAA+B;AAC/B,MAAM,WAAW,qBAAqB;IACrC,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,mDAAmD;IACnD,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAID,MAAM,WAAW,wBAAwB;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,8BAA8B;IAC9C,SAAS,EAAE;QAAE,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;IACtG,IAAI,EAAE,KAAK,CAAC;CACZ;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,SAAS;IACrD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8C;gBAGvE,UAAU,EAAE,8BAA8B,EAC1C,IAAI,GAAE,wBAA6B;IAO9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAOb,aAAa;YA0Bb,UAAU;YAqBV,UAAU;YA2BV,WAAW;YAmBX,YAAY;CAO1B;AAED,sFAAsF;AACtF,eAAO,MAAM,oBAAoB,GAAI,OAAM,wBAA6B,MACtE,YAAY,8BAA8B,yBAA+C,CAAC;AAI5F;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAGjC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,YAAY,EACzB,cAAc,GAAE,MAAW;IAM5B,wCAAwC;IAClC,UAAU,CACf,QAAQ,EAAE,MAAM,EAAE,EAClB,MAAM,GAAE,oBAAoB,CAAC,QAAQ,CAAe,GAClD,OAAO,CAAC,qBAAqB,CAAC;IAKjC,sCAAsC;IAChC,UAAU,CACf,QAAQ,EAAE,MAAM,EAAE,EAClB,gBAAgB,EAAE,UAAU,EAAE,EAC9B,MAAM,GAAE,oBAAoB,CAAC,QAAQ,CAAe,GAClD,OAAO,CAAC,qBAAqB,CAAC;CAQjC"}
1
+ {"version":3,"file":"block-transfer-service.d.ts","sourceRoot":"","sources":["../../../src/cluster/block-transfer-service.ts"],"names":[],"mappings":"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"}
@@ -29,7 +29,14 @@ export class BlockTransferService {
29
29
  if (this.running)
30
30
  return;
31
31
  await this.registrar.handle(this.protocol, async (data) => {
32
- await this.handleRequest(data.stream);
32
+ // libp2p invokes the stream handler with the Stream as the FIRST positional argument
33
+ // (see cluster/repo/dispute services, which all use `(stream, connection)`). The block-
34
+ // transfer handler previously read `data.stream`, which is `undefined` for the positional
35
+ // shape — so `readRequest` ran `pipe(undefined, ...)` → "Empty pipeline", the receiver
36
+ // never replied, and every push/pull dialled this service hung with no response. Unwrap
37
+ // defensively (older shape passed `{ stream }`), mirroring sync/service.ts.
38
+ const stream = data?.stream ?? data;
39
+ await this.handleRequest(stream);
33
40
  });
34
41
  this.running = true;
35
42
  log('started on %s', this.protocol);
@@ -42,31 +49,43 @@ export class BlockTransferService {
42
49
  log('stopped');
43
50
  }
44
51
  async handleRequest(stream) {
52
+ const self = this;
45
53
  try {
46
- const request = await this.readRequest(stream);
47
- log('request type=%s blocks=%d reason=%s', request.type, request.blockIds.length, request.reason);
48
- let response;
49
- if (request.type === 'pull') {
50
- response = await this.handlePull(request);
51
- }
52
- else {
53
- response = await this.handlePush(request);
54
- }
55
- await this.sendResponse(stream, response);
56
- log('response blocks=%d missing=%d', Object.keys(response.blocks).length, response.missing.length);
57
- }
58
- catch (error) {
59
- log('error: %s', error.message);
60
- try {
61
- await this.sendResponse(stream, { blocks: {}, missing: [] });
62
- }
63
- catch {
64
- // ignore send errors
54
+ // Read the request, process it, and write the response on ONE continuous duplex
55
+ // pipe (mirrors cluster/repo/dispute services). The earlier read-to-end-then-write
56
+ // design deadlocked over a real stream: the client sends one length-prefixed request
57
+ // and holds its write side open awaiting the reply, so a receiver that drained the
58
+ // source until end-of-stream blocked forever — and the reply, written only after
59
+ // teardown, hit a closed stream. Yielding the response as soon as the request is read
60
+ // keeps both sides live.
61
+ const responses = pipe(stream, (source) => lp.decode(source), async function* (source) {
62
+ for await (const msg of source) {
63
+ const request = JSON.parse(u8ToString(msg.subarray(), 'utf8'));
64
+ log('request type=%s blocks=%d reason=%s', request.type, request.blockIds.length, request.reason);
65
+ let response;
66
+ try {
67
+ response = request.type === 'pull'
68
+ ? await self.handlePull(request)
69
+ : await self.handlePush(request);
70
+ }
71
+ catch (error) {
72
+ log('error: %s', error.message);
73
+ response = { blocks: {}, missing: [] };
74
+ }
75
+ log('response blocks=%d missing=%d', Object.keys(response.blocks).length, response.missing.length);
76
+ yield u8FromString(JSON.stringify(response), 'utf8');
77
+ return; // one request → one response per stream
78
+ }
79
+ }, (source) => lp.encode(source));
80
+ for await (const chunk of responses) {
81
+ stream.send(chunk);
65
82
  }
83
+ await stream.close();
66
84
  }
67
- finally {
85
+ catch (err) {
86
+ log('error: %s', err.message);
68
87
  try {
69
- await stream.close();
88
+ stream.abort(err instanceof Error ? err : new Error(String(err)));
70
89
  }
71
90
  catch { /* ignore */ }
72
91
  }
@@ -86,52 +105,53 @@ export class BlockTransferService {
86
105
  }
87
106
  return { blocks, missing };
88
107
  }
89
- // TODO: handlePush validates incoming block data but does not persist it.
90
- // The pushed data is a serialized IBlock, not a full BlockArchive with revisions.
91
- // Persistence should be wired when RebalanceMonitor integrates with BlockStorage.saveRestored().
108
+ /**
109
+ * Persist pushed blocks into local storage so the new owner holds a durable
110
+ * replica after churn. A block is reported `accepted` only if it was both
111
+ * received (parseable) AND successfully persisted; a parse or persist failure
112
+ * surfaces it as `missing` so the sender does not falsely treat it as replicated.
113
+ */
92
114
  async handlePush(request) {
93
115
  const blocks = {};
94
116
  const missing = [];
95
117
  if (!request.blockData) {
96
118
  return { blocks: {}, missing: request.blockIds };
97
119
  }
98
- // Accept pushed blocks — for each block, validate we received parseable data
99
120
  for (const blockId of request.blockIds) {
100
121
  const data = request.blockData[blockId];
101
- if (data) {
102
- // Verify we received valid data
103
- try {
104
- JSON.parse(Buffer.from(data, 'base64').toString('utf8'));
105
- blocks[blockId] = data;
106
- }
107
- catch {
108
- missing.push(blockId);
109
- }
122
+ if (!data) {
123
+ missing.push(blockId);
124
+ continue;
110
125
  }
111
- else {
126
+ // Decode + parse the wire payload into an IBlock.
127
+ let block;
128
+ try {
129
+ block = JSON.parse(Buffer.from(data, 'base64').toString('utf8'));
130
+ }
131
+ catch {
112
132
  missing.push(blockId);
133
+ continue;
113
134
  }
114
- }
115
- return { blocks, missing };
116
- }
117
- async readRequest(stream) {
118
- const messages = [];
119
- await pipe(stream, lp.decode, async (source) => {
120
- for await (const msg of source) {
121
- messages.push(msg.subarray());
135
+ // `JSON.parse` accepts `null`/primitives as valid JSON. Persisting a falsy or
136
+ // header-less "block" would seed metadata with no materialization, making every
137
+ // later `get` throw. Reject such payloads as missing rather than poison storage.
138
+ if (block === null || typeof block !== 'object' || block.header === undefined) {
139
+ log('push:invalid block=%s (not a structurally valid block)', blockId);
140
+ missing.push(blockId);
141
+ continue;
142
+ }
143
+ // Persist locally. Only a received-AND-persisted block is reported accepted.
144
+ try {
145
+ const source = request.blockMeta?.[blockId];
146
+ await this.repo.saveReplicatedBlock(blockId, block, source);
147
+ blocks[blockId] = data;
148
+ }
149
+ catch (error) {
150
+ log('persist:fail block=%s err=%s', blockId, error.message);
151
+ missing.push(blockId);
122
152
  }
123
- });
124
- if (messages.length === 0) {
125
- throw new Error('No request received');
126
- }
127
- return JSON.parse(u8ToString(messages[0], 'utf8'));
128
- }
129
- async sendResponse(stream, response) {
130
- const bytes = u8FromString(JSON.stringify(response), 'utf8');
131
- const encoded = pipe([bytes], lp.encode);
132
- for await (const chunk of encoded) {
133
- stream.send(chunk);
134
153
  }
154
+ return { blocks, missing };
135
155
  }
136
156
  }
137
157
  /** Factory for creating BlockTransferService following the libp2p service pattern. */
@@ -146,19 +166,38 @@ export class BlockTransferClient extends ProtocolClient {
146
166
  super(peerId, peerNetwork);
147
167
  this.protocol = buildBlockTransferProtocol(protocolPrefix);
148
168
  }
149
- /** Pull blocks from the remote peer. */
150
- async pullBlocks(blockIds, reason = 'rebalance') {
169
+ /**
170
+ * Pull blocks from the remote peer.
171
+ *
172
+ * @param options Optional per-call deadlines/cancellation forwarded to the
173
+ * underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
174
+ * bounds waiting for the reply once connected; `signal` cancels the whole
175
+ * request. Omitting all of them preserves the previous uncapped behavior.
176
+ */
177
+ async pullBlocks(blockIds, reason = 'rebalance', options) {
151
178
  const request = { type: 'pull', blockIds, reason };
152
- return await this.processMessage(request, this.protocol);
179
+ return await this.processMessage(request, this.protocol, options);
153
180
  }
154
- /** Push blocks to the remote peer. */
155
- async pushBlocks(blockIds, blockDataBuffers, reason = 'rebalance') {
181
+ /**
182
+ * Push blocks to the remote peer.
183
+ *
184
+ * @param blockMeta Optional per-block source revision metadata (the sender's
185
+ * `state.latest`). When provided, the receiver replicates at the source's
186
+ * `(rev, actionId)`; when omitted, it falls back to a deterministic rev-1 replica.
187
+ * @param options Optional per-call deadlines/cancellation forwarded to the
188
+ * underlying request. `dialTimeoutMs` bounds connecting; `responseTimeoutMs`
189
+ * bounds waiting for the reply once connected (so a peer that connects but goes
190
+ * silent throws {@link ResponseTimeoutError} instead of hanging); `signal`
191
+ * cancels the whole request. Omitting all of them preserves the previous
192
+ * uncapped behavior.
193
+ */
194
+ async pushBlocks(blockIds, blockDataBuffers, reason = 'rebalance', blockMeta, options) {
156
195
  const blockData = {};
157
196
  for (let i = 0; i < blockIds.length; i++) {
158
197
  blockData[blockIds[i]] = Buffer.from(blockDataBuffers[i]).toString('base64');
159
198
  }
160
- const request = { type: 'push', blockIds, reason, blockData };
161
- return await this.processMessage(request, this.protocol);
199
+ const request = { type: 'push', blockIds, reason, blockData, ...(blockMeta ? { blockMeta } : {}) };
200
+ return await this.processMessage(request, this.protocol, options);
162
201
  }
163
202
  }
164
203
  //# sourceMappingURL=block-transfer-service.js.map
@@ -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,11 +1,28 @@
1
1
  import type { PeerId, IPeerNetwork, ICluster, ClusterRecord } from '@optimystic/db-core';
2
2
  import { ProtocolClient } from '../protocol-client.js';
3
+ import { type RpcDeadlineOptions } from '../rpc-deadline.js';
3
4
  export declare class ClusterClient extends ProtocolClient implements ICluster {
4
5
  readonly protocolPrefix?: string | undefined;
5
6
  private constructor();
6
7
  /** Create a new client instance */
7
8
  static create(peerId: PeerId, peerNetwork: IPeerNetwork, protocolPrefix?: string): ClusterClient;
8
- update(record: ClusterRecord, hop?: number): Promise<ClusterRecord>;
9
+ update(record: ClusterRecord, hop?: number, options?: RpcDeadlineOptions): Promise<ClusterRecord>;
10
+ /**
11
+ * Record a coordinator-affinity hint for the block this record's op is
12
+ * coordinated on, so a follow-up op can dial `peerId` directly.
13
+ *
14
+ * The op lives at `record.message.operations[0]` — `record.message` is a
15
+ * RepoMessage `{ operations: [...] }`, NOT a bare `{ commit }`/`{ pend }`.
16
+ * Reading `record.message.commit`/`.pend` (the old code) always saw
17
+ * `undefined`, so this hint was dead code and never recorded anything.
18
+ *
19
+ * The key is `blockIdToBytes(<the coordinated block id>)` — the sha256 digest
20
+ * findCoordinator/recordCoordinator key the cache on — NOT raw utf8 of the id
21
+ * (which would never be retrieved). Commit anchors on blockIds[0] (where
22
+ * CoordinatorRepo runs consensus + verifyResponsibility), not tailId. Pend
23
+ * anchors on a real block id (blockIdsForTransforms), not a structural
24
+ * transforms field name. ClusterClient only ever carries commit/pend.
25
+ */
9
26
  private recordCoordinatorForRecordIfSupported;
10
27
  }
11
28
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/cluster/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,qBAAa,aAAc,SAAQ,cAAe,YAAW,QAAQ;IACL,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM;IAA/F,OAAO;IAIP,mCAAmC;WACrB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,aAAa;IAIhG,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,GAAE,MAAU,GAAG,OAAO,CAAC,aAAa,CAAC;IAsC5E,OAAO,CAAC,qCAAqC;CAc9C"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/cluster/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEtF,qBAAa,aAAc,SAAQ,cAAe,YAAW,QAAQ;IACL,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM;IAA/F,OAAO;IAIP,mCAAmC;WACrB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,aAAa;IAIjG,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,GAAE,MAAU,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAyCzG;;;;;;;;;;;;;;;OAeG;YACW,qCAAqC;CAWpD"}
@@ -1,5 +1,8 @@
1
+ import { blockIdToBytes, blockIdsForTransforms } from '@optimystic/db-core';
1
2
  import { ProtocolClient } from '../protocol-client.js';
2
3
  import { peerIdFromString } from '@libp2p/peer-id';
4
+ import { isClusterErrorEnvelope, clusterErrorFromEnvelope } from './cluster-error.js';
5
+ import { withRpcDeadlineDefaults } from '../rpc-deadline.js';
3
6
  export class ClusterClient extends ProtocolClient {
4
7
  protocolPrefix;
5
8
  constructor(peerId, peerNetwork, protocolPrefix) {
@@ -10,62 +13,75 @@ export class ClusterClient extends ProtocolClient {
10
13
  static create(peerId, peerNetwork, protocolPrefix) {
11
14
  return new ClusterClient(peerId, peerNetwork, protocolPrefix);
12
15
  }
13
- async update(record, hop = 0) {
16
+ async update(record, hop = 0, options) {
14
17
  const message = {
15
18
  operation: 'update',
16
19
  record
17
20
  };
18
- const preferred = (this.protocolPrefix ?? '/db-p2p') + '/cluster/1.0.0';
19
- let response;
20
- try {
21
- response = await this.processMessage(message, preferred);
21
+ // Every node registers the cluster service under its network-prefixed
22
+ // protocol id (`/optimystic/<network>/cluster/1.0.0`); the bare
23
+ // `/db-p2p/cluster/1.0.0` is never registered, so there is no legacy
24
+ // fallback to attempt — a single dial whose error propagates directly.
25
+ const protocol = (this.protocolPrefix ?? '/db-p2p') + '/cluster/1.0.0';
26
+ // Apply the client-level dial/response deadline so a silent cluster peer
27
+ // can't hang the coordinator forever; an explicit caller override wins.
28
+ const response = await this.processMessage(message, protocol, withRpcDeadlineDefaults(options));
29
+ // A member that threw inside `update` replies with a structured error
30
+ // envelope rather than aborting the stream; rethrow the server's real
31
+ // error (preserving name/code) so the coordinator sees the true cause.
32
+ if (isClusterErrorEnvelope(response)) {
33
+ throw clusterErrorFromEnvelope(response);
22
34
  }
23
- catch (err) {
24
- if (preferred !== '/db-p2p/cluster/1.0.0') {
25
- try {
26
- response = await this.processMessage(message, '/db-p2p/cluster/1.0.0');
27
- }
28
- catch (fallbackErr) {
29
- // Throw original error - fallback protocol is likely not registered
30
- throw err;
31
- }
32
- }
33
- else {
34
- throw err;
35
- }
36
- }
37
- if (response?.redirect?.peers?.length) {
35
+ const redirectResponse = response;
36
+ if (redirectResponse?.redirect?.peers?.length) {
38
37
  if (hop >= 2) {
39
38
  throw new Error('Redirect loop detected in ClusterClient (max hops reached)');
40
39
  }
41
40
  const currentIdStr = this.peerId.toString();
42
- const next = response.redirect.peers.find((p) => p.id !== currentIdStr) ?? response.redirect.peers[0];
41
+ const next = redirectResponse.redirect.peers.find((p) => p.id !== currentIdStr) ?? redirectResponse.redirect.peers[0];
43
42
  const nextId = peerIdFromString(next.id);
44
43
  if (next.id === currentIdStr) {
45
44
  throw new Error('Redirect loop detected in ClusterClient (same peer)');
46
45
  }
47
- this.recordCoordinatorForRecordIfSupported(record, nextId);
46
+ await this.recordCoordinatorForRecordIfSupported(record, nextId);
48
47
  const nextClient = ClusterClient.create(nextId, this.peerNetwork, this.protocolPrefix);
49
- return await nextClient.update(record, hop + 1);
48
+ // Thread the caller's *original* options through the redirect hop (the
49
+ // recursive call re-applies its own defaults) so the deadline survives a redirect.
50
+ return await nextClient.update(record, hop + 1, options);
50
51
  }
51
52
  return response;
52
53
  }
53
- recordCoordinatorForRecordIfSupported(record, peerId) {
54
- const rmsg = record?.message;
55
- let tailId;
56
- if (rmsg?.commit?.tailId)
57
- tailId = rmsg.commit.tailId;
58
- else if (rmsg?.pend?.transforms) {
59
- const keys = Object.keys(rmsg.pend.transforms);
60
- if (keys.length > 0)
61
- tailId = keys[0];
62
- }
63
- if (tailId) {
64
- const kbytes = new TextEncoder().encode(tailId);
65
- const pn = this.peerNetwork;
66
- if (typeof pn?.recordCoordinator === 'function')
67
- pn.recordCoordinator(kbytes, peerId);
68
- }
54
+ /**
55
+ * Record a coordinator-affinity hint for the block this record's op is
56
+ * coordinated on, so a follow-up op can dial `peerId` directly.
57
+ *
58
+ * The op lives at `record.message.operations[0]` — `record.message` is a
59
+ * RepoMessage `{ operations: [...] }`, NOT a bare `{ commit }`/`{ pend }`.
60
+ * Reading `record.message.commit`/`.pend` (the old code) always saw
61
+ * `undefined`, so this hint was dead code and never recorded anything.
62
+ *
63
+ * The key is `blockIdToBytes(<the coordinated block id>)` — the sha256 digest
64
+ * findCoordinator/recordCoordinator key the cache on — NOT raw utf8 of the id
65
+ * (which would never be retrieved). Commit anchors on blockIds[0] (where
66
+ * CoordinatorRepo runs consensus + verifyResponsibility), not tailId. Pend
67
+ * anchors on a real block id (blockIdsForTransforms), not a structural
68
+ * transforms field name. ClusterClient only ever carries commit/pend.
69
+ */
70
+ async recordCoordinatorForRecordIfSupported(record, peerId) {
71
+ const op = record.message.operations[0];
72
+ if (!op)
73
+ return;
74
+ let id;
75
+ if ('commit' in op)
76
+ id = op.commit.blockIds[0];
77
+ else if ('pend' in op)
78
+ id = blockIdsForTransforms(op.pend.transforms)[0];
79
+ if (id == null)
80
+ return;
81
+ const kbytes = await blockIdToBytes(id);
82
+ const pn = this.peerNetwork;
83
+ if (typeof pn?.recordCoordinator === 'function')
84
+ pn.recordCoordinator(kbytes, peerId);
69
85
  }
70
86
  }
71
87
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/cluster/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/cluster/client.ts"],"names":[],"mappings":"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"}