@serfab/cadre-core 1.3.0 → 1.5.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 (90) hide show
  1. package/README.md +5 -3
  2. package/dist/cadre-node.d.ts +70 -34
  3. package/dist/cadre-node.js +197 -60
  4. package/dist/cadre-node.js.map +1 -1
  5. package/dist/control-database.d.ts +24 -10
  6. package/dist/control-database.js +48 -16
  7. package/dist/control-database.js.map +1 -1
  8. package/dist/control-formation-recorder.d.ts +4 -4
  9. package/dist/control-formation-recorder.js +6 -6
  10. package/dist/control-formation-recorder.js.map +1 -1
  11. package/dist/control-read-retry.d.ts +12 -0
  12. package/dist/control-read-retry.js +12 -0
  13. package/dist/control-read-retry.js.map +1 -1
  14. package/dist/control-write-retry.d.ts +5 -4
  15. package/dist/control-write-retry.js +24 -7
  16. package/dist/control-write-retry.js.map +1 -1
  17. package/dist/index.d.ts +5 -4
  18. package/dist/index.js +10 -5
  19. package/dist/index.js.map +1 -1
  20. package/dist/link-budget.d.ts +182 -0
  21. package/dist/link-budget.js +195 -0
  22. package/dist/link-budget.js.map +1 -0
  23. package/dist/membership-connection-gater.d.ts +18 -5
  24. package/dist/membership-connection-gater.js +50 -10
  25. package/dist/membership-connection-gater.js.map +1 -1
  26. package/dist/peer-dial.d.ts +36 -17
  27. package/dist/peer-dial.js +37 -17
  28. package/dist/peer-dial.js.map +1 -1
  29. package/dist/peer-join-backfill.d.ts +58 -4
  30. package/dist/peer-join-backfill.js +165 -20
  31. package/dist/peer-join-backfill.js.map +1 -1
  32. package/dist/relay-reservation.d.ts +59 -11
  33. package/dist/relay-reservation.js +169 -43
  34. package/dist/relay-reservation.js.map +1 -1
  35. package/dist/seed-bootstrap.js +2 -1
  36. package/dist/seed-bootstrap.js.map +1 -1
  37. package/dist/storage-scope.d.ts +50 -12
  38. package/dist/storage-scope.js +85 -12
  39. package/dist/storage-scope.js.map +1 -1
  40. package/dist/strand-first-sync-gate.d.ts +43 -5
  41. package/dist/strand-first-sync-gate.js +55 -7
  42. package/dist/strand-first-sync-gate.js.map +1 -1
  43. package/dist/strand-formation-manager.js +2 -1
  44. package/dist/strand-formation-manager.js.map +1 -1
  45. package/dist/strand-id.d.ts +35 -0
  46. package/dist/strand-id.js +46 -0
  47. package/dist/strand-id.js.map +1 -0
  48. package/dist/strand-instance-manager.d.ts +27 -2
  49. package/dist/strand-instance-manager.js +75 -15
  50. package/dist/strand-instance-manager.js.map +1 -1
  51. package/dist/strand-membership-reconciler.d.ts +200 -45
  52. package/dist/strand-membership-reconciler.js +302 -86
  53. package/dist/strand-membership-reconciler.js.map +1 -1
  54. package/dist/strand-membership-writer.d.ts +3 -2
  55. package/dist/strand-membership-writer.js +67 -90
  56. package/dist/strand-membership-writer.js.map +1 -1
  57. package/dist/strand-network-config.d.ts +3 -3
  58. package/dist/strand-network-config.js +3 -3
  59. package/dist/strand-solicitation.js +2 -1
  60. package/dist/strand-solicitation.js.map +1 -1
  61. package/dist/strand-watcher.d.ts +45 -0
  62. package/dist/strand-watcher.js +74 -13
  63. package/dist/strand-watcher.js.map +1 -1
  64. package/dist/types.d.ts +190 -24
  65. package/dist/types.js +73 -4
  66. package/dist/types.js.map +1 -1
  67. package/package.json +8 -8
  68. package/src/cadre-node.ts +7445 -7302
  69. package/src/control-database.ts +48 -16
  70. package/src/control-formation-recorder.ts +6 -6
  71. package/src/control-read-retry.ts +214 -202
  72. package/src/control-write-retry.ts +24 -7
  73. package/src/index.ts +29 -2
  74. package/src/link-budget.ts +217 -0
  75. package/src/membership-connection-gater.ts +56 -11
  76. package/src/peer-dial.ts +39 -17
  77. package/src/peer-join-backfill.ts +192 -23
  78. package/src/relay-reservation.ts +1119 -951
  79. package/src/seed-bootstrap.ts +2 -1
  80. package/src/storage-scope.ts +163 -78
  81. package/src/strand-first-sync-gate.ts +55 -7
  82. package/src/strand-formation-manager.ts +647 -646
  83. package/src/strand-id.ts +48 -0
  84. package/src/strand-instance-manager.ts +1516 -1440
  85. package/src/strand-membership-reconciler.ts +334 -92
  86. package/src/strand-membership-writer.ts +1962 -1987
  87. package/src/strand-network-config.ts +250 -250
  88. package/src/strand-solicitation.ts +500 -499
  89. package/src/strand-watcher.ts +388 -325
  90. package/src/types.ts +192 -23
@@ -20,6 +20,13 @@ export class StrandWatcher {
20
20
  this.provisional = new Set();
21
21
  /** Ids whose last launch attempt threw, with the backoff gating their retry. */
22
22
  this.failureStates = new Map();
23
+ /**
24
+ * Ids a deliberate local stop has withdrawn from offer for the rest of the session
25
+ * (see {@link suppressStrand}). Before {@link forgetStrand} existed, `knownStrands`
26
+ * retention alone made a stop permanent; now that a failed claim can un-know a
27
+ * strand, the permanence has to be recorded explicitly.
28
+ */
29
+ this.suppressed = new Set();
23
30
  this.pollTimer = null;
24
31
  this.initialPollTimer = null;
25
32
  this.running = false;
@@ -84,6 +91,8 @@ export class StrandWatcher {
84
91
  const currentMap = new Map(currentStrands.map(s => [s.Id, s]));
85
92
  // Find added strands
86
93
  for (const strand of currentStrands) {
94
+ if (this.suppressed.has(strand.Id))
95
+ continue; // deliberately stopped locally
87
96
  if (this.knownStrands.has(strand.Id))
88
97
  continue;
89
98
  const failure = this.failureStates.get(strand.Id);
@@ -108,17 +117,7 @@ export class StrandWatcher {
108
117
  }
109
118
  catch (error) {
110
119
  log('Error handling strand add for %s: %o', strand.Id, error);
111
- // A failed launch leaves nothing running (StrandInstanceManager drops the
112
- // record), so forget the strand and let a later poll retry it — gated by
113
- // the backoff recorded here. One case does leave something running: a row
114
- // this machine published lands on an instance something else already
115
- // attached, and honouring the founder request on it (CadreNode.launchStrand
116
- // → StrandInstanceManager.foundExistingStrand) throws. The instance stays up
117
- // as a joiner and the retry re-attempts the bootstrap on it, which is what
118
- // should happen — but do not read the line above as "nothing is running".
119
- this.knownStrands.delete(strand.Id);
120
- this.provisional.delete(strand.Id);
121
- this.recordFailure(strand.Id);
120
+ this.forgetStrand(strand.Id);
122
121
  }
123
122
  }
124
123
  // Re-evaluate provisional admissions whose sAppId may now be resolvable.
@@ -162,13 +161,25 @@ export class StrandWatcher {
162
161
  }
163
162
  }
164
163
  }
165
- // Drop backoff state for strands whose control-network row is gone; a row
166
- // that reappears is a fresh strand and gets a fresh first attempt.
164
+ // Drop backoff and suppression state for strands whose control-network row is
165
+ // gone; a row that reappears is a fresh strand and gets a fresh first attempt,
166
+ // un-backed-off and un-suppressed.
167
167
  for (const strandId of [...this.failureStates.keys()]) {
168
168
  if (!currentMap.has(strandId)) {
169
169
  this.failureStates.delete(strandId);
170
170
  }
171
171
  }
172
+ // NOTE: the clear needs a poll that actually SEES the row absent, so a sibling that
173
+ // unpublishes and re-publishes a locally-stopped id inside one poll interval leaves
174
+ // it suppressed for the session. Contrived today — re-seating a removed id is
175
+ // owner-gated and manual — and there is no row version to distinguish the new row
176
+ // from the old. If re-publishing a removed id ever becomes routine, give the row a
177
+ // generation column and clear suppression on a change rather than on absence.
178
+ for (const strandId of [...this.suppressed]) {
179
+ if (!currentMap.has(strandId)) {
180
+ this.suppressed.delete(strandId);
181
+ }
182
+ }
172
183
  }
173
184
  catch (error) {
174
185
  // NOTE: a machine cut off from its party before it ever received the `Strand` block
@@ -222,8 +233,58 @@ export class StrandWatcher {
222
233
  this.knownStrands.clear();
223
234
  this.provisional.clear();
224
235
  this.failureStates.clear();
236
+ this.suppressed.clear();
225
237
  log('StrandWatcher stopped');
226
238
  }
239
+ /**
240
+ * Forget a strand whose launch failed outside this watcher, so a later poll
241
+ * re-offers it — gated by the same backoff a watcher-driven failure gets.
242
+ *
243
+ * A failed launch normally leaves nothing running (StrandInstanceManager drops the
244
+ * record), which is what makes re-offering it correct. One case does leave something
245
+ * running: a row this machine published lands on an instance something else already
246
+ * attached, and honouring the founder request on it (CadreNode.launchStrand →
247
+ * StrandInstanceManager.foundExistingStrand) throws. The instance stays up as a joiner
248
+ * and the retry re-attempts the bootstrap on it, which is what should happen — but do
249
+ * not read the line above as "nothing is running".
250
+ */
251
+ forgetStrand(strandId) {
252
+ this.knownStrands.delete(strandId);
253
+ this.provisional.delete(strandId);
254
+ this.recordFailure(strandId);
255
+ }
256
+ /**
257
+ * Never offer this strand again this session. Two callers, both meaning "the retry
258
+ * ladder cannot help here": a deliberate local stop, and a launch that can never
259
+ * succeed — a strand whose id is unusable as a storage scope key
260
+ * (`CadreNode.handleStrandAdded`), which every later attempt would reject identically.
261
+ * A launch that merely FAILED is not one of them; that goes to {@link forgetStrand}.
262
+ *
263
+ * Cleared when the strand's control row disappears, because a row that reappears is a
264
+ * strand the party re-published and the stop said nothing about it; also cleared by
265
+ * {@link stop}, since sApp configs do not survive it either, and by
266
+ * {@link unsuppressStrand} when the caller claims the strand again.
267
+ */
268
+ suppressStrand(strandId) {
269
+ log('Suppressing strand %s — deliberate local stop, will not be re-offered', strandId);
270
+ this.suppressed.add(strandId);
271
+ }
272
+ /**
273
+ * Revoke a {@link suppressStrand}: a deliberate local claim overrides the deliberate
274
+ * local stop that preceded it.
275
+ *
276
+ * Not cosmetic — the suppression check runs before the `knownStrands` one, so a
277
+ * suppressed id is never re-recorded there, and the removed-strand loop iterates
278
+ * `knownStrands`. A strand re-claimed while still suppressed would therefore run with
279
+ * the watcher blind to it: a party-wide removal would never stop it locally. That is
280
+ * reachable whenever the stop found the id already un-known — after a claim that
281
+ * failed, or for a strand the filter never admitted.
282
+ */
283
+ unsuppressStrand(strandId) {
284
+ if (this.suppressed.delete(strandId)) {
285
+ log('Strand %s re-claimed — suppression lifted', strandId);
286
+ }
287
+ }
227
288
  /**
228
289
  * Get currently known strands
229
290
  */
@@ -1 +1 @@
1
- {"version":3,"file":"strand-watcher.js","sourceRoot":"","sources":["../src/strand-watcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"strand-watcher.js","sourceRoot":"","sources":["../src/strand-watcher.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ConnectionGater, Libp2p, PeerId, PrivateKey } from '@libp2p/interface';
2
- import type { IRawStorage, Libp2pTransports, NoiseCryptoInterface } from '@optimystic/db-p2p';
2
+ import type { IRawStorage, Libp2pConnectionMonitorInit, Libp2pTransports, NoiseCryptoInterface } from '@optimystic/db-p2p';
3
3
  import type { IPeerNetwork, IRepo } from '@optimystic/db-core';
4
4
  import type { PeerJoinBackfillConfig } from './peer-join-backfill.js';
5
5
  import type { StrandRevocationEnforcementConfig } from './strand-revocation-enforcer.js';
@@ -91,13 +91,13 @@ export declare const HIBERNATION_TIMEOUTS: Record<LatencyHint, HibernationTimeou
91
91
  * Factory functions are useful for creating per-scope storage instances.
92
92
  *
93
93
  * **The argument is an opaque scope key.** Use it directly as a file name, directory
94
- * name or database name: every key cadre-core mints stays within `[A-Za-z0-9._-]`, so
95
- * no escaping is needed and none should be assumed. Do not parse it;
96
- * `controlStorageScope` / `isControlStorageScope` (`storage-scope.ts`) are the
97
- * supported way to mint and recognize the control key. The strand arm of that charset
98
- * rule is intended but not yet checked — a strand id replicated in from another node
99
- * in the party reaches this callback verbatim; see
100
- * `tickets/backlog/bug-strand-scope-key-charset-unenforced`.
94
+ * name or database name: every key stays within `[A-Za-z0-9._-]`, so no escaping is
95
+ * needed and none should be assumed. Do not parse it; `controlStorageScope` /
96
+ * `isControlStorageScope` (`storage-scope.ts`) are the supported way to mint and
97
+ * recognize the control key. The control key holds the charset by base64url encoding;
98
+ * a strand's key — its strand id, which may have replicated in from another node in
99
+ * the party — holds it because `StrandInstanceManager.startStrand` runs
100
+ * `assertStrandScopeKey` on every launch and refuses a strand that fails it.
101
101
  *
102
102
  * **Called once per scope per runtime lifetime.** The scopes are the control database
103
103
  * (once per `CadreNode.start()`) and each strand id (once per `startStrand`).
@@ -284,7 +284,8 @@ export interface NetworkConfig {
284
284
  *
285
285
  * It buys a node that BOOTS, not a node that boots fast: `start()` still waits
286
286
  * out that first attempt, which costs the drive's whole timeout
287
- * (`DEFAULT_RELAY_RESERVE_TIMEOUT_MS`, 10 s) against a relay that is unreachable
287
+ * (`DEFAULT_RELAY_RESERVE_TIMEOUT_MS`, four link round trips at
288
+ * {@link linkRoundTripMs} — 8 s at its default) against a relay that is unreachable
288
289
  * rather than merely refusing (`relay-reservation.ts` polls to the deadline, in
289
290
  * case libp2p's own discovery lands a reservation independently).
290
291
  *
@@ -358,6 +359,72 @@ export interface NetworkConfig {
358
359
  * `NodeOptions.noiseCrypto`.
359
360
  */
360
361
  noiseCrypto?: NoiseCryptoInterface;
362
+ /**
363
+ * libp2p's connection monitor — the liveness ping it runs on every connection — for
364
+ * the control node and every strand node, as {@link noiseCrypto} is. When omitted,
365
+ * cadre-core applies {@link DEFAULT_CONNECTION_MONITOR} rather than leaving libp2p's
366
+ * own defaults in place; an explicit value REPLACES that default wholesale, so `{}`
367
+ * is how an app asks for libp2p's stock behaviour back.
368
+ *
369
+ * Typed from `@optimystic/db-p2p`'s re-export of libp2p's `ConnectionMonitorInit`, so
370
+ * an app does not need a direct `libp2p` dependency, and handed to db-p2p's
371
+ * `NodeOptions.connectionMonitor` unchanged.
372
+ *
373
+ * An app that widens the ping deadline itself must raise `pingInterval` above it in
374
+ * the same object, or libp2p aborts the connection on the second overlapping ping —
375
+ * see {@link DEFAULT_CONNECTION_MONITOR} for why.
376
+ */
377
+ connectionMonitor?: Libp2pConnectionMonitorInit;
378
+ /**
379
+ * How long ONE cohort peer gets to answer ONE read-path request, in milliseconds, for the
380
+ * control node and every strand node — as {@link connectionMonitor} is, and for the same
381
+ * reason: the setting describes the LINK, and a phone's control node and its strand nodes
382
+ * ride the same one. Omitted takes {@link COHORT_READ_DEADLINE_MS} (5000 ms), chosen for two
383
+ * parties reaching each other only through a relay; Optimystic's own default is 1000 ms.
384
+ *
385
+ * Raise it for a link slower still, lower it for a deployment that is all LAN and wants a
386
+ * departed peer to stop holding up a read sooner. The cost of a larger value is that a peer
387
+ * which is truly gone holds a read of a block missing locally for that long before the read
388
+ * is declined and retried, and a joining machine's first sync runs several such consults —
389
+ * so a change here should be weighed against
390
+ * {@link CadreNodeConfig.strandFirstSync}'s budget. The measurement behind the default, and
391
+ * what it costs, are on {@link COHORT_READ_DEADLINE_MS}.
392
+ *
393
+ * Handed to db-p2p's `clusterPolicy.cohortQueryTimeoutMs` unchanged and NOT re-validated
394
+ * here. Optimystic refuses a value that is not a finite number above zero, or is above its
395
+ * `MAX_COHORT_QUERY_TIMEOUT_MS` (about 4.97 days — the ceiling exists because a unit mix-up
396
+ * is the one way to exceed it), by throwing where the libp2p node is built: inside
397
+ * `CadreNode.start()` for the control network, and inside `CadreNode.addStrand` for a strand.
398
+ * Fractional values are accepted — this is a duration, not a count of peers.
399
+ */
400
+ cohortQueryTimeoutMs?: number;
401
+ /**
402
+ * The round trip this node assumes between itself and another machine, in milliseconds, for
403
+ * the control node and every strand node — as {@link cohortQueryTimeoutMs} is, and for the
404
+ * same reason: the setting describes the LINK, and a phone's control node and its strand
405
+ * nodes ride the same one. Omitted takes {@link DECLARED_LINK_ROUND_TRIP_MS} (2000 ms).
406
+ *
407
+ * This is NOT a timeout. It is the one stated assumption that cadre's own dial and
408
+ * reservation deadlines are DERIVED from, each by the number of round trips that operation
409
+ * was measured to cost: a peer-join catch-up's dial to one peer, its push response, one relay
410
+ * reservation drive, and the control-cohort dial budgets. Reaching another machine through a
411
+ * relay costs a fixed number of exchanges, so a deadline written as milliseconds has a link
412
+ * speed above which it can never open a connection — which is the defect this declaration
413
+ * exists to make impossible to reintroduce one budget at a time. The counts, the measurement
414
+ * behind them, and the ceiling that no declaration here can lift are in `link-budget.ts`.
415
+ *
416
+ * Raise it for a link slower than the relayed phone-to-phone band sereus assumes; the cost is
417
+ * the ordinary cost of longer deadlines, a peer that is genuinely gone holding each operation
418
+ * that much longer before it is abandoned and retried. Above about 2500 it buys nothing: two
419
+ * libp2p budgets that sereus cannot reach abandon the connection first
420
+ * (`tickets/blocked/how-slow-a-relayed-link-does-sereus-carry`).
421
+ *
422
+ * Refused where the libp2p node is built — inside `CadreNode.start()` for the control
423
+ * network, inside `CadreNode.addStrand` for a strand — if it is not a finite number above
424
+ * zero, because every consumer multiplies it into a deadline where a zero means "give up at
425
+ * once" and a `NaN` means "never".
426
+ */
427
+ linkRoundTripMs?: number;
361
428
  /**
362
429
  * Optional async resolver returning the multiaddrs to embed in invites
363
430
  * (and other owner-address contexts). When unset, `libp2pNode.getMultiaddrs()`
@@ -438,6 +505,63 @@ export interface NetworkConfig {
438
505
  strandAddrRefreshMs?: number;
439
506
  };
440
507
  }
508
+ /**
509
+ * The connection-monitor settings every cadre node runs with when
510
+ * {@link NetworkConfig.connectionMonitor} is unset: a 30 second ping deadline in place
511
+ * of libp2p's 5 second one, and a 35 second gap between pings so a ping is never
512
+ * outstanding when the next one starts.
513
+ *
514
+ * WHY this is a default and not opt-in. libp2p's monitor pings every connection and,
515
+ * with its own `abortConnectionOnPingFailure: true`, aborts the connection on the FIRST
516
+ * timeout. A peer whose event loop is saturated by pure-JS Noise crypto — a slow phone
517
+ * under React Native, see {@link NetworkConfig.noiseCrypto} — misses that deadline while
518
+ * perfectly healthy; the other end aborts, the peer redials, and the new handshake
519
+ * saturates it further. Measured on gotchoices/sereus#13 at a Galaxy S7's crypto cost, a
520
+ * two-party bring-up failed 3 of 3 runs on stock settings, with 30 `aborting connection
521
+ * due to ping failure` entries in the relay's log for one run, and passed 4 of 4 in about
522
+ * 90 seconds once the deadline was widened on every node. The monitor runs on BOTH ends
523
+ * of a connection and either end's abort closes it for both, so a setting the phone alone
524
+ * applies does not cover the peer dropping it. That is what rules out scoping this to
525
+ * React Native.
526
+ *
527
+ * WHY `pingInterval` MOVES WITH THE DEADLINE, and is not left at libp2p's 10 seconds.
528
+ * The monitor opens a ping stream per connection per interval whether or not the previous
529
+ * ping has answered, and `/ipfs/ping/1.0.0` is registered by `@libp2p/ping` with
530
+ * `maxOutboundStreams: 1`. A second concurrent ping stream on one connection therefore
531
+ * fails in `Connection.newStream` with `TooManyOutboundProtocolStreamsError`, which
532
+ * reaches the monitor's own catch and aborts the connection exactly as a timeout does. A
533
+ * widened deadline alone is thus capped by the ping interval: measured against two local
534
+ * libp2p 3.1.3 nodes whose ping handler answered 600ms late, an interval of 300ms with a
535
+ * 900ms deadline aborted the connection, while a 900ms interval with the same deadline
536
+ * kept it (the same pair aborted at a 200ms stall only when the deadline was 300ms). An
537
+ * interval strictly above the deadline is what makes the 30 seconds real.
538
+ *
539
+ * WHAT IT COSTS. A dead peer is reclaimed 30 to 65 seconds after it stops answering — the
540
+ * deadline, plus up to one interval of waiting for the ping that will fail — where
541
+ * libp2p's defaults took about 5 to 15 seconds. `db-p2p` caps a node at 16 connections,
542
+ * so the worst case is those slots held about a minute longer than before; at that scale
543
+ * it is not a starvation risk.
544
+ *
545
+ * WHY THE DEADLINE IS PINNED rather than given room to adapt. `pingTimeout` is an
546
+ * adaptive-timeout init, and equal `minTimeout`/`maxTimeout` clamp it to one value on
547
+ * every libp2p version. Under libp2p 3.1.3, which sereus resolves today, it is already
548
+ * flat at `minTimeout`: `ConnectionMonitor` asks its `AdaptiveTimeout` for a deadline but
549
+ * never calls `cleanUp` to report how long the ping took, so the moving average the
550
+ * deadline derives from stays at zero. libp2p 3.3 does report ping durations back, and a
551
+ * ceiling above `pingInterval` would then let the deadline grow past the interval and put
552
+ * the overlapping-ping abort above straight back. Pinning both ends keeps the interval's
553
+ * margin true on the version bump instead of making it something to remember. It also
554
+ * sidesteps 3.3's other surprise: the monitor keeps one `AdaptiveTimeout` for all of a
555
+ * node's connections, so one slow peer would otherwise lengthen the deadline for every
556
+ * connection on that node.
557
+ */
558
+ export declare const DEFAULT_CONNECTION_MONITOR: Readonly<{
559
+ pingInterval: number;
560
+ pingTimeout: Readonly<{
561
+ minTimeout: 30000;
562
+ maxTimeout: 30000;
563
+ }>;
564
+ }>;
441
565
  /**
442
566
  * Hibernation configuration
443
567
  */
@@ -482,11 +606,21 @@ export interface ControlNetworkConfig {
482
606
  *
483
607
  * The two `*ClusterPolicy` BUILDERS are the same objects with the block-repair
484
608
  * corroboration yardstick declared from the machines enrolled in this party
485
- * ({@link resolveRepairYardstick}); handed no count, each returns its frozen base
486
- * constant unchanged. A network picks the derived number up when its libp2p node is
487
- * built, which for a strand is every wake from hibernation.
609
+ * ({@link resolveRepairYardstick}) and, if the host set one, its own per-peer read
610
+ * deadline in place of {@link COHORT_READ_DEADLINE_MS}. Both arrive in one named
611
+ * declarations object, because both are plain numbers meaning unrelated things;
612
+ * declaring neither returns the frozen base constant unchanged. A network picks the
613
+ * derived numbers up when its libp2p node is built, which for a strand is every wake
614
+ * from hibernation.
615
+ */
616
+ export { MIN_CLUSTER_SIZE, COHORT_READ_DEADLINE_MS, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize, resolveRepairYardstick, controlClusterPolicy, strandClusterPolicy } from '@serfab/quereus-plugin-sereus';
617
+ /**
618
+ * The declared link round trip every cadre-owned dial and reservation deadline is derived from,
619
+ * re-exported beside {@link NetworkConfig.linkRoundTripMs} so a host reading the setting finds
620
+ * the default it replaces. The counts, the measurement and the derivation live in
621
+ * `link-budget.ts`.
488
622
  */
489
- export { MIN_CLUSTER_SIZE, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize, resolveRepairYardstick, controlClusterPolicy, strandClusterPolicy } from '@serfab/quereus-plugin-sereus';
623
+ export { DECLARED_LINK_ROUND_TRIP_MS } from './link-budget.js';
490
624
  /**
491
625
  * Main configuration for a CadreNode
492
626
  */
@@ -607,10 +741,12 @@ export interface CadreNodeConfig {
607
741
  * to a table it has never fetched creates a private copy of it that never merges.
608
742
  * `timeoutMs` bounds how long {@link CadreNode.addStrand} waits before rejecting with
609
743
  * `StrandAwaitingFirstSyncError` (retryable — the launch stays up and keeps probing);
610
- * `pollIntervalMs` is the probe cadence. Omit for the defaults (`DEFAULT_STRAND_FIRST_SYNC_TIMEOUT_MS`, 30 s;
611
- * `DEFAULT_STRAND_FIRST_SYNC_POLL_MS`, 500 ms). There is deliberately no way to disable
612
- * the gate: a machine that already holds the Header is never gated, so nothing that works
613
- * today is blocked by it.
744
+ * `pollIntervalMs` is the probe cadence. Omit for the defaults (`DEFAULT_STRAND_FIRST_SYNC_TIMEOUT_MS`,
745
+ * 120 s — sized for a machine joining through a relay on a slow link; that constant's doc
746
+ * comment carries the measurement behind the number and what the budget costs, and is the
747
+ * only copy of it; `DEFAULT_STRAND_FIRST_SYNC_POLL_MS`, 500 ms). There is
748
+ * deliberately no way to disable the gate: a machine that already holds the Header is never
749
+ * gated, so nothing that works today is blocked by it.
614
750
  */
615
751
  strandFirstSync?: StrandFirstSyncConfig;
616
752
  /** Hibernation configuration */
@@ -1155,6 +1291,30 @@ export interface CadreNodeEvents {
1155
1291
  'strand:revoked': {
1156
1292
  strandId: string;
1157
1293
  };
1294
+ /**
1295
+ * Emitted when this node holds a staged membership invitation for a CLOSED strand
1296
+ * that its own writes cannot redeem — the shape a REMOVED party hits when a manager
1297
+ * hands it a fresh invitation. Redeeming means writing this party's `Strand.Member`
1298
+ * row into the strand, and the machines that would carry that write are the ones the
1299
+ * remaining members refuse, so the attempt is made and fails. Two triggers, reported
1300
+ * at most once per re-arm of the membership loop (a further invitation staged while the
1301
+ * loop is still running does not reset the report):
1302
+ *
1303
+ * - CONFIRMED: the revoked-peer gate already flags this node as removed (the
1304
+ * `strand:revoked` case) and an invitation is staged.
1305
+ * - PROBABLE: `UNFINISHED_PASSES_BEFORE_ESCALATION` consecutive attempts left the
1306
+ * invitation staged. This one is a SUSPICION, not a verdict — the invitation's row
1307
+ * may simply not have replicated here yet on a slow strand — and the accompanying
1308
+ * warning names both causes.
1309
+ *
1310
+ * Nothing is stopped or torn down. A fresh invitation cannot re-admit a removed
1311
+ * party by itself: the remedy is a remaining manager admitting this party's member
1312
+ * key directly (`addMemberByManager`), after which the membership loop, which keeps
1313
+ * retrying, finishes the join on its own.
1314
+ */
1315
+ 'strand:rejoin-blocked': {
1316
+ strandId: string;
1317
+ };
1158
1318
  /**
1159
1319
  * Emitted when the control network advertises a strand this node has no
1160
1320
  * registered `sAppConfig` for — i.e. a strand created by another member, or
@@ -1164,13 +1324,19 @@ export interface CadreNodeEvents {
1164
1324
  * Carries the full {@link StrandRow} so the app can join without re-querying
1165
1325
  * the control DB.
1166
1326
  *
1167
- * **Fired exactly ONCE per strand per session, and it can fire before your
1168
- * listener is attached.** The strand watcher's first poll runs inside
1169
- * `CadreNode.start()` (100 ms after the watcher starts), so every strand
1170
- * already stored for this party is normally offered while the embedding app is
1171
- * still inside its own `start()` await. The watcher then records the strand as
1172
- * seen and no later poll re-offers it, so a listener attached a moment late
1173
- * misses those strands for the life of the process.
1327
+ * **Fired once per strand per session, and it can fire before your listener is
1328
+ * attached.** The strand watcher's first poll runs inside `CadreNode.start()`
1329
+ * (100 ms after the watcher starts), so every strand already stored for this
1330
+ * party is normally offered while the embedding app is still inside its own
1331
+ * `start()` await. The watcher then records the strand as seen and no later poll
1332
+ * re-offers it, so a listener attached a moment late misses those strands for the
1333
+ * life of the process.
1334
+ *
1335
+ * One exception, and it does NOT produce a second event: when an `addStrand` that
1336
+ * claims a discovered strand FAILS, the watcher is told to forget the strand so a
1337
+ * later poll retries it. That claim left the sApp config registered, so the retry
1338
+ * takes the auto-launch branch — what the app sees is `strand:error` per failed
1339
+ * retry and `strand:started` when one succeeds.
1174
1340
  *
1175
1341
  * So an app that auto-joins discovered strands must **subscribe first, then
1176
1342
  * drain `CadreNode.getDiscoveredStrands()`** — the map of strands no local
package/dist/types.js CHANGED
@@ -35,6 +35,65 @@ export const HIBERNATION_TIMEOUTS = {
35
35
  checkInMaxInterval: 3 * 24 * 60 * 60 * 1000 // cap: ~3 days
36
36
  }
37
37
  };
38
+ /**
39
+ * The connection-monitor settings every cadre node runs with when
40
+ * {@link NetworkConfig.connectionMonitor} is unset: a 30 second ping deadline in place
41
+ * of libp2p's 5 second one, and a 35 second gap between pings so a ping is never
42
+ * outstanding when the next one starts.
43
+ *
44
+ * WHY this is a default and not opt-in. libp2p's monitor pings every connection and,
45
+ * with its own `abortConnectionOnPingFailure: true`, aborts the connection on the FIRST
46
+ * timeout. A peer whose event loop is saturated by pure-JS Noise crypto — a slow phone
47
+ * under React Native, see {@link NetworkConfig.noiseCrypto} — misses that deadline while
48
+ * perfectly healthy; the other end aborts, the peer redials, and the new handshake
49
+ * saturates it further. Measured on gotchoices/sereus#13 at a Galaxy S7's crypto cost, a
50
+ * two-party bring-up failed 3 of 3 runs on stock settings, with 30 `aborting connection
51
+ * due to ping failure` entries in the relay's log for one run, and passed 4 of 4 in about
52
+ * 90 seconds once the deadline was widened on every node. The monitor runs on BOTH ends
53
+ * of a connection and either end's abort closes it for both, so a setting the phone alone
54
+ * applies does not cover the peer dropping it. That is what rules out scoping this to
55
+ * React Native.
56
+ *
57
+ * WHY `pingInterval` MOVES WITH THE DEADLINE, and is not left at libp2p's 10 seconds.
58
+ * The monitor opens a ping stream per connection per interval whether or not the previous
59
+ * ping has answered, and `/ipfs/ping/1.0.0` is registered by `@libp2p/ping` with
60
+ * `maxOutboundStreams: 1`. A second concurrent ping stream on one connection therefore
61
+ * fails in `Connection.newStream` with `TooManyOutboundProtocolStreamsError`, which
62
+ * reaches the monitor's own catch and aborts the connection exactly as a timeout does. A
63
+ * widened deadline alone is thus capped by the ping interval: measured against two local
64
+ * libp2p 3.1.3 nodes whose ping handler answered 600ms late, an interval of 300ms with a
65
+ * 900ms deadline aborted the connection, while a 900ms interval with the same deadline
66
+ * kept it (the same pair aborted at a 200ms stall only when the deadline was 300ms). An
67
+ * interval strictly above the deadline is what makes the 30 seconds real.
68
+ *
69
+ * WHAT IT COSTS. A dead peer is reclaimed 30 to 65 seconds after it stops answering — the
70
+ * deadline, plus up to one interval of waiting for the ping that will fail — where
71
+ * libp2p's defaults took about 5 to 15 seconds. `db-p2p` caps a node at 16 connections,
72
+ * so the worst case is those slots held about a minute longer than before; at that scale
73
+ * it is not a starvation risk.
74
+ *
75
+ * WHY THE DEADLINE IS PINNED rather than given room to adapt. `pingTimeout` is an
76
+ * adaptive-timeout init, and equal `minTimeout`/`maxTimeout` clamp it to one value on
77
+ * every libp2p version. Under libp2p 3.1.3, which sereus resolves today, it is already
78
+ * flat at `minTimeout`: `ConnectionMonitor` asks its `AdaptiveTimeout` for a deadline but
79
+ * never calls `cleanUp` to report how long the ping took, so the moving average the
80
+ * deadline derives from stays at zero. libp2p 3.3 does report ping durations back, and a
81
+ * ceiling above `pingInterval` would then let the deadline grow past the interval and put
82
+ * the overlapping-ping abort above straight back. Pinning both ends keeps the interval's
83
+ * margin true on the version bump instead of making it something to remember. It also
84
+ * sidesteps 3.3's other surprise: the monitor keeps one `AdaptiveTimeout` for all of a
85
+ * node's connections, so one slow peer would otherwise lengthen the deadline for every
86
+ * connection on that node.
87
+ */
88
+ export const DEFAULT_CONNECTION_MONITOR = Object.freeze({
89
+ // Strictly greater than the deadline below, so the previous ping is always resolved or
90
+ // aborted before the next one opens a stream. `types.spec.ts` holds the two apart.
91
+ pingInterval: 35000,
92
+ // Frozen at both levels, as `CONTROL_CLUSTER_POLICY` is: one object reaches every
93
+ // libp2p node this process builds, so a mutation anywhere would move the deadline
94
+ // for all of them.
95
+ pingTimeout: Object.freeze({ minTimeout: 30000, maxTimeout: 30000 })
96
+ });
38
97
  /**
39
98
  * Default duration of the resume-and-probe window during a strand check-in.
40
99
  * See {@link HibernationConfig.checkInWindowMs}.
@@ -54,9 +113,19 @@ export const DEFAULT_CHECKIN_WINDOW_MS = 15 * 1000;
54
113
  *
55
114
  * The two `*ClusterPolicy` BUILDERS are the same objects with the block-repair
56
115
  * corroboration yardstick declared from the machines enrolled in this party
57
- * ({@link resolveRepairYardstick}); handed no count, each returns its frozen base
58
- * constant unchanged. A network picks the derived number up when its libp2p node is
59
- * built, which for a strand is every wake from hibernation.
116
+ * ({@link resolveRepairYardstick}) and, if the host set one, its own per-peer read
117
+ * deadline in place of {@link COHORT_READ_DEADLINE_MS}. Both arrive in one named
118
+ * declarations object, because both are plain numbers meaning unrelated things;
119
+ * declaring neither returns the frozen base constant unchanged. A network picks the
120
+ * derived numbers up when its libp2p node is built, which for a strand is every wake
121
+ * from hibernation.
122
+ */
123
+ export { MIN_CLUSTER_SIZE, COHORT_READ_DEADLINE_MS, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize, resolveRepairYardstick, controlClusterPolicy, strandClusterPolicy } from '@serfab/quereus-plugin-sereus';
124
+ /**
125
+ * The declared link round trip every cadre-owned dial and reservation deadline is derived from,
126
+ * re-exported beside {@link NetworkConfig.linkRoundTripMs} so a host reading the setting finds
127
+ * the default it replaces. The counts, the measurement and the derivation live in
128
+ * `link-budget.ts`.
60
129
  */
61
- export { MIN_CLUSTER_SIZE, CONTROL_REPLICATION_BREADTH, CONTROL_CLUSTER_POLICY, DEFAULT_STRAND_CLUSTER_SIZE, STRAND_CLUSTER_POLICY, resolveStrandClusterSize, resolveRepairYardstick, controlClusterPolicy, strandClusterPolicy } from '@serfab/quereus-plugin-sereus';
130
+ export { DECLARED_LINK_ROUND_TRIP_MS } from './link-budget.js';
62
131
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAgFA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA6C;IAC5E,QAAQ,EAAE;QACR,WAAW,EAAE,QAAQ,EAAS,aAAa;QAC3C,gBAAgB,EAAE,QAAQ,EAAI,kBAAkB;QAChD,eAAe,EAAE,QAAQ,EAAK,MAAM;QACpC,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,QAAQ,CAAE,MAAM;KACrC;IACD,WAAW,EAAE;QACX,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,YAAY;QAC1C,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,wBAAwB;QAC1D,eAAe,EAAE,EAAE,GAAG,IAAI,EAAI,mBAAmB;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KACnD;IACD,UAAU,EAAE;QACV,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,WAAW;QACzC,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAG,uBAAuB;QACzD,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,kBAAkB;QACpD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB;KACxD;IACD,OAAO,EAAE;QACP,WAAW,EAAE,EAAE,GAAG,IAAI,EAAQ,aAAa;QAC3C,gBAAgB,EAAE,EAAE,GAAG,IAAI,EAAG,wBAAwB;QACtD,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAG,eAAe;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KAC5D;CACF,CAAC;AAsXF;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,CAAC;AAYnD;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EACL,gBAAgB,EAChB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAgFA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAA6C;IAC5E,QAAQ,EAAE;QACR,WAAW,EAAE,QAAQ,EAAS,aAAa;QAC3C,gBAAgB,EAAE,QAAQ,EAAI,kBAAkB;QAChD,eAAe,EAAE,QAAQ,EAAK,MAAM;QACpC,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,QAAQ,CAAE,MAAM;KACrC;IACD,WAAW,EAAE;QACX,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,YAAY;QAC1C,gBAAgB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,wBAAwB;QAC1D,eAAe,EAAE,EAAE,GAAG,IAAI,EAAI,mBAAmB;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KACnD;IACD,UAAU,EAAE;QACV,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,WAAW;QACzC,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAG,uBAAuB;QACzD,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,EAAI,kBAAkB;QACpD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB;KACxD;IACD,OAAO,EAAE;QACP,WAAW,EAAE,EAAE,GAAG,IAAI,EAAQ,aAAa;QAC3C,gBAAgB,EAAE,EAAE,GAAG,IAAI,EAAG,wBAAwB;QACtD,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,EAAG,eAAe;QACjD,oBAAoB,EAAE,CAAC;QACvB,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe;KAC5D;CACF,CAAC;AAwaF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC,MAAM,CAAC;IACtD,uFAAuF;IACvF,mFAAmF;IACnF,YAAY,EAAE,KAAM;IACpB,kFAAkF;IAClF,kFAAkF;IAClF,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,KAAM,EAAE,UAAU,EAAE,KAAM,EAAE,CAAC;CACjC,CAAC,CAAC;AAmBzC;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,GAAG,IAAI,CAAC;AAYnD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,+BAA+B,CAAC;AAEvC;;;;;GAKG;AACH,OAAO,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serfab/cadre-core",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "type": "module",
5
5
  "description": "Core library for Sereus cadre nodes - manages control networks and strand participation",
6
6
  "main": "dist/index.js",
@@ -73,7 +73,7 @@
73
73
  "@libp2p/tcp": "^11.0.10",
74
74
  "@libp2p/webrtc": "6.0.14",
75
75
  "@libp2p/websockets": "^10.1.3",
76
- "@optimystic/db-p2p-storage-fs": "^1.3.0",
76
+ "@optimystic/db-p2p-storage-fs": "^1.6.0",
77
77
  "@types/debug": "^4.1.12",
78
78
  "@types/node": "^25.0.10",
79
79
  "@vitest/coverage-v8": "^4.0.17",
@@ -88,12 +88,12 @@
88
88
  "@libp2p/interface": "^3.1.0",
89
89
  "@libp2p/peer-id": "^6.0.4",
90
90
  "@multiformats/multiaddr": "^12.5.1",
91
- "@optimystic/db-core": "^1.3.0",
92
- "@optimystic/db-p2p": "^1.3.0",
93
- "@optimystic/quereus-plugin-crypto": "^1.3.0",
94
- "@optimystic/quereus-plugin-optimystic": "^1.3.0",
95
- "@quereus/quereus": "^4.19.4",
96
- "@serfab/quereus-plugin-sereus": "^1.3.0",
91
+ "@optimystic/db-core": "^1.6.0",
92
+ "@optimystic/db-p2p": "^1.6.0",
93
+ "@optimystic/quereus-plugin-crypto": "^1.6.0",
94
+ "@optimystic/quereus-plugin-optimystic": "^1.6.0",
95
+ "@quereus/quereus": "^4.20.0",
96
+ "@serfab/quereus-plugin-sereus": "^1.5.0",
97
97
  "debug": "^4.4.3",
98
98
  "libp2p": "^3.1.3",
99
99
  "uint8arrays": "^5.1.0"