@optimystic/db-core 0.21.0 → 0.24.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 (185) hide show
  1. package/README.md +336 -336
  2. package/dist/src/btree/btree.d.ts +2 -1
  3. package/dist/src/btree/btree.d.ts.map +1 -1
  4. package/dist/src/btree/btree.js +1 -1
  5. package/dist/src/btree/btree.js.map +1 -1
  6. package/dist/src/chain/chain.d.ts +1 -1
  7. package/dist/src/chain/chain.d.ts.map +1 -1
  8. package/dist/src/chain/chain.js +1 -1
  9. package/dist/src/chain/chain.js.map +1 -1
  10. package/dist/src/cluster/structs.d.ts +39 -1
  11. package/dist/src/cluster/structs.d.ts.map +1 -1
  12. package/dist/src/cluster/structs.js +24 -0
  13. package/dist/src/cluster/structs.js.map +1 -1
  14. package/dist/src/collection/collection.d.ts +20 -1
  15. package/dist/src/collection/collection.d.ts.map +1 -1
  16. package/dist/src/collection/collection.js +31 -4
  17. package/dist/src/collection/collection.js.map +1 -1
  18. package/dist/src/collections/diary/diary.d.ts.map +1 -1
  19. package/dist/src/collections/diary/diary.js +2 -1
  20. package/dist/src/collections/diary/diary.js.map +1 -1
  21. package/dist/src/collections/diary/struct.js +1 -1
  22. package/dist/src/collections/diary/struct.js.map +1 -1
  23. package/dist/src/collections/tree/collection-trunk.js +1 -1
  24. package/dist/src/collections/tree/collection-trunk.js.map +1 -1
  25. package/dist/src/collections/tree/struct.d.ts +1 -1
  26. package/dist/src/collections/tree/struct.d.ts.map +1 -1
  27. package/dist/src/collections/tree/struct.js +2 -1
  28. package/dist/src/collections/tree/struct.js.map +1 -1
  29. package/dist/src/collections/tree/tree.d.ts +5 -0
  30. package/dist/src/collections/tree/tree.d.ts.map +1 -1
  31. package/dist/src/collections/tree/tree.js +7 -0
  32. package/dist/src/collections/tree/tree.js.map +1 -1
  33. package/dist/src/log/log.d.ts +1 -1
  34. package/dist/src/log/log.d.ts.map +1 -1
  35. package/dist/src/log/log.js +2 -2
  36. package/dist/src/log/log.js.map +1 -1
  37. package/dist/src/network/i-peer-network.d.ts +16 -0
  38. package/dist/src/network/i-peer-network.d.ts.map +1 -1
  39. package/dist/src/network/struct.d.ts +39 -2
  40. package/dist/src/network/struct.d.ts.map +1 -1
  41. package/dist/src/network/struct.js +18 -0
  42. package/dist/src/network/struct.js.map +1 -1
  43. package/dist/src/testing/test-transactor.d.ts +95 -8
  44. package/dist/src/testing/test-transactor.d.ts.map +1 -1
  45. package/dist/src/testing/test-transactor.js +133 -12
  46. package/dist/src/testing/test-transactor.js.map +1 -1
  47. package/dist/src/transaction/coordinator.d.ts.map +1 -1
  48. package/dist/src/transaction/coordinator.js +2 -1
  49. package/dist/src/transaction/coordinator.js.map +1 -1
  50. package/dist/src/transaction/transaction.d.ts +1 -1
  51. package/dist/src/transaction/transaction.js +1 -1
  52. package/dist/src/transactor/network-transactor.d.ts.map +1 -1
  53. package/dist/src/transactor/network-transactor.js +57 -18
  54. package/dist/src/transactor/network-transactor.js.map +1 -1
  55. package/dist/src/transactor/transactor-source.d.ts.map +1 -1
  56. package/dist/src/transactor/transactor-source.js +25 -2
  57. package/dist/src/transactor/transactor-source.js.map +1 -1
  58. package/dist/src/transform/cache-source.js +1 -1
  59. package/dist/src/transform/cache-source.js.map +1 -1
  60. package/dist/src/transform/helpers.d.ts +6 -1
  61. package/dist/src/transform/helpers.d.ts.map +1 -1
  62. package/dist/src/transform/helpers.js +7 -6
  63. package/dist/src/transform/helpers.js.map +1 -1
  64. package/dist/src/transform/tracker.d.ts.map +1 -1
  65. package/dist/src/transform/tracker.js +2 -1
  66. package/dist/src/transform/tracker.js.map +1 -1
  67. package/package.json +1 -1
  68. package/src/btree/btree.ts +2 -1
  69. package/src/chain/chain.ts +2 -1
  70. package/src/cluster/membership.ts +85 -85
  71. package/src/cluster/structs.ts +43 -4
  72. package/src/cohort-topic/addressing.ts +120 -120
  73. package/src/cohort-topic/antidos/bootstrap-evidence-envelope.ts +253 -253
  74. package/src/cohort-topic/antidos/bootstrap-evidence.ts +106 -106
  75. package/src/cohort-topic/antidos/index.ts +5 -5
  76. package/src/cohort-topic/antidos/rate-limiter.ts +210 -210
  77. package/src/cohort-topic/antidos/replay-guard.ts +146 -146
  78. package/src/cohort-topic/antidos/topic-budget.ts +160 -160
  79. package/src/cohort-topic/antiflood/index.ts +2 -2
  80. package/src/cohort-topic/antiflood/invariants.ts +108 -108
  81. package/src/cohort-topic/antiflood/jitter.ts +117 -117
  82. package/src/cohort-topic/coldstart.ts +237 -237
  83. package/src/cohort-topic/dmax.ts +88 -88
  84. package/src/cohort-topic/gossip/bus.ts +254 -254
  85. package/src/cohort-topic/gossip/index.ts +3 -3
  86. package/src/cohort-topic/gossip/records.ts +45 -45
  87. package/src/cohort-topic/gossip/view.ts +91 -91
  88. package/src/cohort-topic/index.ts +20 -20
  89. package/src/cohort-topic/load/barometer.ts +134 -134
  90. package/src/cohort-topic/load/index.ts +1 -1
  91. package/src/cohort-topic/member-engine.ts +430 -430
  92. package/src/cohort-topic/membership/index.ts +3 -3
  93. package/src/cohort-topic/membership/publisher.ts +163 -163
  94. package/src/cohort-topic/membership/source.ts +41 -41
  95. package/src/cohort-topic/membership/verifier.ts +461 -461
  96. package/src/cohort-topic/ports.ts +157 -157
  97. package/src/cohort-topic/promotion.ts +405 -405
  98. package/src/cohort-topic/registration/bytes.ts +37 -37
  99. package/src/cohort-topic/registration/handoff.ts +154 -154
  100. package/src/cohort-topic/registration/index.ts +6 -6
  101. package/src/cohort-topic/registration/renewal.ts +495 -495
  102. package/src/cohort-topic/registration/sharding.ts +61 -61
  103. package/src/cohort-topic/registration/store.ts +81 -81
  104. package/src/cohort-topic/registration/types.ts +91 -91
  105. package/src/cohort-topic/ring-hash.ts +50 -50
  106. package/src/cohort-topic/service.ts +416 -416
  107. package/src/cohort-topic/sig/index.ts +2 -2
  108. package/src/cohort-topic/sig/payloads.ts +59 -59
  109. package/src/cohort-topic/sig/threshold.ts +64 -64
  110. package/src/cohort-topic/tiers.ts +74 -74
  111. package/src/cohort-topic/traffic.ts +233 -233
  112. package/src/cohort-topic/walk.ts +326 -326
  113. package/src/cohort-topic/willingness.ts +237 -237
  114. package/src/cohort-topic/wire/codec.ts +216 -216
  115. package/src/cohort-topic/wire/index.ts +18 -18
  116. package/src/cohort-topic/wire/payloads.ts +126 -126
  117. package/src/cohort-topic/wire/primitives.ts +188 -188
  118. package/src/cohort-topic/wire/types.ts +475 -475
  119. package/src/cohort-topic/wire/validate.ts +512 -512
  120. package/src/collection/collection-type-registry.ts +37 -37
  121. package/src/collection/collection.ts +32 -4
  122. package/src/collections/diary/diary.ts +68 -67
  123. package/src/collections/diary/struct.ts +1 -1
  124. package/src/collections/tree/collection-trunk.ts +1 -1
  125. package/src/collections/tree/readme.md +4 -0
  126. package/src/collections/tree/struct.ts +3 -1
  127. package/src/collections/tree/tree.ts +320 -312
  128. package/src/log/log.ts +2 -2
  129. package/src/matchmaking/capability-filter.ts +45 -45
  130. package/src/matchmaking/config.ts +98 -98
  131. package/src/matchmaking/index.ts +21 -21
  132. package/src/matchmaking/multi-cohort-seeker.ts +234 -234
  133. package/src/matchmaking/provider.ts +123 -123
  134. package/src/matchmaking/query-eval.ts +105 -105
  135. package/src/matchmaking/seeker-walk.ts +127 -127
  136. package/src/matchmaking/seeker.ts +86 -86
  137. package/src/matchmaking/topic-anchor.ts +90 -90
  138. package/src/matchmaking/voting-quorum.ts +394 -394
  139. package/src/matchmaking/wire.ts +603 -603
  140. package/src/network/i-peer-network.ts +17 -0
  141. package/src/network/stale-failure.ts +43 -43
  142. package/src/network/struct.ts +41 -2
  143. package/src/network/types.ts +37 -37
  144. package/src/reactivity/backfill.ts +220 -220
  145. package/src/reactivity/backpressure.ts +191 -191
  146. package/src/reactivity/checkpoint.ts +308 -308
  147. package/src/reactivity/config.ts +172 -172
  148. package/src/reactivity/dedupe.ts +132 -132
  149. package/src/reactivity/forwarder.ts +87 -87
  150. package/src/reactivity/index.ts +34 -34
  151. package/src/reactivity/notification.ts +123 -123
  152. package/src/reactivity/policy.ts +79 -79
  153. package/src/reactivity/push-state.ts +310 -310
  154. package/src/reactivity/recover.ts +153 -153
  155. package/src/reactivity/replay-buffer.ts +141 -141
  156. package/src/reactivity/resume.ts +549 -549
  157. package/src/reactivity/rotation.ts +415 -415
  158. package/src/reactivity/subscriber.ts +132 -132
  159. package/src/reactivity/subscription.ts +66 -66
  160. package/src/reactivity/topic-anchor.ts +71 -71
  161. package/src/reactivity/verify.ts +73 -73
  162. package/src/reactivity/wire-validate.ts +13 -13
  163. package/src/reactivity/wire.ts +224 -224
  164. package/src/testing/async-wait.ts +65 -65
  165. package/src/testing/index.ts +2 -2
  166. package/src/testing/test-transactor.ts +638 -489
  167. package/src/transaction/coordinator.ts +2 -1
  168. package/src/transaction/errors.ts +91 -91
  169. package/src/transaction/operations-hash.ts +196 -196
  170. package/src/transaction/read-dependency-collector.ts +78 -78
  171. package/src/transaction/transaction.ts +1 -1
  172. package/src/transactor/change-notifier.ts +80 -80
  173. package/src/transactor/index.ts +5 -5
  174. package/src/transactor/network-transactor.ts +58 -19
  175. package/src/transactor/transactor-source.ts +25 -2
  176. package/src/transform/atomic-proxy.ts +92 -92
  177. package/src/transform/cache-source.ts +1 -1
  178. package/src/transform/helpers.ts +159 -158
  179. package/src/transform/tracker.ts +2 -1
  180. package/src/utility/backoff.ts +95 -95
  181. package/src/utility/batch-coordinator.ts +191 -191
  182. package/dist/src/transaction/context.d.ts +0 -60
  183. package/dist/src/transaction/context.d.ts.map +0 -1
  184. package/dist/src/transaction/context.js +0 -91
  185. package/dist/src/transaction/context.js.map +0 -1
@@ -1,157 +1,157 @@
1
- /**
2
- * Cohort-topic substrate — transport ports.
3
- *
4
- * These are the seams that keep the cohort-topic substrate split cleanly across packages:
5
- * db-core defines the interfaces here (pure logic depends only on a hash function and
6
- * byte-array peer IDs), and db-p2p supplies the concrete FRET + libp2p implementations.
7
- *
8
- * **db-core never imports FRET or libp2p.** Every db-core substrate module takes these ports
9
- * by injection (constructor / factory args); db-p2p constructs the FRET-backed versions and
10
- * composes them with the db-core logic in `CohortTopicService`'s transport host.
11
- *
12
- * See `docs/cohort-topic.md` §FRET integration and `tickets` slug
13
- * `cohort-topic-package-layering` for the authoritative layering rule.
14
- */
15
-
16
- import type { MembershipCertV1 } from "./wire/types.js";
17
-
18
- /**
19
- * Ring coordinate — SHA-256 truncated to the ring width `B` (see {@link IRingHash}). db-core
20
- * owns this type; db-p2p maps it onto FRET's coordinate type, ensuring the byte representation
21
- * matches FRET's ring width so routing keys line up on the wire.
22
- */
23
- export type RingCoord = Uint8Array;
24
-
25
- /** A peer, referenced only by its opaque byte-array id. No multiaddr, no libp2p PeerId here. */
26
- export interface PeerRef {
27
- readonly id: Uint8Array;
28
- }
29
-
30
- /**
31
- * Wraps FRET's `RouteAndMaybeAct` so the walk / registration decision logic in db-core stays
32
- * transport-agnostic.
33
- */
34
- export interface ITopicRouter {
35
- /**
36
- * Route `activity` to the cohort owning `key` and run the cohort's activity callback,
37
- * collecting up to `wantK` participants and at least `minSigs` signatures.
38
- * @returns the encoded cohort reply.
39
- */
40
- routeAndAct(key: RingCoord, activity: Uint8Array, opts: { wantK: number; minSigs: number }): Promise<Uint8Array>;
41
- /** Direct dial to a cached primary; falls back to {@link routeAndAct} on failure (caller decides). */
42
- dialMember(member: PeerRef, activity: Uint8Array): Promise<Uint8Array>;
43
- }
44
-
45
- /** Intra-cohort gossip transport (FRET cohort gossip underneath). */
46
- export interface ICohortGossipTransport {
47
- /** Fire-and-forget broadcast of `msg` to the cohort at `coord`. */
48
- broadcast(coord: RingCoord, msg: Uint8Array): void;
49
- /** Subscribe to inbound cohort gossip; returns an unsubscribe handle. */
50
- onMessage(handler: (from: PeerRef, msg: Uint8Array) => void): () => void;
51
- }
52
-
53
- /** Authoritative cohort membership snapshots (FRET `MembershipCertV1` / stabilization underneath). */
54
- export interface IMembershipSource {
55
- /** Current cached membership cert for `coord`, encoded; `undefined` if none is cached. */
56
- current(coord: RingCoord): Promise<Uint8Array | undefined>;
57
- /** Force one refresh of `coord`'s membership cert (stale-cache retry); encoded, or `undefined`. */
58
- fetch(coord: RingCoord): Promise<Uint8Array | undefined>;
59
- }
60
-
61
- /**
62
- * Cohort threshold-signature primitive (FRET's `minSigs = k − x` cohort-signature assembly
63
- * underneath). db-core defines the seam; db-p2p binds FRET's signer/verifier without modifying it.
64
- * Peer ids are raw byte arrays here ({@link PeerRef}`.id`), matching the rest of the substrate; the
65
- * wire layer carries them as base64url strings.
66
- */
67
- export interface ICohortThresholdCrypto {
68
- /**
69
- * Assemble a cohort threshold signature over `payload`, collecting at least `minSigs` signers.
70
- * Resolves to the combined signature and the peers that contributed.
71
- */
72
- assemble(payload: Uint8Array, minSigs: number): Promise<{ thresholdSig: Uint8Array; signers: Uint8Array[] }>;
73
- /** Verify `thresholdSig` is a valid cohort signature over `payload` produced by `signers`. */
74
- verify(payload: Uint8Array, thresholdSig: Uint8Array, signers: readonly Uint8Array[]): boolean;
75
- }
76
-
77
- /**
78
- * Sink the cohort uses to publish a `MembershipCertV1` (over FRET's `/membership` protocol).
79
- * db-core's publisher builds + threshold-signs the cert and hands it here; db-p2p serves it.
80
- */
81
- export interface IMembershipPublishSink {
82
- /** Publish (advertise/serve) an already-signed membership certificate, encoded. */
83
- publish(encodedCert: Uint8Array): void;
84
- }
85
-
86
- /** Network-size estimate feeding `d_max`. */
87
- export interface ISizeEstimator {
88
- estimate(): { nEst: number; confidence: number };
89
- }
90
-
91
- /**
92
- * Verdict on whether a {@link MembershipCertV1}'s `(cohortCoord → members)` binding is vouched by a
93
- * source the verifying node *directly* trusts.
94
- *
95
- * - `"anchored"` — the binding is vouched (e.g. matches FRET `assembleCohort(coord)`, or the
96
- * tx-log commit certificate). The cert is trusted on this basis.
97
- * - `"rejected"` — the binding is contradicted (a known-different keyset owns this coord). A
98
- * `"rejected"` verdict is **fatal**: the cert is a forgery and is rejected even if it is
99
- * internally self-consistent, overriding the interim TOFU fallback.
100
- * - `"unknown"` — this node has no local authority over the coord, so it cannot judge. The
101
- * verifier falls through to the attestation chain / interim TOFU fallback.
102
- */
103
- export type TrustAnchorVerdict = "anchored" | "rejected" | "unknown";
104
-
105
- /**
106
- * Direct (base-case) trust anchor for a {@link MembershipCertV1}'s `coord → keyset` binding.
107
- *
108
- * db-core owns the chain-of-attestations and trust-root logic; the **direct** anchor is
109
- * tier/transport-specific (FRET ring agreement for T2/T3, tx-log commit certificate for T0/T1) and
110
- * is therefore delegated through this port. db-p2p binds it; **db-core never imports FRET**. A node
111
- * with no local authority for the coord returns `"unknown"` so the verifier falls through to the
112
- * chain / interim fallback instead of breaking distant verification. See {@link noAuthorityTrustAnchor}
113
- * for the db-core default (every coord `"unknown"`).
114
- */
115
- export interface IMembershipTrustAnchor {
116
- /** Judge, from a directly-trusted source, whether `cert.members` is authoritative for `cert.cohortCoord` at `tier`. */
117
- directAnchor(cert: MembershipCertV1, tier: number): TrustAnchorVerdict;
118
- }
119
-
120
- /**
121
- * An out-of-band-seeded trust root: the genesis-block-related cohorts a joining participant is told
122
- * to trust (validated against the genesis block hash by the caller before seeding). A trust root is
123
- * the base case of every attestation chain — a cert matching a root by `(coord, epoch, member-set)`
124
- * is trusted directly. Byte fields are raw (the verifier compares them against the cert's base64url
125
- * form internally).
126
- */
127
- export interface TrustRoot {
128
- /** Cohort coord (32 bytes). */
129
- readonly coord: Uint8Array;
130
- /** Cohort epoch (32 bytes) — required so a cert reusing a genesis coord with a swapped keyset is not a root. */
131
- readonly epoch: Uint8Array;
132
- /** Authoritative cohort members (any order; matched as a set). */
133
- readonly members: readonly Uint8Array[];
134
- }
135
-
136
- /**
137
- * The db-core default {@link IMembershipTrustAnchor}: it has no local authority over any coord, so it
138
- * returns `"unknown"` for every cert. Existing verifier callers that inject no anchor get this, keeping
139
- * the interim TOFU behavior (no regression) until db-p2p binds a real anchor.
140
- */
141
- export const noAuthorityTrustAnchor: IMembershipTrustAnchor = {
142
- directAnchor(_cert: MembershipCertV1, _tier: number): TrustAnchorVerdict {
143
- return "unknown";
144
- },
145
- };
146
-
147
- /**
148
- * Hash + ring math. db-core supplies its OWN SHA-256 (it already hashes logs and block ids);
149
- * the ring width is configuration. db-p2p, when mapping {@link RingCoord} onto FRET's coordinate
150
- * type, ensures `ringBits` matches FRET's ring width so coords are byte-compatible.
151
- */
152
- export interface IRingHash {
153
- /** SHA-256 of `bytes`, truncated to the ring width `B` ({@link ringBits}). */
154
- H(bytes: Uint8Array): RingCoord;
155
- /** Ring width in bits. */
156
- readonly ringBits: number;
157
- }
1
+ /**
2
+ * Cohort-topic substrate — transport ports.
3
+ *
4
+ * These are the seams that keep the cohort-topic substrate split cleanly across packages:
5
+ * db-core defines the interfaces here (pure logic depends only on a hash function and
6
+ * byte-array peer IDs), and db-p2p supplies the concrete FRET + libp2p implementations.
7
+ *
8
+ * **db-core never imports FRET or libp2p.** Every db-core substrate module takes these ports
9
+ * by injection (constructor / factory args); db-p2p constructs the FRET-backed versions and
10
+ * composes them with the db-core logic in `CohortTopicService`'s transport host.
11
+ *
12
+ * See `docs/cohort-topic.md` §FRET integration and `tickets` slug
13
+ * `cohort-topic-package-layering` for the authoritative layering rule.
14
+ */
15
+
16
+ import type { MembershipCertV1 } from "./wire/types.js";
17
+
18
+ /**
19
+ * Ring coordinate — SHA-256 truncated to the ring width `B` (see {@link IRingHash}). db-core
20
+ * owns this type; db-p2p maps it onto FRET's coordinate type, ensuring the byte representation
21
+ * matches FRET's ring width so routing keys line up on the wire.
22
+ */
23
+ export type RingCoord = Uint8Array;
24
+
25
+ /** A peer, referenced only by its opaque byte-array id. No multiaddr, no libp2p PeerId here. */
26
+ export interface PeerRef {
27
+ readonly id: Uint8Array;
28
+ }
29
+
30
+ /**
31
+ * Wraps FRET's `RouteAndMaybeAct` so the walk / registration decision logic in db-core stays
32
+ * transport-agnostic.
33
+ */
34
+ export interface ITopicRouter {
35
+ /**
36
+ * Route `activity` to the cohort owning `key` and run the cohort's activity callback,
37
+ * collecting up to `wantK` participants and at least `minSigs` signatures.
38
+ * @returns the encoded cohort reply.
39
+ */
40
+ routeAndAct(key: RingCoord, activity: Uint8Array, opts: { wantK: number; minSigs: number }): Promise<Uint8Array>;
41
+ /** Direct dial to a cached primary; falls back to {@link routeAndAct} on failure (caller decides). */
42
+ dialMember(member: PeerRef, activity: Uint8Array): Promise<Uint8Array>;
43
+ }
44
+
45
+ /** Intra-cohort gossip transport (FRET cohort gossip underneath). */
46
+ export interface ICohortGossipTransport {
47
+ /** Fire-and-forget broadcast of `msg` to the cohort at `coord`. */
48
+ broadcast(coord: RingCoord, msg: Uint8Array): void;
49
+ /** Subscribe to inbound cohort gossip; returns an unsubscribe handle. */
50
+ onMessage(handler: (from: PeerRef, msg: Uint8Array) => void): () => void;
51
+ }
52
+
53
+ /** Authoritative cohort membership snapshots (FRET `MembershipCertV1` / stabilization underneath). */
54
+ export interface IMembershipSource {
55
+ /** Current cached membership cert for `coord`, encoded; `undefined` if none is cached. */
56
+ current(coord: RingCoord): Promise<Uint8Array | undefined>;
57
+ /** Force one refresh of `coord`'s membership cert (stale-cache retry); encoded, or `undefined`. */
58
+ fetch(coord: RingCoord): Promise<Uint8Array | undefined>;
59
+ }
60
+
61
+ /**
62
+ * Cohort threshold-signature primitive (FRET's `minSigs = k − x` cohort-signature assembly
63
+ * underneath). db-core defines the seam; db-p2p binds FRET's signer/verifier without modifying it.
64
+ * Peer ids are raw byte arrays here ({@link PeerRef}`.id`), matching the rest of the substrate; the
65
+ * wire layer carries them as base64url strings.
66
+ */
67
+ export interface ICohortThresholdCrypto {
68
+ /**
69
+ * Assemble a cohort threshold signature over `payload`, collecting at least `minSigs` signers.
70
+ * Resolves to the combined signature and the peers that contributed.
71
+ */
72
+ assemble(payload: Uint8Array, minSigs: number): Promise<{ thresholdSig: Uint8Array; signers: Uint8Array[] }>;
73
+ /** Verify `thresholdSig` is a valid cohort signature over `payload` produced by `signers`. */
74
+ verify(payload: Uint8Array, thresholdSig: Uint8Array, signers: readonly Uint8Array[]): boolean;
75
+ }
76
+
77
+ /**
78
+ * Sink the cohort uses to publish a `MembershipCertV1` (over FRET's `/membership` protocol).
79
+ * db-core's publisher builds + threshold-signs the cert and hands it here; db-p2p serves it.
80
+ */
81
+ export interface IMembershipPublishSink {
82
+ /** Publish (advertise/serve) an already-signed membership certificate, encoded. */
83
+ publish(encodedCert: Uint8Array): void;
84
+ }
85
+
86
+ /** Network-size estimate feeding `d_max`. */
87
+ export interface ISizeEstimator {
88
+ estimate(): { nEst: number; confidence: number };
89
+ }
90
+
91
+ /**
92
+ * Verdict on whether a {@link MembershipCertV1}'s `(cohortCoord → members)` binding is vouched by a
93
+ * source the verifying node *directly* trusts.
94
+ *
95
+ * - `"anchored"` — the binding is vouched (e.g. matches FRET `assembleCohort(coord)`, or the
96
+ * tx-log commit certificate). The cert is trusted on this basis.
97
+ * - `"rejected"` — the binding is contradicted (a known-different keyset owns this coord). A
98
+ * `"rejected"` verdict is **fatal**: the cert is a forgery and is rejected even if it is
99
+ * internally self-consistent, overriding the interim TOFU fallback.
100
+ * - `"unknown"` — this node has no local authority over the coord, so it cannot judge. The
101
+ * verifier falls through to the attestation chain / interim TOFU fallback.
102
+ */
103
+ export type TrustAnchorVerdict = "anchored" | "rejected" | "unknown";
104
+
105
+ /**
106
+ * Direct (base-case) trust anchor for a {@link MembershipCertV1}'s `coord → keyset` binding.
107
+ *
108
+ * db-core owns the chain-of-attestations and trust-root logic; the **direct** anchor is
109
+ * tier/transport-specific (FRET ring agreement for T2/T3, tx-log commit certificate for T0/T1) and
110
+ * is therefore delegated through this port. db-p2p binds it; **db-core never imports FRET**. A node
111
+ * with no local authority for the coord returns `"unknown"` so the verifier falls through to the
112
+ * chain / interim fallback instead of breaking distant verification. See {@link noAuthorityTrustAnchor}
113
+ * for the db-core default (every coord `"unknown"`).
114
+ */
115
+ export interface IMembershipTrustAnchor {
116
+ /** Judge, from a directly-trusted source, whether `cert.members` is authoritative for `cert.cohortCoord` at `tier`. */
117
+ directAnchor(cert: MembershipCertV1, tier: number): TrustAnchorVerdict;
118
+ }
119
+
120
+ /**
121
+ * An out-of-band-seeded trust root: the genesis-block-related cohorts a joining participant is told
122
+ * to trust (validated against the genesis block hash by the caller before seeding). A trust root is
123
+ * the base case of every attestation chain — a cert matching a root by `(coord, epoch, member-set)`
124
+ * is trusted directly. Byte fields are raw (the verifier compares them against the cert's base64url
125
+ * form internally).
126
+ */
127
+ export interface TrustRoot {
128
+ /** Cohort coord (32 bytes). */
129
+ readonly coord: Uint8Array;
130
+ /** Cohort epoch (32 bytes) — required so a cert reusing a genesis coord with a swapped keyset is not a root. */
131
+ readonly epoch: Uint8Array;
132
+ /** Authoritative cohort members (any order; matched as a set). */
133
+ readonly members: readonly Uint8Array[];
134
+ }
135
+
136
+ /**
137
+ * The db-core default {@link IMembershipTrustAnchor}: it has no local authority over any coord, so it
138
+ * returns `"unknown"` for every cert. Existing verifier callers that inject no anchor get this, keeping
139
+ * the interim TOFU behavior (no regression) until db-p2p binds a real anchor.
140
+ */
141
+ export const noAuthorityTrustAnchor: IMembershipTrustAnchor = {
142
+ directAnchor(_cert: MembershipCertV1, _tier: number): TrustAnchorVerdict {
143
+ return "unknown";
144
+ },
145
+ };
146
+
147
+ /**
148
+ * Hash + ring math. db-core supplies its OWN SHA-256 (it already hashes logs and block ids);
149
+ * the ring width is configuration. db-p2p, when mapping {@link RingCoord} onto FRET's coordinate
150
+ * type, ensures `ringBits` matches FRET's ring width so coords are byte-compatible.
151
+ */
152
+ export interface IRingHash {
153
+ /** SHA-256 of `bytes`, truncated to the ring width `B` ({@link ringBits}). */
154
+ H(bytes: Uint8Array): RingCoord;
155
+ /** Ring width in bits. */
156
+ readonly ringBits: number;
157
+ }