@serfab/cadre-core 1.12.0 → 1.13.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 +7 -0
- package/dist/cadre-node.js +45 -14
- package/dist/cadre-node.js.map +1 -1
- package/dist/membership-connection-gater.d.ts +6 -6
- package/dist/membership-connection-gater.js +6 -6
- package/dist/strand-first-sync-gate.d.ts +5 -4
- package/dist/strand-first-sync-gate.js +5 -4
- package/dist/strand-first-sync-gate.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +33 -1
- package/dist/strand-instance-manager.js +81 -3
- package/dist/strand-instance-manager.js.map +1 -1
- package/package.json +8 -8
- package/src/cadre-node.ts +8686 -8655
- package/src/membership-connection-gater.ts +570 -570
- package/src/strand-first-sync-gate.ts +392 -391
- package/src/strand-instance-manager.ts +1883 -1804
package/dist/cadre-node.d.ts
CHANGED
|
@@ -1154,6 +1154,13 @@ export declare class CadreNode implements SAppIdLookup {
|
|
|
1154
1154
|
* failure and is re-driven by the next membership write and by the timed reconcile.
|
|
1155
1155
|
*/
|
|
1156
1156
|
private refreshAuthorizedControlPeers;
|
|
1157
|
+
/**
|
|
1158
|
+
* Add the configured `controlNetwork.bootstrapNodes` to the control node's address book
|
|
1159
|
+
* and dial each peer once — what `@libp2p/bootstrap` would have done had the node been
|
|
1160
|
+
* built with them. Best-effort: a failed dial is logged, and the connection manager and
|
|
1161
|
+
* FRET reconnect from the address book as they do for any known peer.
|
|
1162
|
+
*/
|
|
1163
|
+
private dialControlBootstrapPeers;
|
|
1157
1164
|
/**
|
|
1158
1165
|
* PeerIds of the configured control bootstrap nodes (relay/bootstrap
|
|
1159
1166
|
* infrastructure — always admitted inbound). Parsed once, lazily; an
|
package/dist/cadre-node.js
CHANGED
|
@@ -895,22 +895,20 @@ export class CadreNode {
|
|
|
895
895
|
// only way to declare it at all — see `enrolled-machine-store.ts`.
|
|
896
896
|
this.initializeEnrolledMachineStore();
|
|
897
897
|
// Arm the connection gate's BRING-UP QUIET PERIOD before the libp2p node
|
|
898
|
-
// exists, so no connection can form ahead of it:
|
|
899
|
-
// its
|
|
900
|
-
//
|
|
898
|
+
// exists, so no connection can form ahead of it: the node is built without
|
|
899
|
+
// its bootstrap peers (dialed after bring-up), but a peer it already knows
|
|
900
|
+
// from a previous run, or one that dials in, could otherwise connect inside
|
|
901
|
+
// createControlNode below.
|
|
901
902
|
// The invariant being protected is "zero control connections during
|
|
902
903
|
// control-database bring-up" — see the field's doc and
|
|
903
904
|
// `membership-connection-gater.ts` → "The bring-up quiet period".
|
|
904
905
|
//
|
|
905
|
-
// NOTE:
|
|
906
|
-
//
|
|
907
|
-
//
|
|
908
|
-
//
|
|
909
|
-
//
|
|
910
|
-
//
|
|
911
|
-
// range bring-up is 9-15 s, far past the fuse. So if this gate is ever removed
|
|
912
|
-
// or bypassed, that arm reopens for exactly the nodes most likely to hit it —
|
|
913
|
-
// phones joining a party, whose membership row has not replicated yet.
|
|
906
|
+
// NOTE: the gate, not the ordering, is what holds the invariant. Bring-up
|
|
907
|
+
// duration is (raw-storage operations) × per-operation latency; the cold-start
|
|
908
|
+
// operation count and the 50-90 ms/op figure a loaded phone sees live in
|
|
909
|
+
// `control-database.ts`'s `loadSchema` note (pinned by
|
|
910
|
+
// `control-start-storage-op-budget.spec.ts`), so bring-up can take 9-15 s —
|
|
911
|
+
// ample time for a remembered or inbound peer to connect without the gate.
|
|
914
912
|
this.controlBringUpInFlight = true;
|
|
915
913
|
// Create the control network libp2p node
|
|
916
914
|
let t0 = performance.now();
|
|
@@ -948,6 +946,10 @@ export class CadreNode {
|
|
|
948
946
|
// bring-up hazard for boot-time strand seeds that are always empty.
|
|
949
947
|
this.controlBringUpInFlight = false;
|
|
950
948
|
log('Control database initialized');
|
|
949
|
+
// Now that the gate is open, make contact with the configured bootstrap peers the
|
|
950
|
+
// node was built without (see buildControlNodeOptions). Not awaited: an unreachable
|
|
951
|
+
// relay must not hold up start().
|
|
952
|
+
void this.dialControlBootstrapPeers();
|
|
951
953
|
// Attach the per-stream gate to the control DB's membership hub, so every
|
|
952
954
|
// committed `CadrePeer` write re-materializes the authorized snapshot on its
|
|
953
955
|
// own. Wired before anything can write. `_running` is still false for the
|
|
@@ -1528,7 +1530,7 @@ export class CadreNode {
|
|
|
1528
1530
|
* only caller in production is `createControlNode`.
|
|
1529
1531
|
*/
|
|
1530
1532
|
buildControlNodeOptions() {
|
|
1531
|
-
const {
|
|
1533
|
+
const { network, profile } = this.config;
|
|
1532
1534
|
const identityKey = this.identityKey;
|
|
1533
1535
|
// `network.relayAddrs` contributes the bare `/p2p-circuit` SEARCH entry, which
|
|
1534
1536
|
// opens no connection — the reservation is driven explicitly at the END of
|
|
@@ -1545,7 +1547,11 @@ export class CadreNode {
|
|
|
1545
1547
|
const controlStorageProvider = this.resolveControlStorage();
|
|
1546
1548
|
const nodeOptions = {
|
|
1547
1549
|
port: 0,
|
|
1548
|
-
|
|
1550
|
+
// Empty on purpose: Optimystic refuses to treat a block as never-created until it has
|
|
1551
|
+
// heard from every `bootstrapNodes` peer, and the bring-up quiet period refuses those
|
|
1552
|
+
// dials, so a non-empty list fails start() with `cohort-unreachable`. The configured
|
|
1553
|
+
// peers are dialed once bring-up ends ({@link dialControlBootstrapPeers}).
|
|
1554
|
+
bootstrapNodes: [],
|
|
1549
1555
|
networkName: this.controlNetworkName(),
|
|
1550
1556
|
storage: controlStorageProvider,
|
|
1551
1557
|
fretProfile: profile === 'storage' ? 'core' : 'edge',
|
|
@@ -2003,6 +2009,31 @@ export class CadreNode {
|
|
|
2003
2009
|
log('refreshAuthorizedControlPeers(%s) failed — keeping previous snapshot: %o', reason, error);
|
|
2004
2010
|
}
|
|
2005
2011
|
}
|
|
2012
|
+
/**
|
|
2013
|
+
* Add the configured `controlNetwork.bootstrapNodes` to the control node's address book
|
|
2014
|
+
* and dial each peer once — what `@libp2p/bootstrap` would have done had the node been
|
|
2015
|
+
* built with them. Best-effort: a failed dial is logged, and the connection manager and
|
|
2016
|
+
* FRET reconnect from the address book as they do for any known peer.
|
|
2017
|
+
*/
|
|
2018
|
+
async dialControlBootstrapPeers() {
|
|
2019
|
+
const node = this.controlNode;
|
|
2020
|
+
if (!node) {
|
|
2021
|
+
return;
|
|
2022
|
+
}
|
|
2023
|
+
const groups = groupAddrsByPeerId(this.config.controlNetwork.bootstrapNodes);
|
|
2024
|
+
await Promise.all([...groups].map(async ([peerId, addrs]) => {
|
|
2025
|
+
if (peerId === node.peerId.toString()) {
|
|
2026
|
+
return;
|
|
2027
|
+
}
|
|
2028
|
+
await mergePeerAddrs(node, peerId, addrs);
|
|
2029
|
+
try {
|
|
2030
|
+
await node.dial(peerIdFromString(peerId));
|
|
2031
|
+
}
|
|
2032
|
+
catch (error) {
|
|
2033
|
+
log('dialControlBootstrapPeers: dial to bootstrap peer %s failed: %o', peerId, error);
|
|
2034
|
+
}
|
|
2035
|
+
}));
|
|
2036
|
+
}
|
|
2006
2037
|
/**
|
|
2007
2038
|
* PeerIds of the configured control bootstrap nodes (relay/bootstrap
|
|
2008
2039
|
* infrastructure — always admitted inbound). Parsed once, lazily; an
|