@optimystic/db-core 0.22.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +336 -336
- package/dist/src/cluster/structs.d.ts +39 -1
- package/dist/src/cluster/structs.d.ts.map +1 -1
- package/dist/src/cluster/structs.js +24 -0
- package/dist/src/cluster/structs.js.map +1 -1
- package/dist/src/collection/collection.d.ts +17 -0
- package/dist/src/collection/collection.d.ts.map +1 -1
- package/dist/src/collection/collection.js +24 -2
- package/dist/src/collection/collection.js.map +1 -1
- package/dist/src/collections/tree/tree.d.ts +5 -0
- package/dist/src/collections/tree/tree.d.ts.map +1 -1
- package/dist/src/collections/tree/tree.js +7 -0
- package/dist/src/collections/tree/tree.js.map +1 -1
- package/dist/src/network/i-peer-network.d.ts +16 -0
- package/dist/src/network/i-peer-network.d.ts.map +1 -1
- package/dist/src/network/struct.d.ts +39 -2
- package/dist/src/network/struct.d.ts.map +1 -1
- package/dist/src/network/struct.js +18 -0
- package/dist/src/network/struct.js.map +1 -1
- package/dist/src/testing/test-transactor.d.ts +95 -8
- package/dist/src/testing/test-transactor.d.ts.map +1 -1
- package/dist/src/testing/test-transactor.js +121 -8
- package/dist/src/testing/test-transactor.js.map +1 -1
- package/dist/src/transaction/transaction.d.ts +1 -1
- package/dist/src/transaction/transaction.js +1 -1
- package/dist/src/transactor/network-transactor.d.ts.map +1 -1
- package/dist/src/transactor/network-transactor.js +48 -13
- package/dist/src/transactor/network-transactor.js.map +1 -1
- package/dist/src/transactor/transactor-source.d.ts.map +1 -1
- package/dist/src/transactor/transactor-source.js +25 -2
- package/dist/src/transactor/transactor-source.js.map +1 -1
- package/package.json +1 -1
- package/src/cluster/membership.ts +85 -85
- package/src/cluster/structs.ts +43 -4
- package/src/cohort-topic/addressing.ts +120 -120
- package/src/cohort-topic/antidos/bootstrap-evidence-envelope.ts +253 -253
- package/src/cohort-topic/antidos/bootstrap-evidence.ts +106 -106
- package/src/cohort-topic/antidos/index.ts +5 -5
- package/src/cohort-topic/antidos/rate-limiter.ts +210 -210
- package/src/cohort-topic/antidos/replay-guard.ts +146 -146
- package/src/cohort-topic/antidos/topic-budget.ts +160 -160
- package/src/cohort-topic/antiflood/index.ts +2 -2
- package/src/cohort-topic/antiflood/invariants.ts +108 -108
- package/src/cohort-topic/antiflood/jitter.ts +117 -117
- package/src/cohort-topic/coldstart.ts +237 -237
- package/src/cohort-topic/dmax.ts +88 -88
- package/src/cohort-topic/gossip/bus.ts +254 -254
- package/src/cohort-topic/gossip/index.ts +3 -3
- package/src/cohort-topic/gossip/records.ts +45 -45
- package/src/cohort-topic/gossip/view.ts +91 -91
- package/src/cohort-topic/index.ts +20 -20
- package/src/cohort-topic/load/barometer.ts +134 -134
- package/src/cohort-topic/load/index.ts +1 -1
- package/src/cohort-topic/member-engine.ts +430 -430
- package/src/cohort-topic/membership/index.ts +3 -3
- package/src/cohort-topic/membership/publisher.ts +163 -163
- package/src/cohort-topic/membership/source.ts +41 -41
- package/src/cohort-topic/membership/verifier.ts +461 -461
- package/src/cohort-topic/ports.ts +157 -157
- package/src/cohort-topic/promotion.ts +405 -405
- package/src/cohort-topic/registration/bytes.ts +37 -37
- package/src/cohort-topic/registration/handoff.ts +154 -154
- package/src/cohort-topic/registration/index.ts +6 -6
- package/src/cohort-topic/registration/renewal.ts +495 -495
- package/src/cohort-topic/registration/sharding.ts +61 -61
- package/src/cohort-topic/registration/store.ts +81 -81
- package/src/cohort-topic/registration/types.ts +91 -91
- package/src/cohort-topic/ring-hash.ts +50 -50
- package/src/cohort-topic/service.ts +416 -416
- package/src/cohort-topic/sig/index.ts +2 -2
- package/src/cohort-topic/sig/payloads.ts +59 -59
- package/src/cohort-topic/sig/threshold.ts +64 -64
- package/src/cohort-topic/tiers.ts +74 -74
- package/src/cohort-topic/traffic.ts +233 -233
- package/src/cohort-topic/walk.ts +326 -326
- package/src/cohort-topic/willingness.ts +237 -237
- package/src/cohort-topic/wire/codec.ts +216 -216
- package/src/cohort-topic/wire/index.ts +18 -18
- package/src/cohort-topic/wire/payloads.ts +126 -126
- package/src/cohort-topic/wire/primitives.ts +188 -188
- package/src/cohort-topic/wire/types.ts +475 -475
- package/src/cohort-topic/wire/validate.ts +512 -512
- package/src/collection/collection-type-registry.ts +37 -37
- package/src/collection/collection.ts +25 -2
- package/src/collections/diary/diary.ts +68 -68
- package/src/collections/tree/readme.md +4 -0
- package/src/collections/tree/tree.ts +320 -312
- package/src/matchmaking/capability-filter.ts +45 -45
- package/src/matchmaking/config.ts +98 -98
- package/src/matchmaking/index.ts +21 -21
- package/src/matchmaking/multi-cohort-seeker.ts +234 -234
- package/src/matchmaking/provider.ts +123 -123
- package/src/matchmaking/query-eval.ts +105 -105
- package/src/matchmaking/seeker-walk.ts +127 -127
- package/src/matchmaking/seeker.ts +86 -86
- package/src/matchmaking/topic-anchor.ts +90 -90
- package/src/matchmaking/voting-quorum.ts +394 -394
- package/src/matchmaking/wire.ts +603 -603
- package/src/network/i-peer-network.ts +17 -0
- package/src/network/stale-failure.ts +43 -43
- package/src/network/struct.ts +41 -2
- package/src/network/types.ts +37 -37
- package/src/reactivity/backfill.ts +220 -220
- package/src/reactivity/backpressure.ts +191 -191
- package/src/reactivity/checkpoint.ts +308 -308
- package/src/reactivity/config.ts +172 -172
- package/src/reactivity/dedupe.ts +132 -132
- package/src/reactivity/forwarder.ts +87 -87
- package/src/reactivity/index.ts +34 -34
- package/src/reactivity/notification.ts +123 -123
- package/src/reactivity/policy.ts +79 -79
- package/src/reactivity/push-state.ts +310 -310
- package/src/reactivity/recover.ts +153 -153
- package/src/reactivity/replay-buffer.ts +141 -141
- package/src/reactivity/resume.ts +549 -549
- package/src/reactivity/rotation.ts +415 -415
- package/src/reactivity/subscriber.ts +132 -132
- package/src/reactivity/subscription.ts +66 -66
- package/src/reactivity/topic-anchor.ts +71 -71
- package/src/reactivity/verify.ts +73 -73
- package/src/reactivity/wire-validate.ts +13 -13
- package/src/reactivity/wire.ts +224 -224
- package/src/testing/async-wait.ts +65 -65
- package/src/testing/index.ts +2 -2
- package/src/testing/test-transactor.ts +638 -502
- package/src/transaction/errors.ts +91 -91
- package/src/transaction/operations-hash.ts +196 -196
- package/src/transaction/read-dependency-collector.ts +78 -78
- package/src/transaction/transaction.ts +1 -1
- package/src/transactor/change-notifier.ts +80 -80
- package/src/transactor/index.ts +5 -5
- package/src/transactor/network-transactor.ts +49 -14
- package/src/transactor/transactor-source.ts +25 -2
- package/src/transform/atomic-proxy.ts +92 -92
- package/src/transform/helpers.ts +159 -159
- package/src/utility/backoff.ts +95 -95
- package/src/utility/batch-coordinator.ts +191 -191
- package/dist/src/transaction/context.d.ts +0 -60
- package/dist/src/transaction/context.d.ts.map +0 -1
- package/dist/src/transaction/context.js +0 -91
- 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
|
+
}
|