@serfab/cadre-core 1.4.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.
- package/dist/cadre-node.d.ts +38 -15
- package/dist/cadre-node.js +77 -29
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-database.d.ts +24 -10
- package/dist/control-database.js +48 -16
- package/dist/control-database.js.map +1 -1
- package/dist/control-read-retry.d.ts +12 -0
- package/dist/control-read-retry.js +12 -0
- package/dist/control-read-retry.js.map +1 -1
- package/dist/control-write-retry.d.ts +5 -4
- package/dist/control-write-retry.js +24 -7
- package/dist/control-write-retry.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/link-budget.d.ts +182 -0
- package/dist/link-budget.js +195 -0
- package/dist/link-budget.js.map +1 -0
- package/dist/peer-dial.d.ts +36 -17
- package/dist/peer-dial.js +37 -17
- package/dist/peer-dial.js.map +1 -1
- package/dist/peer-join-backfill.d.ts +58 -4
- package/dist/peer-join-backfill.js +165 -20
- package/dist/peer-join-backfill.js.map +1 -1
- package/dist/relay-reservation.d.ts +59 -11
- package/dist/relay-reservation.js +169 -43
- package/dist/relay-reservation.js.map +1 -1
- package/dist/seed-bootstrap.js +2 -1
- package/dist/seed-bootstrap.js.map +1 -1
- package/dist/strand-first-sync-gate.d.ts +43 -5
- package/dist/strand-first-sync-gate.js +55 -7
- package/dist/strand-first-sync-gate.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +27 -2
- package/dist/strand-instance-manager.js +56 -13
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-membership-reconciler.d.ts +200 -45
- package/dist/strand-membership-reconciler.js +302 -86
- package/dist/strand-membership-reconciler.js.map +1 -1
- package/dist/strand-membership-writer.d.ts +3 -2
- package/dist/strand-membership-writer.js +67 -90
- package/dist/strand-membership-writer.js.map +1 -1
- package/dist/strand-network-config.d.ts +2 -2
- package/dist/strand-network-config.js +2 -2
- package/dist/types.d.ts +96 -9
- package/dist/types.js +14 -4
- package/dist/types.js.map +1 -1
- package/package.json +8 -8
- package/src/cadre-node.ts +7445 -7397
- package/src/control-database.ts +48 -16
- package/src/control-read-retry.ts +214 -202
- package/src/control-write-retry.ts +24 -7
- package/src/index.ts +581 -563
- package/src/link-budget.ts +217 -0
- package/src/peer-dial.ts +39 -17
- package/src/peer-join-backfill.ts +192 -23
- package/src/relay-reservation.ts +1119 -951
- package/src/seed-bootstrap.ts +2 -1
- package/src/strand-first-sync-gate.ts +55 -7
- package/src/strand-instance-manager.ts +1516 -1458
- package/src/strand-membership-reconciler.ts +334 -92
- package/src/strand-membership-writer.ts +1962 -1987
- package/src/strand-network-config.ts +2 -2
- package/src/types.ts +95 -8
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
* absorbed by the per-relay entries when one is.
|
|
41
41
|
*
|
|
42
42
|
* Everything else in `NetworkConfig` — `transports`, `noiseCrypto`, `connectionMonitor`,
|
|
43
|
-
* `connectionGater`, `enableRelay` — is inherited by the caller; this
|
|
44
|
-
* the two host-endpoint fields above and the relay listen shape. One caveat on
|
|
43
|
+
* `cohortQueryTimeoutMs`, `connectionGater`, `enableRelay` — is inherited by the caller; this
|
|
44
|
+
* module only owns the two host-endpoint fields above and the relay listen shape. One caveat on
|
|
45
45
|
* `connectionGater`: an OPEN strand's node gets it unchanged, while a CLOSED strand's
|
|
46
46
|
* node composes revoked-peer denial onto it in `strand-instance-manager.ts` (every
|
|
47
47
|
* supplied hook still honored — see `strand-revocation-enforcer.ts`).
|
package/src/types.ts
CHANGED
|
@@ -316,7 +316,8 @@ export interface NetworkConfig {
|
|
|
316
316
|
*
|
|
317
317
|
* It buys a node that BOOTS, not a node that boots fast: `start()` still waits
|
|
318
318
|
* out that first attempt, which costs the drive's whole timeout
|
|
319
|
-
* (`DEFAULT_RELAY_RESERVE_TIMEOUT_MS`,
|
|
319
|
+
* (`DEFAULT_RELAY_RESERVE_TIMEOUT_MS`, four link round trips at
|
|
320
|
+
* {@link linkRoundTripMs} — 8 s at its default) against a relay that is unreachable
|
|
320
321
|
* rather than merely refusing (`relay-reservation.ts` polls to the deadline, in
|
|
321
322
|
* case libp2p's own discovery lands a reservation independently).
|
|
322
323
|
*
|
|
@@ -406,6 +407,56 @@ export interface NetworkConfig {
|
|
|
406
407
|
* see {@link DEFAULT_CONNECTION_MONITOR} for why.
|
|
407
408
|
*/
|
|
408
409
|
connectionMonitor?: Libp2pConnectionMonitorInit;
|
|
410
|
+
/**
|
|
411
|
+
* How long ONE cohort peer gets to answer ONE read-path request, in milliseconds, for the
|
|
412
|
+
* control node and every strand node — as {@link connectionMonitor} is, and for the same
|
|
413
|
+
* reason: the setting describes the LINK, and a phone's control node and its strand nodes
|
|
414
|
+
* ride the same one. Omitted takes {@link COHORT_READ_DEADLINE_MS} (5000 ms), chosen for two
|
|
415
|
+
* parties reaching each other only through a relay; Optimystic's own default is 1000 ms.
|
|
416
|
+
*
|
|
417
|
+
* Raise it for a link slower still, lower it for a deployment that is all LAN and wants a
|
|
418
|
+
* departed peer to stop holding up a read sooner. The cost of a larger value is that a peer
|
|
419
|
+
* which is truly gone holds a read of a block missing locally for that long before the read
|
|
420
|
+
* is declined and retried, and a joining machine's first sync runs several such consults —
|
|
421
|
+
* so a change here should be weighed against
|
|
422
|
+
* {@link CadreNodeConfig.strandFirstSync}'s budget. The measurement behind the default, and
|
|
423
|
+
* what it costs, are on {@link COHORT_READ_DEADLINE_MS}.
|
|
424
|
+
*
|
|
425
|
+
* Handed to db-p2p's `clusterPolicy.cohortQueryTimeoutMs` unchanged and NOT re-validated
|
|
426
|
+
* here. Optimystic refuses a value that is not a finite number above zero, or is above its
|
|
427
|
+
* `MAX_COHORT_QUERY_TIMEOUT_MS` (about 4.97 days — the ceiling exists because a unit mix-up
|
|
428
|
+
* is the one way to exceed it), by throwing where the libp2p node is built: inside
|
|
429
|
+
* `CadreNode.start()` for the control network, and inside `CadreNode.addStrand` for a strand.
|
|
430
|
+
* Fractional values are accepted — this is a duration, not a count of peers.
|
|
431
|
+
*/
|
|
432
|
+
cohortQueryTimeoutMs?: number;
|
|
433
|
+
/**
|
|
434
|
+
* The round trip this node assumes between itself and another machine, in milliseconds, for
|
|
435
|
+
* the control node and every strand node — as {@link cohortQueryTimeoutMs} is, and for the
|
|
436
|
+
* same reason: the setting describes the LINK, and a phone's control node and its strand
|
|
437
|
+
* nodes ride the same one. Omitted takes {@link DECLARED_LINK_ROUND_TRIP_MS} (2000 ms).
|
|
438
|
+
*
|
|
439
|
+
* This is NOT a timeout. It is the one stated assumption that cadre's own dial and
|
|
440
|
+
* reservation deadlines are DERIVED from, each by the number of round trips that operation
|
|
441
|
+
* was measured to cost: a peer-join catch-up's dial to one peer, its push response, one relay
|
|
442
|
+
* reservation drive, and the control-cohort dial budgets. Reaching another machine through a
|
|
443
|
+
* relay costs a fixed number of exchanges, so a deadline written as milliseconds has a link
|
|
444
|
+
* speed above which it can never open a connection — which is the defect this declaration
|
|
445
|
+
* exists to make impossible to reintroduce one budget at a time. The counts, the measurement
|
|
446
|
+
* behind them, and the ceiling that no declaration here can lift are in `link-budget.ts`.
|
|
447
|
+
*
|
|
448
|
+
* Raise it for a link slower than the relayed phone-to-phone band sereus assumes; the cost is
|
|
449
|
+
* the ordinary cost of longer deadlines, a peer that is genuinely gone holding each operation
|
|
450
|
+
* that much longer before it is abandoned and retried. Above about 2500 it buys nothing: two
|
|
451
|
+
* libp2p budgets that sereus cannot reach abandon the connection first
|
|
452
|
+
* (`tickets/blocked/how-slow-a-relayed-link-does-sereus-carry`).
|
|
453
|
+
*
|
|
454
|
+
* Refused where the libp2p node is built — inside `CadreNode.start()` for the control
|
|
455
|
+
* network, inside `CadreNode.addStrand` for a strand — if it is not a finite number above
|
|
456
|
+
* zero, because every consumer multiplies it into a deadline where a zero means "give up at
|
|
457
|
+
* once" and a `NaN` means "never".
|
|
458
|
+
*/
|
|
459
|
+
linkRoundTripMs?: number;
|
|
409
460
|
/**
|
|
410
461
|
* Optional async resolver returning the multiaddrs to embed in invites
|
|
411
462
|
* (and other owner-address contexts). When unset, `libp2pNode.getMultiaddrs()`
|
|
@@ -594,12 +645,16 @@ export interface ControlNetworkConfig {
|
|
|
594
645
|
*
|
|
595
646
|
* The two `*ClusterPolicy` BUILDERS are the same objects with the block-repair
|
|
596
647
|
* corroboration yardstick declared from the machines enrolled in this party
|
|
597
|
-
* ({@link resolveRepairYardstick})
|
|
598
|
-
*
|
|
599
|
-
*
|
|
648
|
+
* ({@link resolveRepairYardstick}) and, if the host set one, its own per-peer read
|
|
649
|
+
* deadline in place of {@link COHORT_READ_DEADLINE_MS}. Both arrive in one named
|
|
650
|
+
* declarations object, because both are plain numbers meaning unrelated things;
|
|
651
|
+
* declaring neither returns the frozen base constant unchanged. A network picks the
|
|
652
|
+
* derived numbers up when its libp2p node is built, which for a strand is every wake
|
|
653
|
+
* from hibernation.
|
|
600
654
|
*/
|
|
601
655
|
export {
|
|
602
656
|
MIN_CLUSTER_SIZE,
|
|
657
|
+
COHORT_READ_DEADLINE_MS,
|
|
603
658
|
CONTROL_REPLICATION_BREADTH,
|
|
604
659
|
CONTROL_CLUSTER_POLICY,
|
|
605
660
|
DEFAULT_STRAND_CLUSTER_SIZE,
|
|
@@ -610,6 +665,14 @@ export {
|
|
|
610
665
|
strandClusterPolicy
|
|
611
666
|
} from '@serfab/quereus-plugin-sereus';
|
|
612
667
|
|
|
668
|
+
/**
|
|
669
|
+
* The declared link round trip every cadre-owned dial and reservation deadline is derived from,
|
|
670
|
+
* re-exported beside {@link NetworkConfig.linkRoundTripMs} so a host reading the setting finds
|
|
671
|
+
* the default it replaces. The counts, the measurement and the derivation live in
|
|
672
|
+
* `link-budget.ts`.
|
|
673
|
+
*/
|
|
674
|
+
export { DECLARED_LINK_ROUND_TRIP_MS } from './link-budget.js';
|
|
675
|
+
|
|
613
676
|
/**
|
|
614
677
|
* Main configuration for a CadreNode
|
|
615
678
|
*/
|
|
@@ -743,10 +806,12 @@ export interface CadreNodeConfig {
|
|
|
743
806
|
* to a table it has never fetched creates a private copy of it that never merges.
|
|
744
807
|
* `timeoutMs` bounds how long {@link CadreNode.addStrand} waits before rejecting with
|
|
745
808
|
* `StrandAwaitingFirstSyncError` (retryable — the launch stays up and keeps probing);
|
|
746
|
-
* `pollIntervalMs` is the probe cadence. Omit for the defaults (`DEFAULT_STRAND_FIRST_SYNC_TIMEOUT_MS`,
|
|
747
|
-
*
|
|
748
|
-
* the
|
|
749
|
-
*
|
|
809
|
+
* `pollIntervalMs` is the probe cadence. Omit for the defaults (`DEFAULT_STRAND_FIRST_SYNC_TIMEOUT_MS`,
|
|
810
|
+
* 120 s — sized for a machine joining through a relay on a slow link; that constant's doc
|
|
811
|
+
* comment carries the measurement behind the number and what the budget costs, and is the
|
|
812
|
+
* only copy of it; `DEFAULT_STRAND_FIRST_SYNC_POLL_MS`, 500 ms). There is
|
|
813
|
+
* deliberately no way to disable the gate: a machine that already holds the Header is never
|
|
814
|
+
* gated, so nothing that works today is blocked by it.
|
|
750
815
|
*/
|
|
751
816
|
strandFirstSync?: StrandFirstSyncConfig;
|
|
752
817
|
|
|
@@ -1322,6 +1387,28 @@ export interface CadreNodeEvents {
|
|
|
1322
1387
|
* revoked.
|
|
1323
1388
|
*/
|
|
1324
1389
|
'strand:revoked': { strandId: string };
|
|
1390
|
+
/**
|
|
1391
|
+
* Emitted when this node holds a staged membership invitation for a CLOSED strand
|
|
1392
|
+
* that its own writes cannot redeem — the shape a REMOVED party hits when a manager
|
|
1393
|
+
* hands it a fresh invitation. Redeeming means writing this party's `Strand.Member`
|
|
1394
|
+
* row into the strand, and the machines that would carry that write are the ones the
|
|
1395
|
+
* remaining members refuse, so the attempt is made and fails. Two triggers, reported
|
|
1396
|
+
* at most once per re-arm of the membership loop (a further invitation staged while the
|
|
1397
|
+
* loop is still running does not reset the report):
|
|
1398
|
+
*
|
|
1399
|
+
* - CONFIRMED: the revoked-peer gate already flags this node as removed (the
|
|
1400
|
+
* `strand:revoked` case) and an invitation is staged.
|
|
1401
|
+
* - PROBABLE: `UNFINISHED_PASSES_BEFORE_ESCALATION` consecutive attempts left the
|
|
1402
|
+
* invitation staged. This one is a SUSPICION, not a verdict — the invitation's row
|
|
1403
|
+
* may simply not have replicated here yet on a slow strand — and the accompanying
|
|
1404
|
+
* warning names both causes.
|
|
1405
|
+
*
|
|
1406
|
+
* Nothing is stopped or torn down. A fresh invitation cannot re-admit a removed
|
|
1407
|
+
* party by itself: the remedy is a remaining manager admitting this party's member
|
|
1408
|
+
* key directly (`addMemberByManager`), after which the membership loop, which keeps
|
|
1409
|
+
* retrying, finishes the join on its own.
|
|
1410
|
+
*/
|
|
1411
|
+
'strand:rejoin-blocked': { strandId: string };
|
|
1325
1412
|
/**
|
|
1326
1413
|
* Emitted when the control network advertises a strand this node has no
|
|
1327
1414
|
* registered `sAppConfig` for — i.e. a strand created by another member, or
|