@serfab/cadre-core 0.10.0 → 0.11.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 +255 -255
- package/dist/cadre-node.d.ts +203 -28
- package/dist/cadre-node.js +445 -84
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-cohort.d.ts +26 -0
- package/dist/control-cohort.js +26 -0
- package/dist/control-cohort.js.map +1 -1
- package/dist/control-database.d.ts +82 -117
- package/dist/control-database.js +217 -295
- package/dist/control-database.js.map +1 -1
- package/dist/control-formation-recorder.d.ts +8 -7
- package/dist/control-formation-recorder.js +8 -7
- package/dist/control-formation-recorder.js.map +1 -1
- package/dist/control-schema.d.ts +1 -1
- package/dist/control-schema.js +789 -774
- package/dist/control-schema.js.map +1 -1
- package/dist/control-write-retry.d.ts +15 -5
- package/dist/control-write-retry.js +19 -18
- package/dist/control-write-retry.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/peer-addr-book.d.ts +92 -0
- package/dist/peer-addr-book.js +220 -0
- package/dist/peer-addr-book.js.map +1 -0
- package/dist/seed-bootstrap.d.ts +7 -0
- package/dist/seed-bootstrap.js +15 -13
- package/dist/seed-bootstrap.js.map +1 -1
- package/dist/strand-cohort.d.ts +4 -37
- package/dist/strand-cohort.js +4 -15
- package/dist/strand-cohort.js.map +1 -1
- package/dist/strand-database.d.ts +11 -16
- package/dist/strand-database.js +19 -7
- package/dist/strand-database.js.map +1 -1
- package/dist/strand-formation-manager.d.ts +8 -8
- package/dist/strand-formation-manager.js +15 -18
- package/dist/strand-formation-manager.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +52 -21
- package/dist/strand-instance-manager.js +100 -34
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-membership-writer.d.ts +6 -4
- package/dist/strand-membership-writer.js +38 -36
- package/dist/strand-membership-writer.js.map +1 -1
- package/dist/types.d.ts +39 -31
- package/dist/types.js.map +1 -1
- package/package.json +8 -7
- package/src/arachnode-stub.ts +159 -159
- package/src/bootstrap-peer-store-file.ts +44 -44
- package/src/bootstrap-peer-store.ts +172 -172
- package/src/cadre-node.ts +5158 -4771
- package/src/canonical-json.ts +30 -30
- package/src/control-authorization.ts +114 -114
- package/src/control-cohort.ts +130 -103
- package/src/control-database.ts +2406 -2506
- package/src/control-formation-recorder.ts +305 -304
- package/src/control-schema.ts +801 -786
- package/src/control-stream.ts +205 -205
- package/src/control-write-retry.ts +483 -473
- package/src/delegate-admission.ts +302 -302
- package/src/device-token.ts +94 -94
- package/src/diagnostics/connection-path.ts +277 -277
- package/src/diagnostics/webrtc-turn-tracker.ts +222 -222
- package/src/ed25519-key.ts +134 -134
- package/src/enrollment.ts +199 -199
- package/src/file-durable-slot.ts +61 -61
- package/src/formation-approval.ts +604 -604
- package/src/fs-atomic.ts +107 -107
- package/src/hibernation-manager.ts +437 -437
- package/src/identity-key.ts +109 -109
- package/src/index.ts +1 -0
- package/src/key-store-file.ts +132 -132
- package/src/key-store.ts +99 -99
- package/src/membership-connection-gater.ts +204 -204
- package/src/node-local-snapshot.ts +260 -260
- package/src/peer-addr-book.ts +250 -0
- package/src/peer-authorization.ts +259 -259
- package/src/peer-record.ts +164 -164
- package/src/push-credentials.ts +84 -84
- package/src/push-node.ts +64 -64
- package/src/push-notifier-apns.ts +247 -247
- package/src/push-notifier-fcm.ts +220 -220
- package/src/push-notifier-shared.ts +28 -28
- package/src/push-notifier.ts +52 -52
- package/src/relay-addrs.ts +111 -111
- package/src/relay-reservation.ts +823 -823
- package/src/seed-bootstrap.ts +15 -15
- package/src/seed-trust-policy.ts +140 -140
- package/src/strand-addr-protocol.ts +441 -441
- package/src/strand-backfill.ts +366 -366
- package/src/strand-cohort.ts +38 -77
- package/src/strand-database.ts +202 -204
- package/src/strand-formation-manager.ts +491 -494
- package/src/strand-formation-protocol.ts +692 -692
- package/src/strand-instance-manager.ts +108 -50
- package/src/strand-member-key.ts +39 -39
- package/src/strand-member-registry.ts +182 -182
- package/src/strand-membership-writer.ts +1432 -1430
- package/src/strand-solicitation.ts +472 -472
- package/src/strand-transport-key.ts +58 -58
- package/src/strand-wake-payload.ts +32 -32
- package/src/strand-wake-protocol.ts +314 -314
- package/src/strand-watcher.ts +314 -314
- package/src/trusted-owner-store-file.ts +41 -41
- package/src/trusted-owner-store.ts +171 -171
- package/src/types.ts +1309 -1303
package/dist/cadre-node.d.ts
CHANGED
|
@@ -13,6 +13,18 @@ import { StrandSolicitationService, type StrandSolicitationServiceOptions } from
|
|
|
13
13
|
import { type RelayReservationState, type RelayReservationSupervisorOptions } from './relay-reservation.js';
|
|
14
14
|
import type { WakeAck } from './types.js';
|
|
15
15
|
import { type ConnectionPathSummary } from './diagnostics/connection-path.js';
|
|
16
|
+
/**
|
|
17
|
+
* How often a running strand re-resolves its siblings' strand-network addresses
|
|
18
|
+
* and re-merges them into its own libp2p address book
|
|
19
|
+
* ({@link CadreNode.refreshStrandPeerAddrs}). Overridable per node via
|
|
20
|
+
* `network.controlCohort.strandAddrRefreshMs`.
|
|
21
|
+
*
|
|
22
|
+
* Ten minutes sits comfortably inside the peerStore's one-hour address expiry
|
|
23
|
+
* (`MAX_ADDRESS_AGE`, see `peer-addr-book.ts`) with headroom for several missed
|
|
24
|
+
* passes, and far above the 15 s reconcile cadence the refresh rides on, so the
|
|
25
|
+
* strand-addr RPC fan-out stays cheap.
|
|
26
|
+
*/
|
|
27
|
+
export declare const STRAND_PEER_ADDR_REFRESH_MS: number;
|
|
16
28
|
type EventHandler<T> = (data: T) => void;
|
|
17
29
|
/**
|
|
18
30
|
* CadreNode is the main entry point for a cadre member.
|
|
@@ -68,6 +80,14 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
68
80
|
private pushFanoutService;
|
|
69
81
|
/** Backing field for the {@link running} / {@link isRunning} getters. */
|
|
70
82
|
private _running;
|
|
83
|
+
/**
|
|
84
|
+
* The control database's own raw storage (cache-wrapped), resolved once per
|
|
85
|
+
* `start()` and released in {@link cleanup}. Owning it is what keeps
|
|
86
|
+
* `config.storage.provider('control')` a once-per-runtime call: a `stop()` then
|
|
87
|
+
* `start()` cycle on this object re-resolves against a live cache, and never
|
|
88
|
+
* orphans the previous wrapper's registration in the shared cache pool.
|
|
89
|
+
*/
|
|
90
|
+
private controlStorage;
|
|
71
91
|
/**
|
|
72
92
|
* In-flight {@link serviceWake} operations keyed by strandId. Coalesces
|
|
73
93
|
* concurrent on-demand wakes for the same strand into one runtime build + one
|
|
@@ -176,6 +196,16 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
176
196
|
* strand is no longer running are pruned on each reconcile pass.
|
|
177
197
|
*/
|
|
178
198
|
private readonly delegateAnnounceAt;
|
|
199
|
+
/**
|
|
200
|
+
* When each running strand last had its siblings' strand addresses re-resolved
|
|
201
|
+
* into its own address book, keyed by strandId. Throttles
|
|
202
|
+
* {@link refreshStrandPeerAddrs} to once per {@link STRAND_PEER_ADDR_REFRESH_MS}
|
|
203
|
+
* per strand so the 15 s reconcile tick never becomes per-tick RPC chatter.
|
|
204
|
+
* Entries for strands that are no longer running are pruned on each pass, so a
|
|
205
|
+
* hibernated-then-resumed strand refreshes immediately rather than inheriting a
|
|
206
|
+
* stale stamp.
|
|
207
|
+
*/
|
|
208
|
+
private readonly strandPeerAddrRefreshAt;
|
|
179
209
|
/**
|
|
180
210
|
* Cold-start bootstrap dial targets: the owner-flagged peers of every seed
|
|
181
211
|
* this node has applied, keyed by peer id, valued by the seed's multiaddr
|
|
@@ -473,6 +503,25 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
473
503
|
*/
|
|
474
504
|
trustOwnerKeys(keys: Iterable<string>, source: Exclude<TrustSource, 'genesis'>): Promise<void>;
|
|
475
505
|
private createControlNode;
|
|
506
|
+
/**
|
|
507
|
+
* The control database's cache-wrapped raw storage, resolved from
|
|
508
|
+
* `config.storage.provider` on first use and then held in {@link controlStorage}
|
|
509
|
+
* for the rest of this runtime.
|
|
510
|
+
*
|
|
511
|
+
* Resolving once is the contract `RawStorageProvider` (types.ts) states: a provider is
|
|
512
|
+
* called once per scope per runtime lifetime. Re-entering it per call would mint a
|
|
513
|
+
* second store over one backend — a fresh, cold cache, with the previous wrapper's
|
|
514
|
+
* registration orphaned in the process-wide pool.
|
|
515
|
+
*
|
|
516
|
+
* Lazy rather than eager in `start()` so the pure-unit call path
|
|
517
|
+
* (`cadre-node-control-node-options.spec.ts` calls `buildControlNodeOptions` on a
|
|
518
|
+
* bare `new CadreNode`) still resolves — and, on that path too, only once.
|
|
519
|
+
*
|
|
520
|
+
* Wrapped in the write-through raw-storage cache (quereus-plugin-sereus's
|
|
521
|
+
* `cached-storage.ts`) because a control start's cost is its raw-storage
|
|
522
|
+
* operation count.
|
|
523
|
+
*/
|
|
524
|
+
private resolveControlStorage;
|
|
476
525
|
/**
|
|
477
526
|
* Map this node's config onto the control network's libp2p node options.
|
|
478
527
|
*
|
|
@@ -759,23 +808,67 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
759
808
|
/** Body of {@link reconcileControlCohort}; serialised by its single-flight guard. */
|
|
760
809
|
private runReconcileControlCohort;
|
|
761
810
|
/**
|
|
762
|
-
* Resolve
|
|
763
|
-
*
|
|
811
|
+
* Resolve every sibling's signed address record once and merge what resolves
|
|
812
|
+
* into the control node's libp2p **address book** (peerStore). Returns the
|
|
813
|
+
* resolved addresses per sibling so the dial loop reuses them rather than
|
|
814
|
+
* re-resolving — one `queryPeerRecord` per sibling per pass, not two.
|
|
815
|
+
*
|
|
816
|
+
* Deliberately every sibling, not the {@link selectControlCohortDials} subset,
|
|
817
|
+
* and deliberately including already-connected ones: everything below
|
|
818
|
+
* cadre-core dials by bare peer id (Optimystic's cluster/repo clients, FRET
|
|
819
|
+
* ping/announce), so the address book has to be warm BEFORE a live connection
|
|
820
|
+
* drops, and a sibling the out-degree cap declines to dial is still one those
|
|
821
|
+
* layers may need to reach.
|
|
764
822
|
*
|
|
765
|
-
*
|
|
766
|
-
*
|
|
767
|
-
*
|
|
768
|
-
*
|
|
823
|
+
* Only `resolvePeerAddrs` output is merged — never the cold-start
|
|
824
|
+
* `peerStoreAddrs` fallback, which came out of the address book to begin with
|
|
825
|
+
* and would restamp unverified seed addresses indefinitely. A sibling that
|
|
826
|
+
* resolves to nothing (revoked, stale, untrusted) is not written at all, so its
|
|
827
|
+
* existing entry ages out on its own.
|
|
828
|
+
*
|
|
829
|
+
* NOTE: this resolves EVERY sibling serially before the dial loop below runs,
|
|
830
|
+
* so it costs one record query per sibling per reconcile pass (~15s) and each
|
|
831
|
+
* one delays the pass's first dial. A cadre is a handful of devices, so today
|
|
832
|
+
* that is a few extra local reads; if cadres ever grow large, batch the records
|
|
833
|
+
* into one query, merge only on change, or move the warm pass after the dials.
|
|
834
|
+
*/
|
|
835
|
+
private warmSiblingAddrBook;
|
|
836
|
+
/**
|
|
837
|
+
* {@link resolvePeerAddrs} for one sibling, best-effort: a control-DB read
|
|
838
|
+
* failure yields `[]` (and the cold-start fallback then gets its turn) rather
|
|
839
|
+
* than aborting the whole pass, like every other step here.
|
|
840
|
+
*/
|
|
841
|
+
private resolveSiblingAddrs;
|
|
842
|
+
/**
|
|
843
|
+
* Budget for ONE proactive dial of the reconcile pass — steady-state sibling
|
|
844
|
+
* ({@link dialControlSibling}) and cold-start bootstrap peer
|
|
845
|
+
* ({@link dialBootstrapPeer}) alike, since both feed a whole address list to
|
|
846
|
+
* one `dial()` and both run in a sequential loop that the next entry waits on.
|
|
847
|
+
*
|
|
848
|
+
* See {@link DEFAULT_CONTROL_COHORT_DIAL_TIMEOUT_MS} for why the pass bounds
|
|
849
|
+
* this itself rather than inheriting each address's libp2p attempt timeout.
|
|
850
|
+
*/
|
|
851
|
+
private controlDialTimeoutMs;
|
|
852
|
+
/**
|
|
853
|
+
* Dial one sibling from its already-resolved addresses, best-effort. Returns
|
|
854
|
+
* whether a dial was attempted (false when no address resolves).
|
|
855
|
+
*
|
|
856
|
+
* A per-peer failure (NAT, offline, relay down, connection-gater denial, or
|
|
857
|
+
* the {@link controlDialTimeoutMs} budget expiring) is logged and swallowed so
|
|
858
|
+
* one unreachable sibling never aborts the pass — exactly like
|
|
859
|
+
* {@link SeedBootstrapService.applySeed}'s owner-dial loop. A failed dial is
|
|
860
|
+
* simply retried on the next pass.
|
|
769
861
|
*/
|
|
770
862
|
private dialControlSibling;
|
|
771
863
|
/**
|
|
772
|
-
*
|
|
864
|
+
* A sibling's control-network dial addresses for the reconcile pass.
|
|
773
865
|
*
|
|
774
|
-
* Primary (steady state): the signed, fresh, trust-gated control addresses
|
|
775
|
-
*
|
|
776
|
-
*
|
|
777
|
-
*
|
|
778
|
-
*
|
|
866
|
+
* Primary (steady state): the signed, fresh, trust-gated control addresses
|
|
867
|
+
* `resolved` for it by {@link warmSiblingAddrBook} — passed in rather than
|
|
868
|
+
* re-resolved, so the pass makes one record query per sibling. Fallback (cold
|
|
869
|
+
* start): the libp2p peerStore entries `applySeed` populated, used only while
|
|
870
|
+
* the record is not yet resolvable. Returns `[]` (never throws) when neither
|
|
871
|
+
* yields an address — that sibling is skipped this pass.
|
|
779
872
|
*/
|
|
780
873
|
private resolveControlDialAddrs;
|
|
781
874
|
/**
|
|
@@ -1099,7 +1192,7 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
1099
1192
|
private handleStrandHibernate;
|
|
1100
1193
|
/**
|
|
1101
1194
|
* Wake a strand. If it was hibernating (quiesced — no libp2p node), re-resolve
|
|
1102
|
-
* the cohort discovery seed
|
|
1195
|
+
* the cohort discovery seed exactly as `launchStrand` does and rebuild
|
|
1103
1196
|
* its runtime via the strand manager. If it is still live (e.g. waking an idle
|
|
1104
1197
|
* strand, which retains its resources), just flip the status. Overlapping wake
|
|
1105
1198
|
* triggers are coalesced upstream by `HibernationManager`, so this runs once
|
|
@@ -1107,11 +1200,10 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
1107
1200
|
*/
|
|
1108
1201
|
private handleStrandWake;
|
|
1109
1202
|
/**
|
|
1110
|
-
* Rebuild a quiesced strand's runtime, re-resolving the volatile cohort
|
|
1111
|
-
* first: the discovery seed may have grown
|
|
1112
|
-
* shifted the mode `bootstrap → networked` since the strand last ran. Shared by
|
|
1203
|
+
* Rebuild a quiesced strand's runtime, re-resolving the volatile cohort input
|
|
1204
|
+
* first: the discovery seed may have grown since the strand last ran. Shared by
|
|
1113
1205
|
* the wake (`handleStrandWake`) and check-in (`handleStrandCheckIn`) paths so
|
|
1114
|
-
* both apply the same fresh seed
|
|
1206
|
+
* both apply the same fresh seed resolution. `resumeStrand` is idempotent
|
|
1115
1207
|
* (returns the live instance unchanged) as a backstop against double-resume.
|
|
1116
1208
|
*/
|
|
1117
1209
|
private resumeStrandRuntime;
|
|
@@ -1124,7 +1216,7 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
1124
1216
|
* realized as a resume → bounded window → re-hibernate-if-idle cycle that
|
|
1125
1217
|
* reuses the existing quiesce/resume primitives rather than a bespoke probe:
|
|
1126
1218
|
*
|
|
1127
|
-
* 1. Resume the strand (rebuild node + db, re-resolve cohort seed
|
|
1219
|
+
* 1. Resume the strand (rebuild node + db, re-resolve the cohort seed) so
|
|
1128
1220
|
* its strand network can reach cohort peers — exactly as a wake does.
|
|
1129
1221
|
* 2. Hold it resumed for a bounded window, during which the app may drive
|
|
1130
1222
|
* reads (pull-on-read) and record activity.
|
|
@@ -1356,8 +1448,8 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
1356
1448
|
/**
|
|
1357
1449
|
* Shared strand launch path for both the explicit (`addStrand`) and the
|
|
1358
1450
|
* control-discovered (`handleStrandAdded`) entry points. Resolves the cohort
|
|
1359
|
-
* seed,
|
|
1360
|
-
*
|
|
1451
|
+
* seed, starts the strand, and registers it with the hibernation manager
|
|
1452
|
+
* before emitting `strand:started`.
|
|
1361
1453
|
*
|
|
1362
1454
|
* Idempotent no-op when the strand manager already tracks `strand.Id` — the
|
|
1363
1455
|
* ordinary founding sequence is `addStrand` (starts it locally) followed by
|
|
@@ -1370,18 +1462,19 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
1370
1462
|
*/
|
|
1371
1463
|
private launchStrand;
|
|
1372
1464
|
/**
|
|
1373
|
-
* Resolve a strand's discovery seed
|
|
1374
|
-
*
|
|
1375
|
-
*
|
|
1376
|
-
*
|
|
1377
|
-
* addresses that must not
|
|
1465
|
+
* Resolve a strand's discovery seed — the dialable strand-network multiaddr
|
|
1466
|
+
* strings for cohort siblings. Membership comes from the control network's
|
|
1467
|
+
* CadrePeer rows; the **strand-network** bootstrap addresses are resolved on
|
|
1468
|
+
* demand over the control mesh via the strand-addr RPC — deliberately NOT
|
|
1469
|
+
* from `CadrePeer.Multiaddr`, which carries *control* addresses that must not
|
|
1470
|
+
* seed the strand mesh.
|
|
1378
1471
|
*
|
|
1379
1472
|
* Only siblings we already hold an open control connection to are RPC'd: they
|
|
1380
1473
|
* are the ones that can answer right now, and dialing them by peerId reuses the
|
|
1381
1474
|
* live connection. When no connected sibling yet runs the strand the seed is
|
|
1382
|
-
* empty (`[]`) —
|
|
1383
|
-
*
|
|
1384
|
-
*
|
|
1475
|
+
* empty (`[]`) — the empty seed self-heals on the next resume / check-in pass.
|
|
1476
|
+
* Returns an empty seed when the control DB or node is absent (not yet
|
|
1477
|
+
* started / torn down).
|
|
1385
1478
|
*
|
|
1386
1479
|
* When `delegatePeerId` is given (a strand launch/resume is imminent), the
|
|
1387
1480
|
* pass doubles as the delegate ANNOUNCEMENT: our circuit relays are merged
|
|
@@ -1395,6 +1488,37 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
1395
1488
|
* for a relay we are not yet connected to.
|
|
1396
1489
|
*/
|
|
1397
1490
|
private resolveCohortSeed;
|
|
1491
|
+
/**
|
|
1492
|
+
* The co-cadre siblings worth sending a strand-addr RPC to right now: cohort
|
|
1493
|
+
* members (self excluded) we already hold an open control connection to. They
|
|
1494
|
+
* are the ones that can answer immediately, and dialing them by peerId reuses
|
|
1495
|
+
* the live connection instead of opening a second one.
|
|
1496
|
+
*
|
|
1497
|
+
* Shared by {@link resolveCohortSeed} (launch/resume) and
|
|
1498
|
+
* {@link refreshStrandPeerAddrs} (the periodic pass) so both ask the same set.
|
|
1499
|
+
* Empty when the control DB or node is absent (not yet started / torn down).
|
|
1500
|
+
*
|
|
1501
|
+
* The read below is issued even when the node holds no control connection and
|
|
1502
|
+
* the answer is therefore empty by construction. That is deliberate on the
|
|
1503
|
+
* launch path: `control-database-solo-warm-start.spec.ts` exists to prove this
|
|
1504
|
+
* exact read does not stall as an embedder's FIRST awaited control operation,
|
|
1505
|
+
* on a warm cohort no one can reach. A caller that re-enters often enough for
|
|
1506
|
+
* the read to matter should skip the call itself, as
|
|
1507
|
+
* {@link refreshStrandPeerAddrs} does.
|
|
1508
|
+
*
|
|
1509
|
+
* NOTE: this read is UNBOUNDED and sits on the critical path an embedding app
|
|
1510
|
+
* awaits during startup — `addStrand` cannot resolve until it does, and it is
|
|
1511
|
+
* the first control operation an embedder's boot order issues (before genesis,
|
|
1512
|
+
* before seed bootstrap). Measured fine today: the warm-start-alone shape a
|
|
1513
|
+
* report pointed at — a `CadrePeer` list naming peers that are all gone, read
|
|
1514
|
+
* off real files after a restart — completes in milliseconds, and
|
|
1515
|
+
* `control-database-solo-warm-start.spec.ts` covers it under a deadline. If a
|
|
1516
|
+
* control read ever CAN stall (a transactor change that consults the network
|
|
1517
|
+
* for a local row, a storage backend with blocking I/O), give this one a
|
|
1518
|
+
* timeout — and decide then whether the breach fails `addStrand` or degrades
|
|
1519
|
+
* to an empty seed, because those promise callers different things.
|
|
1520
|
+
*/
|
|
1521
|
+
private connectedSiblingTargets;
|
|
1398
1522
|
/**
|
|
1399
1523
|
* The circuit relays this node's strand nodes would reserve through: the
|
|
1400
1524
|
* union of the RESOLVED listen addrs' circuits — a hand-written
|
|
@@ -1437,6 +1561,57 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
1437
1561
|
private refreshDelegateGrants;
|
|
1438
1562
|
/** One strand's share of {@link refreshDelegateGrants}: announce to the relays whose grant is due. */
|
|
1439
1563
|
private announceDelegateToDueRelays;
|
|
1564
|
+
/**
|
|
1565
|
+
* Re-resolve each running strand's SIBLING addresses over the control mesh and
|
|
1566
|
+
* merge them into that strand's own libp2p address book, throttled to once per
|
|
1567
|
+
* {@link STRAND_PEER_ADDR_REFRESH_MS} per strand.
|
|
1568
|
+
*
|
|
1569
|
+
* Without this, a strand's address book is written exactly once — the
|
|
1570
|
+
* launch/resume seed — and everything below cadre-core that dials a strand peer
|
|
1571
|
+
* by bare peer id (Optimystic's cluster and repo clients, FRET ping/announce)
|
|
1572
|
+
* loses its address for any sibling it is not currently connected to: a sibling
|
|
1573
|
+
* that restarted its strand node or rotated its relay reservation is never
|
|
1574
|
+
* re-resolved, and even the original seed addresses fall off at the peerStore's
|
|
1575
|
+
* one-hour expiry (see `peer-addr-book.ts`).
|
|
1576
|
+
*
|
|
1577
|
+
* Distinct from {@link refreshDelegateGrants}, deliberately: that pass covers
|
|
1578
|
+
* RELAYS on a `DELEGATE_GRANT_TTL_MS / 2` throttle to keep circuit-relay
|
|
1579
|
+
* admission grants alive, this one covers SIBLINGS on an address-expiry
|
|
1580
|
+
* throttle to keep the address book warm. They overlap only in that both carry
|
|
1581
|
+
* `delegatePeerId`, so a sibling that also runs a relay gets its grant
|
|
1582
|
+
* refreshed here as a side effect. Merging them would tie an admission-grant
|
|
1583
|
+
* TTL to an address-expiry window that has nothing to do with it.
|
|
1584
|
+
*
|
|
1585
|
+
* Strands refresh CONCURRENTLY, like `refreshDelegateGrants`, so one
|
|
1586
|
+
* unreachable sibling's dial timeout does not stack up per strand.
|
|
1587
|
+
*/
|
|
1588
|
+
private refreshStrandPeerAddrs;
|
|
1589
|
+
/**
|
|
1590
|
+
* One strand's share of {@link refreshStrandPeerAddrs}: RPC the siblings, then
|
|
1591
|
+
* merge their answers into this strand's address book. Errors are logged and
|
|
1592
|
+
* swallowed so one strand's failure never costs the others their refresh.
|
|
1593
|
+
*/
|
|
1594
|
+
private refreshOneStrandPeerAddrs;
|
|
1595
|
+
/**
|
|
1596
|
+
* Merge strand-network addresses into ONE strand node's libp2p address book,
|
|
1597
|
+
* attributed per peer. Best-effort throughout: an address-book write must never
|
|
1598
|
+
* fail a launch, a resume, or a reconcile pass.
|
|
1599
|
+
*
|
|
1600
|
+
* `addrs` is the peer-agnostic union the strand-addr RPC returns, so
|
|
1601
|
+
* {@link groupAddrsByPeerId} attributes each entry to the **strand transport**
|
|
1602
|
+
* peerId in its final `/p2p/` component — never the sibling's control peerId,
|
|
1603
|
+
* which names a different libp2p node entirely. Entries that name no peer are
|
|
1604
|
+
* dropped there and counted here, once per pass.
|
|
1605
|
+
*
|
|
1606
|
+
* NOTE: a member could answer with arbitrary multiaddrs bound to arbitrary peer
|
|
1607
|
+
* ids and poison this address book. That is the same exposure the launch-time
|
|
1608
|
+
* `bootstrapNodes` seeding already accepts, and the cost is bounded: an address
|
|
1609
|
+
* grants no authority, the dialed peer authenticates by peer id at the
|
|
1610
|
+
* handshake, and a bad entry costs one failed dial that ages out at the
|
|
1611
|
+
* peerStore's one-hour expiry. No new gating here — cross-party strand trust is
|
|
1612
|
+
* `backlog/strand-network-nat-relay-reachability`.
|
|
1613
|
+
*/
|
|
1614
|
+
private mergeStrandPeerAddrs;
|
|
1440
1615
|
/**
|
|
1441
1616
|
* The local strand instance's dialable strand-network multiaddrs for the
|
|
1442
1617
|
* strand-addr RPC, ordered signaling-first (reusing the control node's
|