@optimystic/db-core 0.14.1 → 0.16.3

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 (301) hide show
  1. package/dist/src/blocks/block-store.d.ts +18 -1
  2. package/dist/src/blocks/block-store.d.ts.map +1 -1
  3. package/dist/src/blocks/helpers.d.ts +2 -2
  4. package/dist/src/blocks/helpers.d.ts.map +1 -1
  5. package/dist/src/blocks/helpers.js +2 -2
  6. package/dist/src/blocks/helpers.js.map +1 -1
  7. package/dist/src/btree/btree.d.ts +27 -6
  8. package/dist/src/btree/btree.d.ts.map +1 -1
  9. package/dist/src/btree/btree.js +104 -61
  10. package/dist/src/btree/btree.js.map +1 -1
  11. package/dist/src/chain/chain.d.ts.map +1 -1
  12. package/dist/src/chain/chain.js +11 -1
  13. package/dist/src/chain/chain.js.map +1 -1
  14. package/dist/src/cluster/index.d.ts +1 -0
  15. package/dist/src/cluster/index.d.ts.map +1 -1
  16. package/dist/src/cluster/index.js +1 -0
  17. package/dist/src/cluster/index.js.map +1 -1
  18. package/dist/src/cluster/membership.d.ts +49 -0
  19. package/dist/src/cluster/membership.d.ts.map +1 -0
  20. package/dist/src/cluster/membership.js +75 -0
  21. package/dist/src/cluster/membership.js.map +1 -0
  22. package/dist/src/cluster/structs.d.ts +50 -1
  23. package/dist/src/cluster/structs.d.ts.map +1 -1
  24. package/dist/src/cluster/structs.js +9 -1
  25. package/dist/src/cluster/structs.js.map +1 -1
  26. package/dist/src/cohort-topic/addressing.d.ts +8 -2
  27. package/dist/src/cohort-topic/addressing.d.ts.map +1 -1
  28. package/dist/src/cohort-topic/addressing.js +11 -3
  29. package/dist/src/cohort-topic/addressing.js.map +1 -1
  30. package/dist/src/cohort-topic/antidos/bootstrap-evidence.d.ts +13 -7
  31. package/dist/src/cohort-topic/antidos/bootstrap-evidence.d.ts.map +1 -1
  32. package/dist/src/cohort-topic/antidos/bootstrap-evidence.js +17 -6
  33. package/dist/src/cohort-topic/antidos/bootstrap-evidence.js.map +1 -1
  34. package/dist/src/cohort-topic/antidos/replay-guard.d.ts +17 -0
  35. package/dist/src/cohort-topic/antidos/replay-guard.d.ts.map +1 -1
  36. package/dist/src/cohort-topic/antidos/replay-guard.js +33 -0
  37. package/dist/src/cohort-topic/antidos/replay-guard.js.map +1 -1
  38. package/dist/src/cohort-topic/antidos/topic-budget.d.ts +7 -0
  39. package/dist/src/cohort-topic/antidos/topic-budget.d.ts.map +1 -1
  40. package/dist/src/cohort-topic/antidos/topic-budget.js +8 -2
  41. package/dist/src/cohort-topic/antidos/topic-budget.js.map +1 -1
  42. package/dist/src/cohort-topic/coldstart.d.ts +34 -14
  43. package/dist/src/cohort-topic/coldstart.d.ts.map +1 -1
  44. package/dist/src/cohort-topic/coldstart.js +25 -11
  45. package/dist/src/cohort-topic/coldstart.js.map +1 -1
  46. package/dist/src/cohort-topic/gossip/bus.d.ts +12 -1
  47. package/dist/src/cohort-topic/gossip/bus.d.ts.map +1 -1
  48. package/dist/src/cohort-topic/gossip/bus.js +27 -1
  49. package/dist/src/cohort-topic/gossip/bus.js.map +1 -1
  50. package/dist/src/cohort-topic/gossip/view.d.ts +8 -0
  51. package/dist/src/cohort-topic/gossip/view.d.ts.map +1 -1
  52. package/dist/src/cohort-topic/gossip/view.js +17 -1
  53. package/dist/src/cohort-topic/gossip/view.js.map +1 -1
  54. package/dist/src/cohort-topic/member-engine.d.ts +10 -3
  55. package/dist/src/cohort-topic/member-engine.d.ts.map +1 -1
  56. package/dist/src/cohort-topic/member-engine.js +29 -14
  57. package/dist/src/cohort-topic/member-engine.js.map +1 -1
  58. package/dist/src/cohort-topic/membership/publisher.d.ts +14 -7
  59. package/dist/src/cohort-topic/membership/publisher.d.ts.map +1 -1
  60. package/dist/src/cohort-topic/membership/publisher.js +15 -27
  61. package/dist/src/cohort-topic/membership/publisher.js.map +1 -1
  62. package/dist/src/cohort-topic/membership/verifier.d.ts +35 -0
  63. package/dist/src/cohort-topic/membership/verifier.d.ts.map +1 -1
  64. package/dist/src/cohort-topic/membership/verifier.js +88 -3
  65. package/dist/src/cohort-topic/membership/verifier.js.map +1 -1
  66. package/dist/src/cohort-topic/promotion.d.ts +7 -0
  67. package/dist/src/cohort-topic/promotion.d.ts.map +1 -1
  68. package/dist/src/cohort-topic/promotion.js +16 -2
  69. package/dist/src/cohort-topic/promotion.js.map +1 -1
  70. package/dist/src/cohort-topic/registration/renewal.d.ts +18 -0
  71. package/dist/src/cohort-topic/registration/renewal.d.ts.map +1 -1
  72. package/dist/src/cohort-topic/registration/renewal.js +54 -0
  73. package/dist/src/cohort-topic/registration/renewal.js.map +1 -1
  74. package/dist/src/cohort-topic/registration/types.d.ts +12 -0
  75. package/dist/src/cohort-topic/registration/types.d.ts.map +1 -1
  76. package/dist/src/cohort-topic/registration/types.js +14 -0
  77. package/dist/src/cohort-topic/registration/types.js.map +1 -1
  78. package/dist/src/cohort-topic/service.d.ts +4 -3
  79. package/dist/src/cohort-topic/service.d.ts.map +1 -1
  80. package/dist/src/cohort-topic/service.js +38 -12
  81. package/dist/src/cohort-topic/service.js.map +1 -1
  82. package/dist/src/cohort-topic/sig/payloads.d.ts +23 -7
  83. package/dist/src/cohort-topic/sig/payloads.d.ts.map +1 -1
  84. package/dist/src/cohort-topic/sig/payloads.js +22 -6
  85. package/dist/src/cohort-topic/sig/payloads.js.map +1 -1
  86. package/dist/src/cohort-topic/traffic.d.ts +6 -0
  87. package/dist/src/cohort-topic/traffic.d.ts.map +1 -1
  88. package/dist/src/cohort-topic/traffic.js +16 -1
  89. package/dist/src/cohort-topic/traffic.js.map +1 -1
  90. package/dist/src/cohort-topic/walk.d.ts +22 -7
  91. package/dist/src/cohort-topic/walk.d.ts.map +1 -1
  92. package/dist/src/cohort-topic/walk.js +78 -18
  93. package/dist/src/cohort-topic/walk.js.map +1 -1
  94. package/dist/src/cohort-topic/wire/codec.d.ts +3 -1
  95. package/dist/src/cohort-topic/wire/codec.d.ts.map +1 -1
  96. package/dist/src/cohort-topic/wire/codec.js +7 -1
  97. package/dist/src/cohort-topic/wire/codec.js.map +1 -1
  98. package/dist/src/cohort-topic/wire/index.d.ts +1 -1
  99. package/dist/src/cohort-topic/wire/index.d.ts.map +1 -1
  100. package/dist/src/cohort-topic/wire/index.js +1 -1
  101. package/dist/src/cohort-topic/wire/index.js.map +1 -1
  102. package/dist/src/cohort-topic/wire/payloads.d.ts +5 -4
  103. package/dist/src/cohort-topic/wire/payloads.d.ts.map +1 -1
  104. package/dist/src/cohort-topic/wire/payloads.js +14 -5
  105. package/dist/src/cohort-topic/wire/payloads.js.map +1 -1
  106. package/dist/src/cohort-topic/wire/primitives.d.ts +65 -0
  107. package/dist/src/cohort-topic/wire/primitives.d.ts.map +1 -0
  108. package/dist/src/cohort-topic/wire/primitives.js +173 -0
  109. package/dist/src/cohort-topic/wire/primitives.js.map +1 -0
  110. package/dist/src/cohort-topic/wire/types.d.ts +132 -5
  111. package/dist/src/cohort-topic/wire/types.d.ts.map +1 -1
  112. package/dist/src/cohort-topic/wire/validate.d.ts +15 -5
  113. package/dist/src/cohort-topic/wire/validate.d.ts.map +1 -1
  114. package/dist/src/cohort-topic/wire/validate.js +146 -123
  115. package/dist/src/cohort-topic/wire/validate.js.map +1 -1
  116. package/dist/src/collection/collection.d.ts +23 -12
  117. package/dist/src/collection/collection.d.ts.map +1 -1
  118. package/dist/src/collection/collection.js +111 -35
  119. package/dist/src/collection/collection.js.map +1 -1
  120. package/dist/src/collection/struct.d.ts +37 -2
  121. package/dist/src/collection/struct.d.ts.map +1 -1
  122. package/dist/src/collection/struct.js +16 -1
  123. package/dist/src/collection/struct.js.map +1 -1
  124. package/dist/src/collections/tree/tree.d.ts +18 -1
  125. package/dist/src/collections/tree/tree.d.ts.map +1 -1
  126. package/dist/src/collections/tree/tree.js +36 -6
  127. package/dist/src/collections/tree/tree.js.map +1 -1
  128. package/dist/src/index.d.ts +1 -0
  129. package/dist/src/index.d.ts.map +1 -1
  130. package/dist/src/index.js +1 -0
  131. package/dist/src/index.js.map +1 -1
  132. package/dist/src/log/log.d.ts +26 -3
  133. package/dist/src/log/log.d.ts.map +1 -1
  134. package/dist/src/log/log.js +34 -7
  135. package/dist/src/log/log.js.map +1 -1
  136. package/dist/src/log/struct.d.ts +5 -4
  137. package/dist/src/log/struct.d.ts.map +1 -1
  138. package/dist/src/log/struct.js.map +1 -1
  139. package/dist/src/matchmaking/wire.d.ts +2 -1
  140. package/dist/src/matchmaking/wire.d.ts.map +1 -1
  141. package/dist/src/matchmaking/wire.js +13 -92
  142. package/dist/src/matchmaking/wire.js.map +1 -1
  143. package/dist/src/network/i-key-network.d.ts +9 -0
  144. package/dist/src/network/i-key-network.d.ts.map +1 -1
  145. package/dist/src/network/i-repo.d.ts +8 -0
  146. package/dist/src/network/i-repo.d.ts.map +1 -1
  147. package/dist/src/network/struct.d.ts +10 -0
  148. package/dist/src/network/struct.d.ts.map +1 -1
  149. package/dist/src/reactivity/push-state.d.ts.map +1 -1
  150. package/dist/src/reactivity/push-state.js +4 -33
  151. package/dist/src/reactivity/push-state.js.map +1 -1
  152. package/dist/src/reactivity/wire-validate.d.ts +7 -22
  153. package/dist/src/reactivity/wire-validate.d.ts.map +1 -1
  154. package/dist/src/reactivity/wire-validate.js +7 -73
  155. package/dist/src/reactivity/wire-validate.js.map +1 -1
  156. package/dist/src/reactivity/wire.js +3 -3
  157. package/dist/src/reactivity/wire.js.map +1 -1
  158. package/dist/src/testing/async-wait.d.ts +23 -0
  159. package/dist/src/testing/async-wait.d.ts.map +1 -0
  160. package/dist/src/testing/async-wait.js +42 -0
  161. package/dist/src/testing/async-wait.js.map +1 -0
  162. package/dist/src/testing/index.d.ts +3 -0
  163. package/dist/src/testing/index.d.ts.map +1 -0
  164. package/dist/src/testing/index.js +3 -0
  165. package/dist/src/testing/index.js.map +1 -0
  166. package/dist/src/testing/test-transactor.d.ts +44 -0
  167. package/dist/src/testing/test-transactor.d.ts.map +1 -0
  168. package/dist/src/testing/test-transactor.js +423 -0
  169. package/dist/src/testing/test-transactor.js.map +1 -0
  170. package/dist/src/transaction/actions-engine.d.ts +6 -3
  171. package/dist/src/transaction/actions-engine.d.ts.map +1 -1
  172. package/dist/src/transaction/actions-engine.js +8 -7
  173. package/dist/src/transaction/actions-engine.js.map +1 -1
  174. package/dist/src/transaction/coordinator.d.ts +43 -22
  175. package/dist/src/transaction/coordinator.d.ts.map +1 -1
  176. package/dist/src/transaction/coordinator.js +443 -178
  177. package/dist/src/transaction/coordinator.js.map +1 -1
  178. package/dist/src/transaction/errors.d.ts +82 -0
  179. package/dist/src/transaction/errors.d.ts.map +1 -0
  180. package/dist/src/transaction/errors.js +93 -0
  181. package/dist/src/transaction/errors.js.map +1 -0
  182. package/dist/src/transaction/index.d.ts +6 -3
  183. package/dist/src/transaction/index.d.ts.map +1 -1
  184. package/dist/src/transaction/index.js +4 -2
  185. package/dist/src/transaction/index.js.map +1 -1
  186. package/dist/src/transaction/operations-hash.d.ts +119 -0
  187. package/dist/src/transaction/operations-hash.d.ts.map +1 -0
  188. package/dist/src/transaction/operations-hash.js +180 -0
  189. package/dist/src/transaction/operations-hash.js.map +1 -0
  190. package/dist/src/transaction/read-dependency-collector.d.ts +43 -0
  191. package/dist/src/transaction/read-dependency-collector.d.ts.map +1 -0
  192. package/dist/src/transaction/read-dependency-collector.js +69 -0
  193. package/dist/src/transaction/read-dependency-collector.js.map +1 -0
  194. package/dist/src/transaction/session.d.ts +12 -3
  195. package/dist/src/transaction/session.d.ts.map +1 -1
  196. package/dist/src/transaction/session.js +35 -9
  197. package/dist/src/transaction/session.js.map +1 -1
  198. package/dist/src/transaction/transaction.d.ts +162 -1
  199. package/dist/src/transaction/transaction.d.ts.map +1 -1
  200. package/dist/src/transaction/transaction.js +85 -3
  201. package/dist/src/transaction/transaction.js.map +1 -1
  202. package/dist/src/transaction/validator.d.ts +3 -11
  203. package/dist/src/transaction/validator.d.ts.map +1 -1
  204. package/dist/src/transaction/validator.js +69 -28
  205. package/dist/src/transaction/validator.js.map +1 -1
  206. package/dist/src/transactor/network-transactor.d.ts +35 -0
  207. package/dist/src/transactor/network-transactor.d.ts.map +1 -1
  208. package/dist/src/transactor/network-transactor.js +146 -40
  209. package/dist/src/transactor/network-transactor.js.map +1 -1
  210. package/dist/src/transactor/transactor-source.d.ts +19 -5
  211. package/dist/src/transactor/transactor-source.d.ts.map +1 -1
  212. package/dist/src/transactor/transactor-source.js +43 -11
  213. package/dist/src/transactor/transactor-source.js.map +1 -1
  214. package/dist/src/transform/atomic-proxy.d.ts +35 -5
  215. package/dist/src/transform/atomic-proxy.d.ts.map +1 -1
  216. package/dist/src/transform/atomic-proxy.js +39 -7
  217. package/dist/src/transform/atomic-proxy.js.map +1 -1
  218. package/dist/src/transform/cache-source.d.ts +36 -5
  219. package/dist/src/transform/cache-source.d.ts.map +1 -1
  220. package/dist/src/transform/cache-source.js +84 -8
  221. package/dist/src/transform/cache-source.js.map +1 -1
  222. package/dist/src/transform/helpers.d.ts.map +1 -1
  223. package/dist/src/transform/helpers.js +8 -2
  224. package/dist/src/transform/helpers.js.map +1 -1
  225. package/dist/src/transform/tracker.d.ts +17 -2
  226. package/dist/src/transform/tracker.d.ts.map +1 -1
  227. package/dist/src/transform/tracker.js +66 -11
  228. package/dist/src/transform/tracker.js.map +1 -1
  229. package/dist/src/utility/backoff.d.ts +48 -0
  230. package/dist/src/utility/backoff.d.ts.map +1 -0
  231. package/dist/src/utility/backoff.js +60 -0
  232. package/dist/src/utility/backoff.js.map +1 -0
  233. package/dist/src/utility/pending.d.ts +1 -0
  234. package/dist/src/utility/pending.d.ts.map +1 -1
  235. package/dist/src/utility/pending.js +3 -1
  236. package/dist/src/utility/pending.js.map +1 -1
  237. package/package.json +4 -4
  238. package/src/blocks/block-store.ts +19 -1
  239. package/src/blocks/helpers.ts +3 -3
  240. package/src/btree/btree.ts +108 -63
  241. package/src/chain/chain.ts +11 -1
  242. package/src/cluster/index.ts +1 -0
  243. package/src/cluster/membership.ts +85 -0
  244. package/src/cluster/structs.ts +51 -1
  245. package/src/cohort-topic/addressing.ts +12 -4
  246. package/src/cohort-topic/antidos/bootstrap-evidence.ts +21 -9
  247. package/src/cohort-topic/antidos/replay-guard.ts +37 -0
  248. package/src/cohort-topic/antidos/topic-budget.ts +17 -2
  249. package/src/cohort-topic/coldstart.ts +48 -15
  250. package/src/cohort-topic/gossip/bus.ts +39 -2
  251. package/src/cohort-topic/gossip/view.ts +26 -1
  252. package/src/cohort-topic/member-engine.ts +36 -15
  253. package/src/cohort-topic/membership/publisher.ts +25 -33
  254. package/src/cohort-topic/membership/verifier.ts +119 -3
  255. package/src/cohort-topic/promotion.ts +23 -2
  256. package/src/cohort-topic/registration/renewal.ts +73 -1
  257. package/src/cohort-topic/registration/types.ts +15 -0
  258. package/src/cohort-topic/service.ts +41 -15
  259. package/src/cohort-topic/sig/payloads.ts +29 -9
  260. package/src/cohort-topic/traffic.ts +23 -1
  261. package/src/cohort-topic/walk.ts +95 -24
  262. package/src/cohort-topic/wire/codec.ts +12 -0
  263. package/src/cohort-topic/wire/index.ts +2 -0
  264. package/src/cohort-topic/wire/payloads.ts +14 -5
  265. package/src/cohort-topic/wire/primitives.ts +188 -0
  266. package/src/cohort-topic/wire/types.ts +136 -4
  267. package/src/cohort-topic/wire/validate.ts +168 -134
  268. package/src/collection/collection.ts +123 -40
  269. package/src/collection/struct.ts +44 -2
  270. package/src/collections/tree/tree.ts +42 -5
  271. package/src/index.ts +1 -0
  272. package/src/log/log.ts +37 -9
  273. package/src/log/struct.ts +5 -4
  274. package/src/matchmaking/wire.ts +25 -102
  275. package/src/network/i-key-network.ts +10 -0
  276. package/src/network/i-repo.ts +8 -0
  277. package/src/network/struct.ts +10 -0
  278. package/src/reactivity/push-state.ts +4 -37
  279. package/src/reactivity/wire-validate.ts +7 -81
  280. package/src/reactivity/wire.ts +3 -3
  281. package/src/testing/async-wait.ts +65 -0
  282. package/src/testing/index.ts +2 -0
  283. package/src/testing/test-transactor.ts +468 -0
  284. package/src/transaction/actions-engine.ts +8 -6
  285. package/src/transaction/coordinator.ts +498 -229
  286. package/src/transaction/errors.ts +91 -0
  287. package/src/transaction/index.ts +23 -3
  288. package/src/transaction/operations-hash.ts +196 -0
  289. package/src/transaction/read-dependency-collector.ts +78 -0
  290. package/src/transaction/session.ts +37 -9
  291. package/src/transaction/transaction.ts +211 -4
  292. package/src/transaction/validator.ts +73 -48
  293. package/src/transactor/network-transactor.ts +164 -49
  294. package/src/transactor/transactor-source.ts +47 -12
  295. package/src/transform/atomic-proxy.ts +92 -49
  296. package/src/transform/cache-source.ts +87 -9
  297. package/src/transform/helpers.ts +8 -2
  298. package/src/transform/tracker.ts +69 -11
  299. package/src/utility/backoff.ts +95 -0
  300. package/src/utility/pending.ts +3 -1
  301. package/src/transaction/context.ts +0 -103
@@ -17,6 +17,16 @@ export type TransactionStamp = {
17
17
  engineId: string;
18
18
  /** Absolute ms epoch after which transaction is invalid */
19
19
  expiration: number;
20
+ /**
21
+ * Random per-transaction nonce, folded into {@link TransactionStamp.id}.
22
+ *
23
+ * Anti-replay for read-free transactions: a transaction with no reads has nothing
24
+ * binding it to a point in history beyond {@link expiration}, so without this a
25
+ * captured signed read-free transaction could be re-submitted within the TTL window.
26
+ * The nonce makes two otherwise-identical transactions from the same peer at the
27
+ * same millisecond produce different ids (hence different signed bytes).
28
+ */
29
+ nonce: string;
20
30
  /** Hash of the stamp fields (computed) - stable identifier throughout transaction */
21
31
  id: string;
22
32
  };
@@ -41,6 +51,42 @@ export type Transaction = {
41
51
  * Final transaction identity, used in logs
42
52
  */
43
53
  id: string;
54
+ /**
55
+ * Optional client signature (base64url) over {@link clientSignaturePayload}
56
+ * `(stamp.id, statements, reads)`, produced at commit by an injected
57
+ * {@link TransactionSigner}.
58
+ *
59
+ * A node that wires a {@link ClientSignatureVerifier} into its
60
+ * {@link TransactionValidator} verifies this at pend; where no verifier is wired,
61
+ * unsigned transactions are still accepted (migration / single-node-dev posture).
62
+ * Plain field on the transaction, so it rides along through serialization/persistence
63
+ * for later recovery-time re-verification.
64
+ *
65
+ * NOTE: preservation is verified only through JSON round-trip and an in-memory session commit —
66
+ * NOT yet through the db-p2p cluster-repo on-disk transaction-log serialization. No recovery
67
+ * reader exists today; when one lands, confirm this field survives that path so `verifyPeerSig`
68
+ * can re-run at recovery time.
69
+ */
70
+ signature?: string;
71
+ /**
72
+ * Aged, advisory retry priority (default 0 when absent). Rises by one per failed retry
73
+ * attempt (attempt-count-derived — deterministic, no wall clock, clock-skew-free) and is
74
+ * capped at {@link MaxPriority}. A cluster member uses it ONLY as the first tiebreak in a
75
+ * concurrent race between two simultaneously-pending conflicting transactions
76
+ * (`resolveRace`), so a transaction that keeps losing races eventually out-ranks fresh
77
+ * (priority-0) rivals instead of losing at random forever.
78
+ *
79
+ * FAIRNESS-ONLY — MUST NOT influence validity, the operations hash, stale-read checks, the
80
+ * transaction id, or the client signature. It is deliberately excluded from
81
+ * {@link createTransactionId} and {@link clientSignaturePayload} so two attempts of the same
82
+ * logical transaction (differing only in priority) keep the same id and signature; folding it
83
+ * into either would churn identity/anti-replay on every retry. It rides inside the signed
84
+ * cluster `message` (via the pend operation), so it is integrity-protected in transit — a
85
+ * relaying peer cannot strip or inflate it without invalidating the message hash — but the
86
+ * originating coordinator can still self-assert it (a fairness concern, not a safety one; see
87
+ * `docs/correctness.md` Theorem 9).
88
+ */
89
+ priority?: number;
44
90
  };
45
91
  /**
46
92
  * Read dependency for optimistic concurrency control.
@@ -58,8 +104,34 @@ export type ReadDependency = {
58
104
  export type TransactionRef = string;
59
105
  /** Default transaction time-to-live in milliseconds (30 seconds). */
60
106
  export declare const DEFAULT_TRANSACTION_TTL_MS = 30000;
107
+ /**
108
+ * Upper bound on a transaction's aged {@link Transaction.priority}. Capping is essential: it
109
+ * bounds the fairness effect (an aged transaction cannot accrue unlimited advantage) and bounds
110
+ * the throughput cost (it can impose at most `MaxPriority` extra race-losses on rivals before it
111
+ * commits). Two transactions capped out at `MaxPriority` fall back to the existing promise-count /
112
+ * message-hash tiebreak, so behavior degrades gracefully to the pre-priority status quo.
113
+ */
114
+ export declare const MaxPriority = 8;
115
+ /**
116
+ * Clamp an attempt-derived priority into `[0, MaxPriority]`. Total: any non-finite / negative
117
+ * input collapses to 0, anything above the cap to {@link MaxPriority}, and the result is floored
118
+ * to an integer. Used both where priority is *set* (the retry loops) and where it is *read* (a
119
+ * cluster member's `resolveRace`), so a Byzantine coordinator self-asserting an out-of-range value
120
+ * cannot exceed the cap.
121
+ */
122
+ export declare function clampPriority(priority: number | undefined): number;
61
123
  /** Check whether a transaction stamp has expired. */
62
124
  export declare function isTransactionExpired(stamp: TransactionStamp): boolean;
125
+ /** The stamp fields that feed the id hash (everything except the id itself). */
126
+ export type StampFields = Omit<TransactionStamp, 'id'>;
127
+ /**
128
+ * Compute the canonical stamp id from its fields. MUST match the historical field order
129
+ * (peerId, timestamp, schemaHash, engineId, expiration, nonce) — changing it churns every
130
+ * existing stamp id and client signature. Both {@link createTransactionStamp} and the
131
+ * validator's integrity check derive the id through this one function, so a validating node
132
+ * can re-derive the id and reject a stamp whose fields were tampered while id stayed fixed.
133
+ */
134
+ export declare function computeStampId(fields: StampFields): Promise<string>;
63
135
  /**
64
136
  * Create a transaction stamp with computed id.
65
137
  * The id is a hash of the stamp fields (including expiration).
@@ -68,8 +140,51 @@ export declare function createTransactionStamp(peerId: string, timestamp: number
68
140
  /**
69
141
  * Create a transaction id from stamp id, statements, and reads.
70
142
  * This is the final transaction identity used in logs.
143
+ *
144
+ * NOTE: reads are serialized in their given order here (non-canonical). This differs
145
+ * from {@link clientSignaturePayload}, which canonicalises reads before hashing. That is
146
+ * intentional for this ticket — the signature payload is self-contained — but the
147
+ * non-canonical ordering here is a separate hygiene concern (see
148
+ * design-consensus-hygiene-notes), NOT fixed here to avoid changing existing tx ids.
149
+ *
150
+ * NOTE: {@link Transaction.priority} is deliberately absent from this preimage — the id is a pure
151
+ * function of `(stampId, statements, reads)`, so two retry attempts that differ only in aged
152
+ * priority produce the SAME id. Do not add priority here.
71
153
  */
72
154
  export declare function createTransactionId(stampId: string, statements: string[], reads: ReadDependency[]): Promise<string>;
155
+ /**
156
+ * Version prefix for the client-signature payload, so the signed form can evolve
157
+ * without ambiguity. Distinct from (but consistent in spirit with) the operations-hash
158
+ * canonical form — this covers transaction INPUTS, not operations.
159
+ */
160
+ export declare const CLIENT_SIG_VERSION = "txsig:v1";
161
+ /**
162
+ * Canonical bytes a client signs and a node verifies. Deterministic: reads are sorted
163
+ * (blockId, then revision); statements keep their sequential order.
164
+ *
165
+ * Binds three things at once: the CLIENT IDENTITY (via `stampId`, which hashes peerId +
166
+ * nonce), the EXACT statements, and the OCC read set (blockId + revision — "tail
167
+ * binding" for anti-replay). Both signer and verifier derive the bytes from
168
+ * `transaction.stamp.id` + `transaction.statements` + `transaction.reads` through this
169
+ * one function, so they reproduce identical bytes regardless of read ordering.
170
+ *
171
+ * NOTE: {@link Transaction.priority} is deliberately absent from the signed bytes — a retry that
172
+ * only bumps priority keeps the same signature, so anti-replay / OCC binding never churns. Do not
173
+ * add priority here.
174
+ */
175
+ export declare function clientSignaturePayload(stampId: string, statements: readonly string[], reads: readonly ReadDependency[]): Uint8Array;
176
+ /**
177
+ * Signs the canonical client-signature payload, returning base64url. Async to allow
178
+ * libp2p `PrivateKey.sign`; tests pass a synchronous fake.
179
+ */
180
+ export type TransactionSigner = (payload: Uint8Array) => Promise<string> | string;
181
+ /**
182
+ * Returns true iff `signature` (base64url) is a valid client signature over `payload`
183
+ * for signer identity `peerId`. Total: returns false, never throws, on any malformed
184
+ * input. The p2p wiring backs this with verifyPeerSig + peerIdBindsPublicKey; tests
185
+ * pass a fake.
186
+ */
187
+ export type ClientSignatureVerifier = (peerId: string, payload: Uint8Array, signature: string) => boolean;
73
188
  /**
74
189
  * Transaction engine interface.
75
190
  * Pluggable engines implement this to process transaction statements.
@@ -78,8 +193,40 @@ export declare function createTransactionId(stampId: string, statements: string[
78
193
  * 1. Parsing the engine-specific statements
79
194
  * 2. Executing/re-executing to produce actions
80
195
  * 3. Returning the resulting actions per collection
196
+ *
197
+ * CONTRACT — an engine must never cause the same action to be applied twice. The
198
+ * caller (a {@link TransactionSession} on the no-pre-supplied-actions branch, or a
199
+ * {@link TransactionCoordinator} in `execute()`) applies whatever non-empty
200
+ * `CollectionActions[]` this method RETURNS. Therefore `execute()` must satisfy
201
+ * exactly ONE of:
202
+ *
203
+ * (a) PURE TRANSLATOR (preferred; how {@link ActionsEngine} works) — parse the
204
+ * statements, RETURN the actions, and do NOT apply them / do NOT call
205
+ * `coordinator.applyActions` / do NOT mutate any collection state. The caller
206
+ * applies them exactly once.
207
+ *
208
+ * (b) SIDE-EFFECT APPLY — apply the actions itself while translating (e.g. the
209
+ * Quereus vtab path stages rows into the coordinator during `db.exec`) and then
210
+ * RETURN an EMPTY actions array, so the caller re-applies nothing.
211
+ *
212
+ * An engine that BOTH applies as a side effect AND returns those same actions
213
+ * double-applies (the caller re-applies the returned actions). Additionally, a
214
+ * side-effecting engine used for validation must apply only to the validator's
215
+ * ISOLATED coordinator — applying to the main coordinator leaks into the validating
216
+ * node's live state.
81
217
  */
82
218
  export interface ITransactionEngine {
219
+ /**
220
+ * Stable identifier for this engine.
221
+ *
222
+ * This is the value stamped into {@link TransactionStamp.engineId} when a
223
+ * {@link TransactionSession} builds a transaction, and the key a
224
+ * {@link TransactionValidator} resolves the engine by. It MUST match the key the
225
+ * engine is registered under in the validator's `engines` map — otherwise a
226
+ * validating node rejects the transaction as `Unknown engine: <id>` before it
227
+ * ever re-executes.
228
+ */
229
+ readonly id: string;
83
230
  /**
84
231
  * Process a transaction statements to produce actions.
85
232
  *
@@ -104,6 +251,16 @@ export type ExecutionResult = {
104
251
  results?: Map<CollectionId, any[]>;
105
252
  /** Error message if execution failed */
106
253
  error?: string;
254
+ /**
255
+ * On a PARTIAL multi-collection commit failure, the collections that DID durably
256
+ * commit through consensus before the failure (and thus CANNOT be rolled back —
257
+ * reconciliation is required). Absent/empty means nothing durably committed, so
258
+ * the caller may treat the failure as a clean abort. See
259
+ * {@link CoordinatorPartialCommitError} for the session-mode (commit) analog.
260
+ */
261
+ committedCollections?: CollectionId[];
262
+ /** On a partial multi-collection commit failure, the collections that failed to commit. */
263
+ failedCollections?: CollectionId[];
107
264
  };
108
265
  /**
109
266
  * Actions for a specific collection resulting from transaction execution.
@@ -148,7 +305,11 @@ export interface ITransactionValidator {
148
305
  /**
149
306
  * Validate a transaction by re-executing and comparing operations hash.
150
307
  *
151
- * Validation steps:
308
+ * Validation steps (see TransactionValidator.validate for the authoritative order):
309
+ * 0.0. Verify stamp.id is the true hash of the stamp fields (integrity — runs first,
310
+ * since every later step trusts a stamp field)
311
+ * 0. Verify the stamp has not expired
312
+ * 0.5. Verify the client signature (only if a signature verifier is wired)
152
313
  * 1. Verify stamp.engineId matches a known engine
153
314
  * 2. Verify stamp.schemaHash matches local schema
154
315
  * 3. Verify read dependencies (no stale reads)
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../src/transaction/transaction.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../src/transaction/transaction.ts"],"names":[],"mappings":"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"}
@@ -1,28 +1,110 @@
1
+ import { randomBytes } from "@noble/hashes/utils.js";
2
+ import { toString as uint8ArrayToString } from "uint8arrays/to-string";
1
3
  import { hashString } from "../utility/hash-string.js";
2
4
  /** Default transaction time-to-live in milliseconds (30 seconds). */
3
5
  export const DEFAULT_TRANSACTION_TTL_MS = 30_000;
6
+ /**
7
+ * Upper bound on a transaction's aged {@link Transaction.priority}. Capping is essential: it
8
+ * bounds the fairness effect (an aged transaction cannot accrue unlimited advantage) and bounds
9
+ * the throughput cost (it can impose at most `MaxPriority` extra race-losses on rivals before it
10
+ * commits). Two transactions capped out at `MaxPriority` fall back to the existing promise-count /
11
+ * message-hash tiebreak, so behavior degrades gracefully to the pre-priority status quo.
12
+ */
13
+ export const MaxPriority = 8;
14
+ /**
15
+ * Clamp an attempt-derived priority into `[0, MaxPriority]`. Total: any non-finite / negative
16
+ * input collapses to 0, anything above the cap to {@link MaxPriority}, and the result is floored
17
+ * to an integer. Used both where priority is *set* (the retry loops) and where it is *read* (a
18
+ * cluster member's `resolveRace`), so a Byzantine coordinator self-asserting an out-of-range value
19
+ * cannot exceed the cap.
20
+ */
21
+ export function clampPriority(priority) {
22
+ if (typeof priority !== 'number' || Number.isNaN(priority) || priority <= 0) {
23
+ return 0;
24
+ }
25
+ // A positive out-of-range value (including +Infinity, or a Byzantine self-asserted number) clamps
26
+ // DOWN to the cap; anything strictly inside the range is floored to an integer.
27
+ if (priority >= MaxPriority) {
28
+ return MaxPriority;
29
+ }
30
+ return Math.floor(priority);
31
+ }
4
32
  /** Check whether a transaction stamp has expired. */
5
33
  export function isTransactionExpired(stamp) {
6
34
  return Date.now() > stamp.expiration;
7
35
  }
36
+ /**
37
+ * Compute the canonical stamp id from its fields. MUST match the historical field order
38
+ * (peerId, timestamp, schemaHash, engineId, expiration, nonce) — changing it churns every
39
+ * existing stamp id and client signature. Both {@link createTransactionStamp} and the
40
+ * validator's integrity check derive the id through this one function, so a validating node
41
+ * can re-derive the id and reject a stamp whose fields were tampered while id stayed fixed.
42
+ */
43
+ export async function computeStampId(fields) {
44
+ // Destructure and rebuild in fixed order rather than passing `fields` straight to
45
+ // JSON.stringify — this ignores any stray `id` (or extra) property a caller slipped in,
46
+ // so the serialized bytes depend on exactly the six fields and nothing else.
47
+ const { peerId, timestamp, schemaHash, engineId, expiration, nonce } = fields;
48
+ const stampData = JSON.stringify({ peerId, timestamp, schemaHash, engineId, expiration, nonce });
49
+ return `stamp:${await hashString(stampData)}`;
50
+ }
8
51
  /**
9
52
  * Create a transaction stamp with computed id.
10
53
  * The id is a hash of the stamp fields (including expiration).
11
54
  */
12
55
  export async function createTransactionStamp(peerId, timestamp, schemaHash, engineId, ttlMs = DEFAULT_TRANSACTION_TTL_MS) {
13
56
  const expiration = timestamp + ttlMs;
14
- const stampData = JSON.stringify({ peerId, timestamp, schemaHash, engineId, expiration });
15
- const id = `stamp:${await hashString(stampData)}`;
16
- return { peerId, timestamp, schemaHash, engineId, expiration, id };
57
+ // Cross-platform CSPRNG (Node + browser) via @noble/hashes matches the rest of
58
+ // db-core (see collection.ts, transactor-source.ts). The nonce is folded into the
59
+ // id hash so two otherwise-identical stamps diverge.
60
+ const nonce = uint8ArrayToString(randomBytes(16), 'base64url');
61
+ const id = await computeStampId({ peerId, timestamp, schemaHash, engineId, expiration, nonce });
62
+ return { peerId, timestamp, schemaHash, engineId, expiration, nonce, id };
17
63
  }
18
64
  /**
19
65
  * Create a transaction id from stamp id, statements, and reads.
20
66
  * This is the final transaction identity used in logs.
67
+ *
68
+ * NOTE: reads are serialized in their given order here (non-canonical). This differs
69
+ * from {@link clientSignaturePayload}, which canonicalises reads before hashing. That is
70
+ * intentional for this ticket — the signature payload is self-contained — but the
71
+ * non-canonical ordering here is a separate hygiene concern (see
72
+ * design-consensus-hygiene-notes), NOT fixed here to avoid changing existing tx ids.
73
+ *
74
+ * NOTE: {@link Transaction.priority} is deliberately absent from this preimage — the id is a pure
75
+ * function of `(stampId, statements, reads)`, so two retry attempts that differ only in aged
76
+ * priority produce the SAME id. Do not add priority here.
21
77
  */
22
78
  export async function createTransactionId(stampId, statements, reads) {
23
79
  const txData = JSON.stringify({ stampId, statements, reads });
24
80
  return `tx:${await hashString(txData)}`;
25
81
  }
82
+ /**
83
+ * Version prefix for the client-signature payload, so the signed form can evolve
84
+ * without ambiguity. Distinct from (but consistent in spirit with) the operations-hash
85
+ * canonical form — this covers transaction INPUTS, not operations.
86
+ */
87
+ export const CLIENT_SIG_VERSION = 'txsig:v1';
88
+ /**
89
+ * Canonical bytes a client signs and a node verifies. Deterministic: reads are sorted
90
+ * (blockId, then revision); statements keep their sequential order.
91
+ *
92
+ * Binds three things at once: the CLIENT IDENTITY (via `stampId`, which hashes peerId +
93
+ * nonce), the EXACT statements, and the OCC read set (blockId + revision — "tail
94
+ * binding" for anti-replay). Both signer and verifier derive the bytes from
95
+ * `transaction.stamp.id` + `transaction.statements` + `transaction.reads` through this
96
+ * one function, so they reproduce identical bytes regardless of read ordering.
97
+ *
98
+ * NOTE: {@link Transaction.priority} is deliberately absent from the signed bytes — a retry that
99
+ * only bumps priority keeps the same signature, so anti-replay / OCC binding never churns. Do not
100
+ * add priority here.
101
+ */
102
+ export function clientSignaturePayload(stampId, statements, reads) {
103
+ const canonicalReads = [...reads].sort((a, b) => a.blockId < b.blockId ? -1 : a.blockId > b.blockId ? 1
104
+ : a.revision - b.revision);
105
+ const body = JSON.stringify({ stampId, statements, reads: canonicalReads });
106
+ return new TextEncoder().encode(`${CLIENT_SIG_VERSION}:${body}`);
107
+ }
26
108
  /**
27
109
  * Helper to create an actions-based transaction statements array.
28
110
  * Each CollectionActions becomes a separate JSON-encoded statement.
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../src/transaction/transaction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAsEvD,qEAAqE;AACrE,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAEjD,qDAAqD;AACrD,MAAM,UAAU,oBAAoB,CAAC,KAAuB;IAC3D,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC3C,MAAc,EACd,SAAiB,EACjB,UAAkB,EAClB,QAAgB,EAChB,QAAgB,0BAA0B;IAE1C,MAAM,UAAU,GAAG,SAAS,GAAG,KAAK,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;IAC1F,MAAM,EAAE,GAAG,SAAS,MAAM,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;IAClD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACxC,OAAe,EACf,UAAoB,EACpB,KAAuB;IAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,OAAO,MAAM,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;AACzC,CAAC;AAmDD;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAgC;IACvE,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../src/transaction/transaction.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type { BlockId, CollectionId, Transforms } from '../index.js';
2
- import type { Transaction, ITransactionEngine, ITransactionValidator, ValidationResult, CollectionActions } from './transaction.js';
2
+ import type { Transaction, ITransactionEngine, ITransactionValidator, ValidationResult, CollectionActions, ClientSignatureVerifier } from './transaction.js';
3
3
  import type { BlockActionState } from '../network/struct.js';
4
4
  /**
5
5
  * Engine registration for validation.
@@ -37,17 +37,9 @@ export declare class TransactionValidator implements ITransactionValidator {
37
37
  private readonly engines;
38
38
  private readonly createValidationCoordinator;
39
39
  private readonly blockStateProvider?;
40
- constructor(engines: Map<string, EngineRegistration>, createValidationCoordinator: ValidationCoordinatorFactory, blockStateProvider?: BlockStateProvider | undefined);
40
+ private readonly verifyClientSignature?;
41
+ constructor(engines: Map<string, EngineRegistration>, createValidationCoordinator: ValidationCoordinatorFactory, blockStateProvider?: BlockStateProvider | undefined, verifyClientSignature?: ClientSignatureVerifier | undefined);
41
42
  validate(transaction: Transaction, operationsHash: string): Promise<ValidationResult>;
42
43
  getSchemaHash(engineId: string): Promise<string | undefined>;
43
- /**
44
- * Collect all operations from transforms.
45
- */
46
- private collectOperations;
47
- /**
48
- * Compute hash of all operations.
49
- * Must match TransactionCoordinator.hashOperations for consistent validation.
50
- */
51
- private hashOperations;
52
44
  }
53
45
  //# sourceMappingURL=validator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/transaction/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAA2B,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9F,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACpI,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAa7D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAChC,sCAAsC;IACtC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,kDAAkD;IAClD,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG,MAAM;IAChD,qDAAqD;IACrD,YAAY,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,mDAAmD;IACnD,aAAa,IAAI,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC/C,4CAA4C;IAC5C,OAAO,IAAI,IAAI,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;AAE7F;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,qBAAqB;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,2BAA2B;IAC5C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;gBAFnB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,EACxC,2BAA2B,EAAE,4BAA4B,EACzD,kBAAkB,CAAC,EAAE,kBAAkB,YAAA;IAGnD,QAAQ,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAmFrF,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAKlE;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;;OAGG;YACW,cAAc;CAI5B"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/transaction/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC7J,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAI7D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAChC,sCAAsC;IACtC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,kDAAkD;IAClD,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACrC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,4BAA4B,GAAG,MAAM;IAChD,qDAAqD;IACrD,YAAY,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,mDAAmD;IACnD,aAAa,IAAI,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC/C,4CAA4C;IAC5C,OAAO,IAAI,IAAI,CAAC;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;AAE7F;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,qBAAqB;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,2BAA2B;IAC5C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IACpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;gBAHtB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,EACxC,2BAA2B,EAAE,4BAA4B,EACzD,kBAAkB,CAAC,EAAE,kBAAkB,YAAA,EACvC,qBAAqB,CAAC,EAAE,uBAAuB,YAAA;IAG3D,QAAQ,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA8IrF,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAIlE"}
@@ -1,5 +1,5 @@
1
- import { isTransactionExpired } from './transaction.js';
2
- import { hashString } from '../utility/hash-string.js';
1
+ import { isTransactionExpired, clientSignaturePayload, computeStampId } from './transaction.js';
2
+ import { collectOperations, hashOperations, opsHashVersion, OPS_HASH_VERSION } from './operations-hash.js';
3
3
  /**
4
4
  * Transaction validator implementation.
5
5
  *
@@ -10,20 +10,43 @@ export class TransactionValidator {
10
10
  engines;
11
11
  createValidationCoordinator;
12
12
  blockStateProvider;
13
- constructor(engines, createValidationCoordinator, blockStateProvider) {
13
+ verifyClientSignature;
14
+ constructor(engines, createValidationCoordinator, blockStateProvider, verifyClientSignature) {
14
15
  this.engines = engines;
15
16
  this.createValidationCoordinator = createValidationCoordinator;
16
17
  this.blockStateProvider = blockStateProvider;
18
+ this.verifyClientSignature = verifyClientSignature;
17
19
  }
18
20
  async validate(transaction, operationsHash) {
19
21
  const { stamp } = transaction;
20
- // 0. Check expiration before any other work
22
+ // 0.0. Integrity: the id must be the true hash of the stamp fields. Runs FIRST because
23
+ // every later step (expiration, signature, engine/schema selection) trusts a stamp field.
24
+ // Always-on (one SHA-256, cheap) and independent of whether a signature verifier is wired —
25
+ // a tampered stamp corrupts expiration and engine selection regardless of signatures.
26
+ const expectedId = await computeStampId(stamp);
27
+ if (expectedId !== stamp.id) {
28
+ return { valid: false, reason: 'Tampered transaction stamp' };
29
+ }
30
+ // 0. Check expiration before any other work. Ordered BEFORE the signature check so
31
+ // an attacker cannot learn signature-validity for an already-expired transaction.
21
32
  if (isTransactionExpired(stamp)) {
22
33
  return {
23
34
  valid: false,
24
35
  reason: `Transaction expired at ${stamp.expiration}`
25
36
  };
26
37
  }
38
+ // 0.5. Verify the client signature, if a verifier port is wired. When the port is
39
+ // absent (migration / single-node-dev posture) unsigned AND signed transactions
40
+ // both pass — the p2p enforcement flag decides whether to inject the port at all.
41
+ if (this.verifyClientSignature) {
42
+ if (transaction.signature === undefined) {
43
+ return { valid: false, reason: 'Missing client signature' };
44
+ }
45
+ const payload = clientSignaturePayload(stamp.id, transaction.statements, transaction.reads);
46
+ if (!this.verifyClientSignature(stamp.peerId, payload, transaction.signature)) {
47
+ return { valid: false, reason: 'Invalid client signature' };
48
+ }
49
+ }
27
50
  // 1. Verify engine exists
28
51
  const registration = this.engines.get(stamp.engineId);
29
52
  if (!registration) {
@@ -56,7 +79,24 @@ export class TransactionValidator {
56
79
  // 4. Create isolated validation coordinator
57
80
  const validationCoordinator = this.createValidationCoordinator();
58
81
  try {
59
- // 5. Re-execute transaction through engine
82
+ // 5. Re-execute transaction through engine.
83
+ //
84
+ // Which of the two ITransactionEngine models the registered engine uses decides
85
+ // where isolation comes from (see the contract in transaction.ts):
86
+ //
87
+ // (a) PURE TRANSLATOR (ActionsEngine) — execute() parses statements into
88
+ // actions and mutates NOTHING, so even an engine constructed against the
89
+ // MAIN coordinator cannot leak into main state here. The returned actions
90
+ // are applied once, on the isolated validationCoordinator at step 6.
91
+ //
92
+ // (b) SIDE-EFFECT APPLY (QuereusEngine) — execute() applies while translating
93
+ // (db.exec drives the vtab into coordinator.applyActions) and returns EMPTY
94
+ // actions. That application lands on whatever coordinator the engine/vtab is
95
+ // bound to, NOT on validationCoordinator, so isolation is the caller's job:
96
+ // the createValidationCoordinator wiring must bind/reset an isolated world
97
+ // (see quereus-validator, which resets the coordinator before each run and
98
+ // makes its validationCoordinator.applyActions a no-op). Step 6 is then
99
+ // skipped by the empty-actions guard.
60
100
  const result = await registration.engine.execute(transaction);
61
101
  if (!result.success) {
62
102
  return {
@@ -64,17 +104,36 @@ export class TransactionValidator {
64
104
  reason: `Re-execution failed: ${result.error}`
65
105
  };
66
106
  }
67
- // 6. Apply actions to validation coordinator (builds transforms)
107
+ // 6. Apply actions to the isolated validation coordinator (builds transforms).
108
+ // Reached only for pure-translator engines that RETURNED actions; a side-effect
109
+ // engine returns empty and already applied during execute() (see above).
68
110
  if (result.actions && result.actions.length > 0) {
69
111
  await validationCoordinator.applyActions(result.actions, stamp.id);
70
112
  }
71
113
  // 7. Collect operations from validation coordinator
72
114
  const transforms = validationCoordinator.getTransforms();
73
- const allOperations = this.collectOperations(transforms);
74
- // 8. Compute hash
75
- const computedHash = await this.hashOperations(allOperations);
76
- // 9. Compare with sender's hash
115
+ // 8. Compute hash via the shared operations-hash module — the SAME collect +
116
+ // canonicalise + hash the coordinator ran, so an honest sender and this
117
+ // validator cannot diverge on ordering.
118
+ const computedHash = await hashOperations(collectOperations(transforms));
119
+ // 9. Compare with sender's hash. Split the failure into two distinct causes so
120
+ // version skew is diagnosable rather than looking like a content fault:
121
+ // - VERSION SKEW: the sender's token carries a format version this node does not
122
+ // produce (a foreign vN, a bare legacy `ops:`, or an unparseable token → null).
123
+ // These bytes are not even comparable, so surface a clear "unsupported format
124
+ // version" error. This is DETECTION only — the node cannot cross-compute the
125
+ // peer's format, so a mixed-version cluster fails legibly, not silently.
126
+ // - CONTENT MISMATCH: same format version, different bytes — a genuine operations
127
+ // disagreement (or a Byzantine lie); the existing error is unchanged.
77
128
  if (computedHash !== operationsHash) {
129
+ const senderVersion = opsHashVersion(operationsHash);
130
+ if (senderVersion !== OPS_HASH_VERSION) {
131
+ return {
132
+ valid: false,
133
+ reason: `Unsupported operations-hash format version: local=${OPS_HASH_VERSION}, sender=${senderVersion ?? 'unrecognized'}`,
134
+ computedHash
135
+ };
136
+ }
78
137
  return {
79
138
  valid: false,
80
139
  reason: `Operations hash mismatch`,
@@ -91,23 +150,5 @@ export class TransactionValidator {
91
150
  const registration = this.engines.get(engineId);
92
151
  return registration ? await registration.getSchemaHash() : undefined;
93
152
  }
94
- /**
95
- * Collect all operations from transforms.
96
- */
97
- collectOperations(transforms) {
98
- return Array.from(transforms.entries()).flatMap(([collectionId, t]) => [
99
- ...Object.entries(t.inserts ?? {}).map(([blockId, block]) => ({ type: 'insert', collectionId, blockId, block })),
100
- ...Object.entries(t.updates ?? {}).map(([blockId, operations]) => ({ type: 'update', collectionId, blockId, operations })),
101
- ...(t.deletes ?? []).map(blockId => ({ type: 'delete', collectionId, blockId }))
102
- ]);
103
- }
104
- /**
105
- * Compute hash of all operations.
106
- * Must match TransactionCoordinator.hashOperations for consistent validation.
107
- */
108
- async hashOperations(operations) {
109
- const operationsData = JSON.stringify(operations);
110
- return `ops:${await hashString(operationsData)}`;
111
- }
112
153
  }
113
154
  //# sourceMappingURL=validator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/transaction/validator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/transaction/validator.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,25 @@ export declare class NetworkTransactor implements ITransactor, IBlockChangeNotif
31
31
  private readonly dialTimeoutMs;
32
32
  private readonly getRepo;
33
33
  private readonly localChangeNotifier;
34
+ /**
35
+ * Per-transaction coordinator cache: `actionId → (blockId → resolved coordinator)`.
36
+ * {@link pend} populates it from its final (retry-adjusted) batch assignment; commit
37
+ * reads it via {@link resolveCoordinator} before falling back to a live
38
+ * `findCoordinator`, so a block's coordinator is resolved once per transaction across
39
+ * the pend→commit window instead of once at pend and again at commit.
40
+ *
41
+ * Keyed by `actionId`, which is unique per transaction, so an entry is only ever read
42
+ * by commits of the SAME transaction — the ones that immediately follow its pend. Once
43
+ * those finish, nothing reads the entry again (a later transaction has a fresh
44
+ * actionId), so it carries no cross-transaction staleness even if it lingers. The TTL
45
+ * and size cap in {@link txnCoordinatorsFor} are therefore only a memory backstop that
46
+ * reclaims entries from transactions that pend but never commit — NOT a staleness
47
+ * bound. This is why keying by actionId gives the same "thrown away when the
48
+ * transaction ends" safety as threading a Map through the call, without touching the
49
+ * ITransactor contract.
50
+ */
51
+ private readonly txnCoordinatorCache;
52
+ private static readonly MAX_TXN_COORDINATOR_CACHE_ENTRIES;
34
53
  constructor(init: NetworkTransactorInit);
35
54
  /**
36
55
  * Subscribe to commits landing on the local node for `collectionId`, delegating
@@ -66,6 +85,22 @@ export declare class NetworkTransactor implements ITransactor, IBlockChangeNotif
66
85
  private commitBlocks;
67
86
  /** Creates batches for a given payload, grouped by the coordinating peer for each block id */
68
87
  private batchesForPayload;
88
+ /**
89
+ * Resolve the coordinator for `blockId`, preferring one this transaction already
90
+ * resolved during pend (the per-transaction cache) before falling back to a live
91
+ * `findCoordinator`. A cached coordinator that is in `excludedPeers` (already tried and
92
+ * failed during a retry) is skipped so a retry can't loop on a dead coordinator. A
93
+ * cache miss — including every call with no `actionId` (get/cancel) — never fails; it
94
+ * always falls through to live resolution.
95
+ */
96
+ private resolveCoordinator;
97
+ /**
98
+ * Get (creating if absent) the per-transaction coordinator map for `actionId`,
99
+ * refreshing its expiry and lazily sweeping expired sibling entries. See
100
+ * {@link txnCoordinatorCache} for why the TTL/size cap here is a memory backstop and
101
+ * not a staleness bound.
102
+ */
103
+ private txnCoordinatorsFor;
69
104
  /** Cancels a pending transaction by canceling all blocks associated with the transaction, including failed peers */
70
105
  private cancelBatch;
71
106
  private formatBatchStatuses;
@@ -1 +1 @@
1
- {"version":3,"file":"network-transactor.d.ts","sourceRoot":"","sources":["../../../src/transactor/network-transactor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAA6B,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAc,aAAa,EAA+B,qBAAqB,EAAE,YAAY,EAAU,MAAM,aAAa,CAAC;AAClU,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAS3F,KAAK,qBAAqB,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,WAAW,CAAC;IACxB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,KAAK,CAAC;IACnC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;CAC3C,CAAA;AAWD,qBAAa,iBAAkB,YAAW,WAAW,EAAE,oBAAoB;IAC1E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAmC;gBAGtE,IAAI,EAAE,qBAAqB;IAc5B;;;;;OAKG;IACH,kBAAkB,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI;IAQxF,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC;IAyHnD,SAAS,CAAC,YAAY,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA0C3E;;;;;;;;;;;OAWG;YACW,yBAAyB;IA6BvC,yGAAyG;YAC3F,sBAAsB;YAuBtB,uBAAuB;IA+F/B,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAgGnD,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9C,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAOtE,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;YAyC7C,WAAW;IAezB,0EAA0E;YAC5D,YAAY;IAoC1B,8FAA8F;YAChF,iBAAiB;IAe/B,oHAAoH;YACtG,WAAW;IAqBzB,OAAO,CAAC,mBAAmB;CAY3B;AAiDD;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAIlG"}
1
+ {"version":3,"file":"network-transactor.d.ts","sourceRoot":"","sources":["../../../src/transactor/network-transactor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAA6B,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,EAAc,aAAa,EAA+B,qBAAqB,EAAE,YAAY,EAAU,MAAM,aAAa,CAAC;AAClU,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAS3F,KAAK,qBAAqB,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,WAAW,CAAC;IACxB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,KAAK,CAAC;IACnC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;CAC3C,CAAA;AAWD,qBAAa,iBAAkB,YAAW,WAAW,EAAE,oBAAoB;IAC1E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IAChD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAmC;IAEvE;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAgF;IACpH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iCAAiC,CAAQ;gBAGhE,IAAI,EAAE,qBAAqB;IAc5B;;;;;OAKG;IACH,kBAAkB,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI;IAQxF,GAAG,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC;IAsInD,SAAS,CAAC,YAAY,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA0C3E;;;;;;;;;;;OAWG;YACW,yBAAyB;IA6BvC,yGAAyG;YAC3F,sBAAsB;YAuBtB,uBAAuB;IA+F/B,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAiHnD,MAAM,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9C,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAOtE,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;YAyC7C,WAAW;IAqBzB,0EAA0E;YAC5D,YAAY;IAsC1B,8FAA8F;YAChF,iBAAiB;IAiB/B;;;;;;;OAOG;YACW,kBAAkB;IAchC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IA2B1B,oHAAoH;YACtG,WAAW;IAqBzB,OAAO,CAAC,mBAAmB;CAY3B;AAiDD;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAIlG"}