@serfab/cadre-core 1.10.0 → 1.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/dist/cadre-node.d.ts +0 -27
- package/dist/cadre-node.js +2 -94
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-schema.js +1066 -1066
- package/dist/diagnostics/connection-path.d.ts +1 -18
- package/dist/diagnostics/connection-path.js +1 -20
- package/dist/diagnostics/connection-path.js.map +1 -1
- package/dist/identity-key.d.ts +0 -30
- package/dist/identity-key.js +7 -40
- package/dist/identity-key.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/relay-stun.d.ts +24 -0
- package/dist/relay-stun.js +51 -0
- package/dist/relay-stun.js.map +1 -0
- package/dist/seed-bootstrap.js +4 -4
- package/dist/strand-membership-writer.js +32 -32
- package/package.json +2 -2
- package/src/cadre-node.ts +8654 -8753
- package/src/control-authorization.ts +117 -117
- package/src/control-cohort.ts +128 -128
- package/src/control-formation-recorder.ts +353 -353
- package/src/control-read-retry.ts +216 -216
- package/src/control-schema.ts +1078 -1078
- package/src/control-write-retry.ts +567 -567
- package/src/diagnostics/connection-path.ts +1 -29
- package/src/formation-approval.ts +610 -610
- package/src/hibernation-manager.ts +638 -638
- package/src/identity-key.ts +7 -62
- package/src/index.ts +644 -647
- package/src/invitation-bootstrap.ts +40 -40
- package/src/joined-strand-store.ts +498 -498
- package/src/link-budget.ts +684 -684
- package/src/membership-connection-gater.ts +570 -570
- package/src/node-local-snapshot.ts +298 -298
- package/src/peer-dial.ts +315 -315
- package/src/peer-join-backfill.ts +710 -710
- package/src/pending-join-runner.ts +735 -735
- package/src/relay-reservation.ts +1121 -1121
- package/src/relay-server.ts +98 -98
- package/src/relay-stun.ts +58 -0
- package/src/seed-bootstrap.ts +1448 -1448
- package/src/strand-addr-protocol.ts +547 -547
- package/src/strand-database.ts +287 -287
- package/src/strand-first-sync-gate.ts +391 -391
- package/src/strand-formation-deadlines.ts +227 -227
- package/src/strand-formation-manager.ts +725 -725
- package/src/strand-fret-addrs.ts +145 -145
- package/src/strand-instance-manager.ts +1789 -1789
- package/src/strand-membership-writer.ts +1974 -1974
- package/src/strand-network-state-file.ts +40 -40
- package/src/strand-network-state.ts +243 -243
- package/src/strand-revocation-enforcer.ts +654 -654
- package/src/strand-solicitation.ts +532 -532
- package/src/strand-wake-protocol.ts +401 -401
- package/src/types.ts +2222 -2222
- package/dist/diagnostics/webrtc-turn-tracker.d.ts +0 -50
- package/dist/diagnostics/webrtc-turn-tracker.js +0 -196
- package/dist/diagnostics/webrtc-turn-tracker.js.map +0 -1
- package/src/diagnostics/webrtc-turn-tracker.ts +0 -222
package/dist/cadre-node.d.ts
CHANGED
|
@@ -612,23 +612,6 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
612
612
|
private controlConnectionOpenHandler;
|
|
613
613
|
/** `connection:close` listener re-arming the growth edge (teardown in {@link stopRecordRefresh}). */
|
|
614
614
|
private controlConnectionCloseHandler;
|
|
615
|
-
/**
|
|
616
|
-
* Hooks `globalThis.RTCPeerConnection` to observe whether ICE selected a TURN
|
|
617
|
-
* relay candidate for each WebRTC session. Installed in {@link start}, disposed
|
|
618
|
-
* in {@link cleanup}; inert on Node.js (no `RTCPeerConnection`).
|
|
619
|
-
*/
|
|
620
|
-
private readonly turnTracker;
|
|
621
|
-
/**
|
|
622
|
-
* Peer IDs whose current WebRTC connection was observed to be TURN-relayed.
|
|
623
|
-
* Populated by {@link handleTurnConnectionOpen} (drains the tracker queue on a
|
|
624
|
-
* `/webrtc` `connection:open`), cleared per-peer on `connection:close`. Read by
|
|
625
|
-
* {@link getConnectionPaths} to promote `webrtc` → `webrtc-turn` (relayed).
|
|
626
|
-
*/
|
|
627
|
-
private turnRelayedPeers;
|
|
628
|
-
/** `connection:open` listener feeding TURN detection (teardown in {@link stopRecordRefresh}). */
|
|
629
|
-
private turnConnectionOpenHandler;
|
|
630
|
-
/** `connection:close` listener clearing a peer's TURN flag (teardown in {@link stopRecordRefresh}). */
|
|
631
|
-
private turnConnectionCloseHandler;
|
|
632
615
|
constructor(config: CadreNodeConfig);
|
|
633
616
|
/**
|
|
634
617
|
* SAppIdLookup implementation - get sAppId for a strand: the claiming config's, else
|
|
@@ -1852,16 +1835,6 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
1852
1835
|
* Idempotent.
|
|
1853
1836
|
*/
|
|
1854
1837
|
private wireControlConnectionListeners;
|
|
1855
|
-
/**
|
|
1856
|
-
* On a control connection opening: if it is a WebRTC connection, drain the TURN
|
|
1857
|
-
* tracker for the just-settled ICE verdict and, when it relayed, mark the peer
|
|
1858
|
-
* so {@link getConnectionPaths} classifies it `webrtc-turn` (relayed). The
|
|
1859
|
-
* settlement↔open correlation is timing-based and best-effort; an unknown
|
|
1860
|
-
* verdict degrades to not-relayed. Never throws to the event loop.
|
|
1861
|
-
*/
|
|
1862
|
-
private handleTurnConnectionOpen;
|
|
1863
|
-
/** On a control connection closing, drop any TURN-relayed flag for its peer. */
|
|
1864
|
-
private handleTurnConnectionClose;
|
|
1865
1838
|
/**
|
|
1866
1839
|
* Publish (or refresh) this node's own self-signed `DeviceToken` row so a server
|
|
1867
1840
|
* peer can resolve its FCM/APNs push token from its PeerId alone. Mirrors
|
package/dist/cadre-node.js
CHANGED
|
@@ -51,17 +51,10 @@ import { resolveRelayServer } from './relay-server.js';
|
|
|
51
51
|
import { replacesAdvertisedAddrs, resolveAnnounceAddrs } from './announce-addrs.js';
|
|
52
52
|
import { superviseRelayReservation, resolveRelayReservationState } from './relay-reservation.js';
|
|
53
53
|
import { PushFanoutService } from './push-fanout.js';
|
|
54
|
-
import { summarizeConnectionPaths
|
|
55
|
-
import { TurnRelayTracker } from './diagnostics/webrtc-turn-tracker.js';
|
|
54
|
+
import { summarizeConnectionPaths } from './diagnostics/connection-path.js';
|
|
56
55
|
import { timedStep } from './timed-step.js';
|
|
57
56
|
const log = debug('sereus:cadre:node');
|
|
58
57
|
const timing = debug('sereus:cadre:timing');
|
|
59
|
-
/**
|
|
60
|
-
* Window (ms) within which a queued TURN-relay settlement is correlated to a
|
|
61
|
-
* `connection:open`. Generous relative to the tight async gap between an
|
|
62
|
-
* `RTCPeerConnection` reaching `connected` and libp2p surfacing the connection.
|
|
63
|
-
*/
|
|
64
|
-
const TURN_CONSUME_WINDOW_MS = 1000;
|
|
65
58
|
/**
|
|
66
59
|
* How often a running strand re-asks each connected sibling that last ANSWERED
|
|
67
60
|
* (even with nothing) for its strand-network addresses, and re-merges them into
|
|
@@ -734,24 +727,6 @@ export class CadreNode {
|
|
|
734
727
|
this.controlConnectionOpenHandler = null;
|
|
735
728
|
/** `connection:close` listener re-arming the growth edge (teardown in {@link stopRecordRefresh}). */
|
|
736
729
|
this.controlConnectionCloseHandler = null;
|
|
737
|
-
// ── WebRTC TURN-relay detection (turn-relayed-path-metrics) ─────────────────
|
|
738
|
-
/**
|
|
739
|
-
* Hooks `globalThis.RTCPeerConnection` to observe whether ICE selected a TURN
|
|
740
|
-
* relay candidate for each WebRTC session. Installed in {@link start}, disposed
|
|
741
|
-
* in {@link cleanup}; inert on Node.js (no `RTCPeerConnection`).
|
|
742
|
-
*/
|
|
743
|
-
this.turnTracker = new TurnRelayTracker();
|
|
744
|
-
/**
|
|
745
|
-
* Peer IDs whose current WebRTC connection was observed to be TURN-relayed.
|
|
746
|
-
* Populated by {@link handleTurnConnectionOpen} (drains the tracker queue on a
|
|
747
|
-
* `/webrtc` `connection:open`), cleared per-peer on `connection:close`. Read by
|
|
748
|
-
* {@link getConnectionPaths} to promote `webrtc` → `webrtc-turn` (relayed).
|
|
749
|
-
*/
|
|
750
|
-
this.turnRelayedPeers = new Set();
|
|
751
|
-
/** `connection:open` listener feeding TURN detection (teardown in {@link stopRecordRefresh}). */
|
|
752
|
-
this.turnConnectionOpenHandler = null;
|
|
753
|
-
/** `connection:close` listener clearing a peer's TURN flag (teardown in {@link stopRecordRefresh}). */
|
|
754
|
-
this.turnConnectionCloseHandler = null;
|
|
755
730
|
this.config = config;
|
|
756
731
|
this.hostUnclaimedStrands = config.hostUnclaimedStrands ?? config.profile === 'storage';
|
|
757
732
|
this.strandManager = new StrandInstanceManager();
|
|
@@ -831,18 +806,7 @@ export class CadreNode {
|
|
|
831
806
|
* direct sibling is considered stuck (default 10_000ms)
|
|
832
807
|
*/
|
|
833
808
|
getConnectionPaths(settleWindowMs) {
|
|
834
|
-
|
|
835
|
-
// Annotate each connection with the TURN-relay hint so a WebRTC session whose
|
|
836
|
-
// ICE selected a TURN candidate classifies as relayed/webrtc-turn rather than
|
|
837
|
-
// direct/webrtc (the multiaddr alone cannot reveal it).
|
|
838
|
-
const annotated = conns.map((c) => ({
|
|
839
|
-
remotePeer: c.remotePeer,
|
|
840
|
-
remoteAddr: c.remoteAddr,
|
|
841
|
-
direction: c.direction,
|
|
842
|
-
timeline: c.timeline,
|
|
843
|
-
turnRelayed: this.turnRelayedPeers.has(c.remotePeer.toString()),
|
|
844
|
-
}));
|
|
845
|
-
return summarizeConnectionPaths(annotated, settleWindowMs);
|
|
809
|
+
return summarizeConnectionPaths(this.controlNode?.getConnections(), settleWindowMs);
|
|
846
810
|
}
|
|
847
811
|
/**
|
|
848
812
|
* Get all strand instances
|
|
@@ -902,10 +866,6 @@ export class CadreNode {
|
|
|
902
866
|
// yet), so a node with a zero or NaN declaration would otherwise boot and fail later
|
|
903
867
|
// inside a best-effort path that logs and carries on. `link-budget.ts`.
|
|
904
868
|
resolveLinkRoundTripMs(this.config.network?.linkRoundTripMs);
|
|
905
|
-
// Install the WebRTC TURN-relay tracker BEFORE any libp2p bring-up, so it
|
|
906
|
-
// wraps globalThis.RTCPeerConnection before the control node can create one.
|
|
907
|
-
// Inert on Node.js (no RTCPeerConnection); disposed in cleanup().
|
|
908
|
-
this.turnTracker.install();
|
|
909
869
|
// Resolve the node identity (keyStore | privateKey | ephemeral) BEFORE any
|
|
910
870
|
// libp2p/network bring-up, so a misconfiguration or an access-denied secure
|
|
911
871
|
// store fails closed before a node is created.
|
|
@@ -2535,18 +2495,10 @@ export class CadreNode {
|
|
|
2535
2495
|
if (this.controlConnectionCloseHandler) {
|
|
2536
2496
|
this.controlNode.removeEventListener('connection:close', this.controlConnectionCloseHandler);
|
|
2537
2497
|
}
|
|
2538
|
-
if (this.turnConnectionOpenHandler) {
|
|
2539
|
-
this.controlNode.removeEventListener('connection:open', this.turnConnectionOpenHandler);
|
|
2540
|
-
}
|
|
2541
|
-
if (this.turnConnectionCloseHandler) {
|
|
2542
|
-
this.controlNode.removeEventListener('connection:close', this.turnConnectionCloseHandler);
|
|
2543
|
-
}
|
|
2544
2498
|
}
|
|
2545
2499
|
this.selfPeerUpdateHandler = null;
|
|
2546
2500
|
this.controlConnectionOpenHandler = null;
|
|
2547
2501
|
this.controlConnectionCloseHandler = null;
|
|
2548
|
-
this.turnConnectionOpenHandler = null;
|
|
2549
|
-
this.turnConnectionCloseHandler = null;
|
|
2550
2502
|
// Reset the write-while-alone re-replication state so a stop()→start() cycle
|
|
2551
2503
|
// re-arms the growth edge and re-runs BOTH one-shot passes. Any queued
|
|
2552
2504
|
// local-only writes are moot once the node is torn down: owner inserts are
|
|
@@ -3815,47 +3767,6 @@ export class CadreNode {
|
|
|
3815
3767
|
this.controlConnectionCloseHandler = () => this.handleControlConnectionClose();
|
|
3816
3768
|
this.controlNode.addEventListener('connection:open', this.controlConnectionOpenHandler);
|
|
3817
3769
|
this.controlNode.addEventListener('connection:close', this.controlConnectionCloseHandler);
|
|
3818
|
-
// TURN-relay detection: tag/untag peers whose WebRTC ICE used a TURN candidate.
|
|
3819
|
-
this.turnConnectionOpenHandler = (evt) => this.handleTurnConnectionOpen(evt.detail);
|
|
3820
|
-
this.turnConnectionCloseHandler = (evt) => this.handleTurnConnectionClose(evt.detail);
|
|
3821
|
-
this.controlNode.addEventListener('connection:open', this.turnConnectionOpenHandler);
|
|
3822
|
-
this.controlNode.addEventListener('connection:close', this.turnConnectionCloseHandler);
|
|
3823
|
-
}
|
|
3824
|
-
/**
|
|
3825
|
-
* On a control connection opening: if it is a WebRTC connection, drain the TURN
|
|
3826
|
-
* tracker for the just-settled ICE verdict and, when it relayed, mark the peer
|
|
3827
|
-
* so {@link getConnectionPaths} classifies it `webrtc-turn` (relayed). The
|
|
3828
|
-
* settlement↔open correlation is timing-based and best-effort; an unknown
|
|
3829
|
-
* verdict degrades to not-relayed. Never throws to the event loop.
|
|
3830
|
-
*/
|
|
3831
|
-
handleTurnConnectionOpen(conn) {
|
|
3832
|
-
try {
|
|
3833
|
-
const addr = conn.remoteAddr?.toString() ?? '';
|
|
3834
|
-
// Only a genuine `/webrtc` (ICE) session can be TURN-relayed and promoted to
|
|
3835
|
-
// webrtc-turn. Use the classifier (which checks `/webrtc-direct` first) rather
|
|
3836
|
-
// than a bare substring — `'/webrtc-direct'.includes('/webrtc')` is true, and a
|
|
3837
|
-
// webrtc-direct open must not drain a settlement meant for a real webrtc dial.
|
|
3838
|
-
if (classifyTransport(addr).transport !== 'webrtc') {
|
|
3839
|
-
return;
|
|
3840
|
-
}
|
|
3841
|
-
if (this.turnTracker.consume(TURN_CONSUME_WINDOW_MS) === true) {
|
|
3842
|
-
const peerId = conn.remotePeer.toString();
|
|
3843
|
-
this.turnRelayedPeers.add(peerId);
|
|
3844
|
-
log('TURN-relayed WebRTC connection detected for peer %s', peerId);
|
|
3845
|
-
}
|
|
3846
|
-
}
|
|
3847
|
-
catch (error) {
|
|
3848
|
-
log('handleTurnConnectionOpen failed: %o', error);
|
|
3849
|
-
}
|
|
3850
|
-
}
|
|
3851
|
-
/** On a control connection closing, drop any TURN-relayed flag for its peer. */
|
|
3852
|
-
handleTurnConnectionClose(conn) {
|
|
3853
|
-
try {
|
|
3854
|
-
this.turnRelayedPeers.delete(conn.remotePeer.toString());
|
|
3855
|
-
}
|
|
3856
|
-
catch (error) {
|
|
3857
|
-
log('handleTurnConnectionClose failed: %o', error);
|
|
3858
|
-
}
|
|
3859
3770
|
}
|
|
3860
3771
|
// ============================================================================
|
|
3861
3772
|
// Device-token registry (control-network push-token publish + resolve)
|
|
@@ -4217,9 +4128,6 @@ export class CadreNode {
|
|
|
4217
4128
|
// Stop self-record refresh timers + address-change listener (before the
|
|
4218
4129
|
// control node is torn down, so removeEventListener has a live target).
|
|
4219
4130
|
this.stopRecordRefresh();
|
|
4220
|
-
// Restore the wrapped globalThis.RTCPeerConnection and drop TURN-relay state.
|
|
4221
|
-
this.turnTracker.dispose();
|
|
4222
|
-
this.turnRelayedPeers.clear();
|
|
4223
4131
|
// Stop hibernation manager
|
|
4224
4132
|
this.hibernationManager.stop();
|
|
4225
4133
|
// Stop seed bootstrap service
|