@serfab/cadre-core 1.6.0 → 1.8.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.
- package/README.md +8 -6
- package/dist/cadre-node.d.ts +548 -137
- package/dist/cadre-node.js +1208 -383
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-authorization.d.ts +2 -2
- package/dist/control-authorization.js +1 -0
- package/dist/control-authorization.js.map +1 -1
- package/dist/control-cohort.d.ts +6 -0
- package/dist/control-cohort.js +6 -0
- package/dist/control-cohort.js.map +1 -1
- package/dist/control-database.d.ts +46 -8
- package/dist/control-database.js +97 -18
- package/dist/control-database.js.map +1 -1
- package/dist/control-formation-recorder.d.ts +37 -14
- package/dist/control-formation-recorder.js +60 -10
- package/dist/control-formation-recorder.js.map +1 -1
- package/dist/control-read-retry.d.ts +13 -12
- package/dist/control-read-retry.js +14 -12
- package/dist/control-read-retry.js.map +1 -1
- package/dist/control-schema.d.ts +1 -1
- package/dist/control-schema.js +67 -5
- package/dist/control-schema.js.map +1 -1
- package/dist/control-stream.d.ts +9 -1
- package/dist/control-stream.js +24 -1
- package/dist/control-stream.js.map +1 -1
- package/dist/control-write-retry.d.ts +12 -2
- package/dist/control-write-retry.js +13 -2
- package/dist/control-write-retry.js.map +1 -1
- package/dist/delegate-admission.d.ts +11 -8
- package/dist/delegate-admission.js +19 -11
- package/dist/delegate-admission.js.map +1 -1
- package/dist/diagnostics/connection-path.d.ts +0 -7
- package/dist/diagnostics/connection-path.js +0 -7
- package/dist/diagnostics/connection-path.js.map +1 -1
- package/dist/formation-approval.d.ts +7 -0
- package/dist/formation-approval.js +9 -3
- package/dist/formation-approval.js.map +1 -1
- package/dist/fs-atomic.d.ts +11 -2
- package/dist/fs-atomic.js +13 -3
- package/dist/fs-atomic.js.map +1 -1
- package/dist/hibernation-manager.d.ts +111 -8
- package/dist/hibernation-manager.js +234 -49
- package/dist/hibernation-manager.js.map +1 -1
- package/dist/index.d.ts +13 -6
- package/dist/index.js +27 -5
- package/dist/index.js.map +1 -1
- package/dist/joined-strand-store.d.ts +177 -0
- package/dist/joined-strand-store.js +431 -0
- package/dist/joined-strand-store.js.map +1 -0
- package/dist/key-store-file.js +14 -5
- package/dist/key-store-file.js.map +1 -1
- package/dist/key-store.d.ts +6 -0
- package/dist/key-store.js.map +1 -1
- package/dist/link-budget.d.ts +367 -69
- package/dist/link-budget.js +375 -72
- package/dist/link-budget.js.map +1 -1
- package/dist/membership-connection-gater.d.ts +30 -43
- package/dist/membership-connection-gater.js +31 -42
- package/dist/membership-connection-gater.js.map +1 -1
- package/dist/node-local-snapshot.d.ts +5 -4
- package/dist/node-local-snapshot.js +6 -3
- package/dist/node-local-snapshot.js.map +1 -1
- package/dist/peer-dial.d.ts +24 -4
- package/dist/peer-dial.js +74 -5
- package/dist/peer-dial.js.map +1 -1
- package/dist/peer-join-backfill.d.ts +35 -15
- package/dist/peer-join-backfill.js +115 -55
- package/dist/peer-join-backfill.js.map +1 -1
- package/dist/push-fanout.d.ts +6 -0
- package/dist/push-fanout.js +6 -0
- package/dist/push-fanout.js.map +1 -1
- package/dist/relay-reservation.d.ts +3 -1
- package/dist/relay-reservation.js +3 -1
- package/dist/relay-reservation.js.map +1 -1
- package/dist/relay-server.d.ts +79 -0
- package/dist/relay-server.js +74 -0
- package/dist/relay-server.js.map +1 -0
- package/dist/seed-bootstrap.d.ts +57 -4
- package/dist/seed-bootstrap.js +107 -83
- package/dist/seed-bootstrap.js.map +1 -1
- package/dist/storage-scope.d.ts +33 -17
- package/dist/storage-scope.js +44 -23
- package/dist/storage-scope.js.map +1 -1
- package/dist/strand-addr-protocol.d.ts +58 -21
- package/dist/strand-addr-protocol.js +133 -85
- package/dist/strand-addr-protocol.js.map +1 -1
- package/dist/strand-database.d.ts +20 -2
- package/dist/strand-database.js +42 -5
- package/dist/strand-database.js.map +1 -1
- package/dist/strand-first-sync-gate.d.ts +59 -21
- package/dist/strand-first-sync-gate.js +58 -19
- package/dist/strand-first-sync-gate.js.map +1 -1
- package/dist/strand-formation-deadlines.d.ts +151 -0
- package/dist/strand-formation-deadlines.js +171 -0
- package/dist/strand-formation-deadlines.js.map +1 -0
- package/dist/strand-formation-manager.d.ts +63 -30
- package/dist/strand-formation-manager.js +67 -41
- package/dist/strand-formation-manager.js.map +1 -1
- package/dist/strand-formation-protocol.d.ts +45 -35
- package/dist/strand-formation-protocol.js +59 -122
- package/dist/strand-formation-protocol.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +152 -6
- package/dist/strand-instance-manager.js +331 -42
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-membership-writer.d.ts +6 -0
- package/dist/strand-membership-writer.js +11 -0
- package/dist/strand-membership-writer.js.map +1 -1
- package/dist/strand-peer-book-file.d.ts +12 -0
- package/dist/strand-peer-book-file.js +37 -0
- package/dist/strand-peer-book-file.js.map +1 -0
- package/dist/strand-peer-book-protocol.d.ts +168 -0
- package/dist/strand-peer-book-protocol.js +356 -0
- package/dist/strand-peer-book-protocol.js.map +1 -0
- package/dist/strand-peer-book-swap.d.ts +104 -0
- package/dist/strand-peer-book-swap.js +284 -0
- package/dist/strand-peer-book-swap.js.map +1 -0
- package/dist/strand-peer-book.d.ts +159 -0
- package/dist/strand-peer-book.js +361 -0
- package/dist/strand-peer-book.js.map +1 -0
- package/dist/strand-peer-observer.d.ts +88 -0
- package/dist/strand-peer-observer.js +180 -0
- package/dist/strand-peer-observer.js.map +1 -0
- package/dist/strand-revocation-enforcer.js +2 -1
- package/dist/strand-revocation-enforcer.js.map +1 -1
- package/dist/strand-solicitation.d.ts +36 -20
- package/dist/strand-solicitation.js +4 -4
- package/dist/strand-solicitation.js.map +1 -1
- package/dist/strand-wake-protocol.d.ts +80 -23
- package/dist/strand-wake-protocol.js +89 -64
- package/dist/strand-wake-protocol.js.map +1 -1
- package/dist/types.d.ts +181 -33
- package/dist/types.js +4 -3
- package/dist/types.js.map +1 -1
- package/package.json +11 -7
- package/src/cadre-node.ts +1316 -398
- package/src/control-authorization.ts +2 -1
- package/src/control-cohort.ts +6 -0
- package/src/control-database.ts +122 -18
- package/src/control-formation-recorder.ts +354 -305
- package/src/control-read-retry.ts +14 -12
- package/src/control-schema.ts +67 -5
- package/src/control-stream.ts +25 -1
- package/src/control-write-retry.ts +13 -2
- package/src/delegate-admission.ts +23 -13
- package/src/diagnostics/connection-path.ts +0 -7
- package/src/formation-approval.ts +610 -604
- package/src/fs-atomic.ts +14 -4
- package/src/hibernation-manager.ts +638 -437
- package/src/index.ts +91 -6
- package/src/joined-strand-store.ts +498 -0
- package/src/key-store-file.ts +14 -5
- package/src/key-store.ts +6 -0
- package/src/link-budget.ts +393 -74
- package/src/membership-connection-gater.ts +31 -45
- package/src/node-local-snapshot.ts +293 -289
- package/src/peer-dial.ts +81 -7
- package/src/peer-join-backfill.ts +120 -57
- package/src/push-fanout.ts +6 -0
- package/src/relay-reservation.ts +3 -1
- package/src/relay-server.ts +98 -0
- package/src/seed-bootstrap.ts +133 -91
- package/src/storage-scope.ts +44 -23
- package/src/strand-addr-protocol.ts +547 -458
- package/src/strand-database.ts +287 -242
- package/src/strand-first-sync-gate.ts +58 -19
- package/src/strand-formation-deadlines.ts +227 -0
- package/src/strand-formation-manager.ts +700 -647
- package/src/strand-formation-protocol.ts +103 -150
- package/src/strand-instance-manager.ts +387 -45
- package/src/strand-membership-writer.ts +12 -0
- package/src/strand-peer-book-file.ts +39 -0
- package/src/strand-peer-book-protocol.ts +466 -0
- package/src/strand-peer-book-swap.ts +338 -0
- package/src/strand-peer-book.ts +475 -0
- package/src/strand-peer-observer.ts +235 -0
- package/src/strand-revocation-enforcer.ts +2 -1
- package/src/strand-solicitation.ts +519 -500
- package/src/strand-wake-protocol.ts +401 -355
- package/src/types.ts +185 -33
|
@@ -85,7 +85,10 @@
|
|
|
85
85
|
* infra outright, and admits peers it cannot place only within a bounded
|
|
86
86
|
* budget ({@link UnauthorizedReservationBudget}) — a member whose row is in
|
|
87
87
|
* flight always finds a slot under any sane cap, while outsiders cannot
|
|
88
|
-
* annex the party's relay capacity.
|
|
88
|
+
* annex the party's relay capacity. COUNT and lifetime are the only bounds
|
|
89
|
+
* on such a peer: a party-run relay forwards without libp2p's per-connection
|
|
90
|
+
* data and duration limit by default (`relay-server.ts`), so what a granted
|
|
91
|
+
* slot carries is not capped.
|
|
89
92
|
* - An `'admit-for-relay'` connection that is NOT reserving is dropped: it has
|
|
90
93
|
* {@link RELAY_ADMISSION_RESERVE_DEADLINE_MS} to get a reservation ADMITTED
|
|
91
94
|
* at that hook, after which the gate CLOSES the underlying connection so
|
|
@@ -160,6 +163,8 @@ import type { ConnectionGater, PeerId, MultiaddrConnection } from '@libp2p/inter
|
|
|
160
163
|
import { SEED_PROTOCOL } from './seed-bootstrap.js';
|
|
161
164
|
import { FORMATION_PROTOCOL } from './strand-formation-protocol.js';
|
|
162
165
|
import { withDeadline } from './control-stream.js';
|
|
166
|
+
import { PARTY_RELAY_RESERVATION_TTL_MS } from './relay-server.js';
|
|
167
|
+
import { ADMISSION_DECISION_TIMEOUT_MS, relayAdmissionReserveDeadlineMs } from './link-budget.js';
|
|
163
168
|
|
|
164
169
|
const log = debug('sereus:cadre:connection-gater');
|
|
165
170
|
|
|
@@ -180,22 +185,6 @@ export const STRANGER_OPEN_PROTOCOLS: readonly string[] = [SEED_PROTOCOL, FORMAT
|
|
|
180
185
|
*/
|
|
181
186
|
export const DEFAULT_ENROLLMENT_WINDOW_MS = 30 * 60 * 1000;
|
|
182
187
|
|
|
183
|
-
/**
|
|
184
|
-
* Deadline for one admission decision, after which the fail-open outcome is
|
|
185
|
-
* used (connection admitted / reservation admitted).
|
|
186
|
-
*
|
|
187
|
-
* libp2p awaits `denyInboundEncryptedConnection` inside the inbound upgrade
|
|
188
|
-
* WITHOUT racing its inbound-upgrade timeout signal (unlike the pre-encryption
|
|
189
|
-
* `denyInboundConnection` hook), so a decision that never settles wedges that
|
|
190
|
-
* upgrade forever — the connection-manager's inbound-upgrade slot is taken by
|
|
191
|
-
* `acceptIncomingConnection` and released in the `finally` that never runs. The
|
|
192
|
-
* real policy reads the control DB (`listAuthorizedMembers`), which can pull
|
|
193
|
-
* over the network, so "never settles" is reachable. Bounding it here keeps the
|
|
194
|
-
* fail-open contract honest: a slow decision admits rather than silently
|
|
195
|
-
* failing closed (or not at all).
|
|
196
|
-
*/
|
|
197
|
-
export const ADMISSION_DECISION_TIMEOUT_MS = 2_000;
|
|
198
|
-
|
|
199
188
|
/**
|
|
200
189
|
* How long an `'admit-for-relay'` connection may exist without a relay
|
|
201
190
|
* reservation being ADMITTED at the `denyInboundRelayReservation` hook, after
|
|
@@ -204,8 +193,13 @@ export const ADMISSION_DECISION_TIMEOUT_MS = 2_000;
|
|
|
204
193
|
* dials and requests in one drive; a strand node's configured circuit listener
|
|
205
194
|
* does the same from inside its own `listen()`), so a connection idle past this
|
|
206
195
|
* deadline is not reserving.
|
|
196
|
+
*
|
|
197
|
+
* Derived from the link ({@link relayAdmissionReserveDeadlineMs}): one link round trip for the
|
|
198
|
+
* request to arrive plus one admission decision on it. This is the value at the default
|
|
199
|
+
* declaration; `CadreNode` passes the one derived from the relay's OWN declaration, because the
|
|
200
|
+
* relay is the machine that decides.
|
|
207
201
|
*/
|
|
208
|
-
export const RELAY_ADMISSION_RESERVE_DEADLINE_MS =
|
|
202
|
+
export const RELAY_ADMISSION_RESERVE_DEADLINE_MS = relayAdmissionReserveDeadlineMs();
|
|
209
203
|
|
|
210
204
|
/**
|
|
211
205
|
* Bound on the graceful close of an expired relay-only connection. It exists
|
|
@@ -218,6 +212,7 @@ export const RELAY_ADMISSION_RESERVE_DEADLINE_MS = 5_000;
|
|
|
218
212
|
* Applied through {@link withDeadline}, not `AbortSignal.timeout`: the latter is
|
|
219
213
|
* not reliably present on React Native/Hermes, which loads this same module.
|
|
220
214
|
*/
|
|
215
|
+
// eslint-disable-next-line no-restricted-syntax -- link-independent: bounds a local connection close inside a timer callback, and expiry aborts the connection instead
|
|
221
216
|
export const RELAY_ADMISSION_CLOSE_TIMEOUT_MS = 2_000;
|
|
222
217
|
|
|
223
218
|
/**
|
|
@@ -228,31 +223,17 @@ export const RELAY_ADMISSION_CLOSE_TIMEOUT_MS = 2_000;
|
|
|
228
223
|
* `network.unauthorizedRelayReservationCap` (0 refuses every unauthorized
|
|
229
224
|
* reservation — the strict pre-seam posture).
|
|
230
225
|
*
|
|
231
|
-
* NOTE: this cap shares the relay server's own reservation store, whose
|
|
232
|
-
* size is
|
|
233
|
-
* unplaced peers may therefore occupy up to this many of
|
|
234
|
-
* rest are what members and delegates compete for.
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
226
|
+
* NOTE: this cap shares the relay server's own reservation store, whose
|
|
227
|
+
* party-run default size is `PARTY_RELAY_MAX_RESERVATIONS` (128,
|
|
228
|
+
* `relay-server.ts`); unplaced peers may therefore occupy up to this many of
|
|
229
|
+
* those slots, and the rest are what members and delegates compete for. The two
|
|
230
|
+
* are kept apart by hand — if this is raised, or an embedder shrinks the store
|
|
231
|
+
* through `network.relayServerInit.reservations.maxReservations`, keep this one
|
|
232
|
+
* well under the store's, or a fleet of unplaceable peers can crowd genuine
|
|
233
|
+
* members out of the server's own store (which the gate cannot override).
|
|
238
234
|
*/
|
|
239
235
|
export const MAX_UNAUTHORIZED_RELAY_RESERVATIONS = 8;
|
|
240
236
|
|
|
241
|
-
/**
|
|
242
|
-
* How long one {@link UnauthorizedReservationBudget} entry occupies a slot
|
|
243
|
-
* without a refresh. Mirrors the relay server's own default reservation TTL
|
|
244
|
-
* (`@libp2p/circuit-relay-v2`'s `DEFAULT_MAX_RESERVATION_TTL`, 2 h): the server
|
|
245
|
-
* holds an unrefreshed reservation exactly that long, and a live reserver
|
|
246
|
-
* re-requests (re-hitting the admission hook, refreshing its entry) well before
|
|
247
|
-
* expiry — so the live entry count tracks the server's own occupancy without
|
|
248
|
-
* this module reaching into the server's reservation store.
|
|
249
|
-
*
|
|
250
|
-
* NOTE: a mirror, not a live coupling — if the relay server is ever configured
|
|
251
|
-
* with a non-default `reservationTtl` (db-p2p's `relayServerInit`), update this
|
|
252
|
-
* constant alongside it or the budget's occupancy drifts from the server's.
|
|
253
|
-
*/
|
|
254
|
-
export const UNAUTHORIZED_RESERVATION_TTL_MS = 2 * 60 * 60 * 1000;
|
|
255
|
-
|
|
256
237
|
/**
|
|
257
238
|
* The connection-level outcome of the admission policy:
|
|
258
239
|
* - `'admit'` — a peer with a legitimate claim on the connection (member,
|
|
@@ -295,9 +276,13 @@ export interface InboundAdmissionPolicy {
|
|
|
295
276
|
* Bounded budget of concurrent relay reservations for peers the membership
|
|
296
277
|
* check could not place. `tryAdmit` is the whole surface: an already-admitted
|
|
297
278
|
* peer refreshes its entry (a reservation refresh never double-counts), a new
|
|
298
|
-
* peer takes a free slot or is refused. Entries expire after `ttlMs
|
|
299
|
-
*
|
|
300
|
-
* server
|
|
279
|
+
* peer takes a free slot or is refused. Entries expire after `ttlMs`, which
|
|
280
|
+
* `CadreNode` passes as the relay server's own resolved `reservationTtl`
|
|
281
|
+
* (`relay-server.ts`): the server holds an unrefreshed reservation exactly that
|
|
282
|
+
* long, and a live reserver re-requests (re-hitting the admission hook,
|
|
283
|
+
* refreshing its entry) well before expiry — so the live entry count tracks the
|
|
284
|
+
* server's own occupancy without this module reaching into the server's
|
|
285
|
+
* reservation store. Injectable `now` keeps expiry testable without fake
|
|
301
286
|
* timers. Authorized members and delegates are never run through this — the
|
|
302
287
|
* policy admits them before consulting the budget, and `release`s the slot such
|
|
303
288
|
* a peer took while it was still unplaceable, so the boot-ordering window a
|
|
@@ -307,8 +292,9 @@ export class UnauthorizedReservationBudget {
|
|
|
307
292
|
private readonly admitted = new Map<string, number>();
|
|
308
293
|
|
|
309
294
|
constructor(
|
|
310
|
-
|
|
311
|
-
|
|
295
|
+
/** Most peers admitted at once — `network.unauthorizedRelayReservationCap`, resolved. */
|
|
296
|
+
readonly cap: number = MAX_UNAUTHORIZED_RELAY_RESERVATIONS,
|
|
297
|
+
private readonly ttlMs: number = PARTY_RELAY_RESERVATION_TTL_MS
|
|
312
298
|
) {}
|
|
313
299
|
|
|
314
300
|
/** Number of live (unexpired at last prune) entries — test/diagnostic surface. */
|