@serfab/cadre-core 0.11.0 → 0.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/README.md +3 -2
- package/dist/announce-addrs.d.ts +49 -0
- package/dist/announce-addrs.js +78 -0
- package/dist/announce-addrs.js.map +1 -0
- package/dist/cadre-node.d.ts +607 -53
- package/dist/cadre-node.js +1268 -157
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-database.d.ts +174 -23
- package/dist/control-database.js +317 -107
- package/dist/control-database.js.map +1 -1
- package/dist/control-read-retry.d.ts +103 -0
- package/dist/control-read-retry.js +145 -0
- package/dist/control-read-retry.js.map +1 -0
- package/dist/control-retry.d.ts +101 -0
- package/dist/control-retry.js +108 -0
- package/dist/control-retry.js.map +1 -0
- package/dist/control-schema.d.ts +1 -1
- package/dist/control-schema.js +50 -6
- package/dist/control-schema.js.map +1 -1
- package/dist/control-write-retry.d.ts +59 -35
- package/dist/control-write-retry.js +21 -92
- package/dist/control-write-retry.js.map +1 -1
- package/dist/delegate-admission.d.ts +17 -15
- package/dist/delegate-admission.js +17 -15
- package/dist/delegate-admission.js.map +1 -1
- package/dist/enrolled-machine-store-file.d.ts +13 -0
- package/dist/enrolled-machine-store-file.js +41 -0
- package/dist/enrolled-machine-store-file.js.map +1 -0
- package/dist/enrolled-machine-store.d.ts +81 -0
- package/dist/enrolled-machine-store.js +225 -0
- package/dist/enrolled-machine-store.js.map +1 -0
- package/dist/file-durable-slot.js +5 -3
- package/dist/file-durable-slot.js.map +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.js +39 -12
- package/dist/index.js.map +1 -1
- package/dist/membership-connection-gater.d.ts +226 -26
- package/dist/membership-connection-gater.js +316 -30
- package/dist/membership-connection-gater.js.map +1 -1
- package/dist/node-local-snapshot.d.ts +6 -0
- package/dist/node-local-snapshot.js +7 -1
- package/dist/node-local-snapshot.js.map +1 -1
- package/dist/{strand-backfill.d.ts → peer-join-backfill.d.ts} +49 -20
- package/dist/{strand-backfill.js → peer-join-backfill.js} +146 -56
- package/dist/peer-join-backfill.js.map +1 -0
- package/dist/peer-record.d.ts +26 -0
- package/dist/peer-record.js +32 -0
- package/dist/peer-record.js.map +1 -1
- package/dist/relay-addrs.d.ts +145 -22
- package/dist/relay-addrs.js +314 -31
- package/dist/relay-addrs.js.map +1 -1
- package/dist/relay-reservation.d.ts +20 -15
- package/dist/relay-reservation.js +18 -14
- package/dist/relay-reservation.js.map +1 -1
- package/dist/strand-addr-protocol.js +16 -0
- package/dist/strand-addr-protocol.js.map +1 -1
- package/dist/strand-database.d.ts +12 -0
- package/dist/strand-database.js +16 -0
- package/dist/strand-database.js.map +1 -1
- package/dist/strand-formation-manager.d.ts +22 -9
- package/dist/strand-formation-manager.js +20 -12
- package/dist/strand-formation-manager.js.map +1 -1
- package/dist/strand-formation-protocol.d.ts +83 -9
- package/dist/strand-formation-protocol.js +86 -10
- package/dist/strand-formation-protocol.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +151 -17
- package/dist/strand-instance-manager.js +237 -32
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-membership-writer.d.ts +118 -14
- package/dist/strand-membership-writer.js +203 -15
- package/dist/strand-membership-writer.js.map +1 -1
- package/dist/strand-network-config.d.ts +84 -0
- package/dist/strand-network-config.js +136 -0
- package/dist/strand-network-config.js.map +1 -0
- package/dist/strand-revocation-enforcer.d.ts +392 -0
- package/dist/strand-revocation-enforcer.js +533 -0
- package/dist/strand-revocation-enforcer.js.map +1 -0
- package/dist/strand-solicitation.d.ts +10 -3
- package/dist/strand-solicitation.js +12 -7
- package/dist/strand-solicitation.js.map +1 -1
- package/dist/strand-wake-protocol.d.ts +47 -2
- package/dist/strand-wake-protocol.js +76 -6
- package/dist/strand-wake-protocol.js.map +1 -1
- package/dist/strand-watcher.js +6 -1
- package/dist/strand-watcher.js.map +1 -1
- package/dist/types.d.ts +282 -43
- package/dist/types.js +7 -1
- package/dist/types.js.map +1 -1
- package/package.json +16 -8
- package/src/announce-addrs.ts +93 -0
- package/src/cadre-node.ts +1366 -171
- package/src/control-database.ts +2628 -2406
- package/src/control-read-retry.ts +167 -0
- package/src/control-retry.ts +190 -0
- package/src/control-schema.ts +50 -6
- package/src/control-write-retry.ts +30 -130
- package/src/delegate-admission.ts +17 -15
- package/src/enrolled-machine-store-file.ts +43 -0
- package/src/enrolled-machine-store.ts +280 -0
- package/src/file-durable-slot.ts +5 -3
- package/src/index.ts +477 -407
- package/src/membership-connection-gater.ts +539 -204
- package/src/node-local-snapshot.ts +13 -1
- package/src/peer-addr-book.ts +251 -250
- package/src/{strand-backfill.ts → peer-join-backfill.ts} +187 -75
- package/src/peer-record.ts +33 -0
- package/src/relay-addrs.ts +436 -111
- package/src/relay-reservation.ts +828 -823
- package/src/strand-addr-protocol.ts +17 -0
- package/src/strand-database.ts +17 -0
- package/src/strand-formation-manager.ts +511 -491
- package/src/strand-formation-protocol.ts +808 -692
- package/src/strand-instance-manager.ts +899 -611
- package/src/strand-membership-writer.ts +232 -15
- package/src/strand-network-config.ts +172 -0
- package/src/strand-revocation-enforcer.ts +653 -0
- package/src/strand-solicitation.ts +484 -472
- package/src/strand-wake-protocol.ts +94 -8
- package/src/strand-watcher.ts +319 -314
- package/src/types.ts +1554 -1309
- package/dist/strand-backfill.js.map +0 -1
package/README.md
CHANGED
|
@@ -168,9 +168,10 @@ The main entry point for cadre participation.
|
|
|
168
168
|
| `stop()` | Gracefully disconnect from all networks |
|
|
169
169
|
| `getStrands()` | Get all active strand instances |
|
|
170
170
|
| `getStrand(id)` | Get a specific strand instance |
|
|
171
|
-
| `
|
|
171
|
+
| `foundStrand(config)` | **Create a strand**: publish its `Strand` row and start it locally as founder, in one call that is safe to re-run after an interruption. Returns the instance plus the row it actually runs under — for a closed strand read the membership key from there, since a resumed founding keeps the stored key |
|
|
172
|
+
| `addStrand(row)` | Attach only — start a local instance for a row that already exists (the join path; also testing/direct API). Does **not** publish |
|
|
172
173
|
| `stopStrand(id)` | Stop a strand on this node only (the shared `Strand` row stays; rediscovered on restart) |
|
|
173
|
-
| `publishStrand(id, type?, memberKey?)` | Owner-signed `Strand` row insert — makes the strand visible cadre-wide |
|
|
174
|
+
| `publishStrand(id, type?, memberKey?)` | Owner-signed `Strand` row insert — makes the strand visible cadre-wide. Idempotent: a live row with the same `(Type, MemberPrivateKey)` is returned unwritten; different content on the same id throws. Prefer `foundStrand` when creating a strand |
|
|
174
175
|
| `unpublishStrand(id)` | Owner-signed party-wide removal — deletes this party's `Strand` row; every node stops the strand. Destroys a closed strand's `MemberPrivateKey` |
|
|
175
176
|
| `getEnrollmentService()` | Access peer enrollment API |
|
|
176
177
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translate `network.announceAddrs` / `network.appendAnnounceAddrs` — the operator-facing
|
|
3
|
+
* "advertise these addresses" settings — into the two `@optimystic/db-p2p` `NodeOptions`
|
|
4
|
+
* fields of the same names, which reach libp2p's `addresses.announce` /
|
|
5
|
+
* `addresses.appendAnnounce`.
|
|
6
|
+
*
|
|
7
|
+
* Two jobs, both of which the control node and every strand node need identically, hence
|
|
8
|
+
* one module rather than the same conditional spread written twice:
|
|
9
|
+
*
|
|
10
|
+
* - **Empty means unset.** libp2p treats `announce: []` as "no override", and forwarding
|
|
11
|
+
* `[]` would still be forwarding a field. An empty config array is dropped so it cannot
|
|
12
|
+
* land as an explicit empty announce set.
|
|
13
|
+
* - **Validate the multiaddrs here, at start.** libp2p does NOT validate announce addrs
|
|
14
|
+
* at construction: `AddressManager` stores them as raw strings and only parses them on
|
|
15
|
+
* the first `getAnnounceAddrs()`. A typo therefore produces a node that starts
|
|
16
|
+
* cleanly, then throws `InvalidMultiaddrError` out of every `getMultiaddrs()` call —
|
|
17
|
+
* including an UNHANDLED one from the debounced peer-store update libp2p runs on
|
|
18
|
+
* `transport:listening`. Verified against libp2p's `address-manager` (its constructor
|
|
19
|
+
* does `announce.map(ma => ma.toString())`; `getAnnounceAddrs()` does `multiaddr(a)`).
|
|
20
|
+
* Parsing each entry up front converts that into a loud failure at node start, which is
|
|
21
|
+
* what {@link relayCircuitAddrs} already does for `network.relayAddrs`.
|
|
22
|
+
*
|
|
23
|
+
* Parsing alone is not enough, though: `''` and `'/'` both parse into a component-less
|
|
24
|
+
* multiaddr, and a set holding only those is non-empty by the rule above — so it would
|
|
25
|
+
* replace every advertised address with nothing at all. An entry naming no address is
|
|
26
|
+
* therefore rejected alongside one that fails to parse.
|
|
27
|
+
*/
|
|
28
|
+
import type { NetworkConfig } from './types.js';
|
|
29
|
+
/**
|
|
30
|
+
* The announce fields to spread into `createLibp2pNode` options. A field is present
|
|
31
|
+
* only when the operator configured a non-empty list for it, so a node that configures
|
|
32
|
+
* neither passes neither.
|
|
33
|
+
*/
|
|
34
|
+
export interface ResolvedAnnounceAddrs {
|
|
35
|
+
announceAddrs?: string[];
|
|
36
|
+
appendAnnounceAddrs?: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolve both announce fields off a `NetworkConfig`. Throws — naming the offending
|
|
40
|
+
* config field and entry — when any entry is not a parsable multiaddr.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveAnnounceAddrs(network: NetworkConfig | undefined): ResolvedAnnounceAddrs;
|
|
43
|
+
/**
|
|
44
|
+
* Whether this node's advertised set will be REPLACED rather than extended — i.e.
|
|
45
|
+
* whether {@link ResolvedAnnounceAddrs.announceAddrs} is in play at all. The single
|
|
46
|
+
* predicate behind `CadreNode.start()`'s operator warning, kept here so the warning
|
|
47
|
+
* and the forwarding agree on what "set" means (non-empty, not merely present).
|
|
48
|
+
*/
|
|
49
|
+
export declare function replacesAdvertisedAddrs(network: NetworkConfig | undefined): boolean;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translate `network.announceAddrs` / `network.appendAnnounceAddrs` — the operator-facing
|
|
3
|
+
* "advertise these addresses" settings — into the two `@optimystic/db-p2p` `NodeOptions`
|
|
4
|
+
* fields of the same names, which reach libp2p's `addresses.announce` /
|
|
5
|
+
* `addresses.appendAnnounce`.
|
|
6
|
+
*
|
|
7
|
+
* Two jobs, both of which the control node and every strand node need identically, hence
|
|
8
|
+
* one module rather than the same conditional spread written twice:
|
|
9
|
+
*
|
|
10
|
+
* - **Empty means unset.** libp2p treats `announce: []` as "no override", and forwarding
|
|
11
|
+
* `[]` would still be forwarding a field. An empty config array is dropped so it cannot
|
|
12
|
+
* land as an explicit empty announce set.
|
|
13
|
+
* - **Validate the multiaddrs here, at start.** libp2p does NOT validate announce addrs
|
|
14
|
+
* at construction: `AddressManager` stores them as raw strings and only parses them on
|
|
15
|
+
* the first `getAnnounceAddrs()`. A typo therefore produces a node that starts
|
|
16
|
+
* cleanly, then throws `InvalidMultiaddrError` out of every `getMultiaddrs()` call —
|
|
17
|
+
* including an UNHANDLED one from the debounced peer-store update libp2p runs on
|
|
18
|
+
* `transport:listening`. Verified against libp2p's `address-manager` (its constructor
|
|
19
|
+
* does `announce.map(ma => ma.toString())`; `getAnnounceAddrs()` does `multiaddr(a)`).
|
|
20
|
+
* Parsing each entry up front converts that into a loud failure at node start, which is
|
|
21
|
+
* what {@link relayCircuitAddrs} already does for `network.relayAddrs`.
|
|
22
|
+
*
|
|
23
|
+
* Parsing alone is not enough, though: `''` and `'/'` both parse into a component-less
|
|
24
|
+
* multiaddr, and a set holding only those is non-empty by the rule above — so it would
|
|
25
|
+
* replace every advertised address with nothing at all. An entry naming no address is
|
|
26
|
+
* therefore rejected alongside one that fails to parse.
|
|
27
|
+
*/
|
|
28
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
|
29
|
+
/**
|
|
30
|
+
* Resolve both announce fields off a `NetworkConfig`. Throws — naming the offending
|
|
31
|
+
* config field and entry — when any entry is not a parsable multiaddr.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveAnnounceAddrs(network) {
|
|
34
|
+
const announceAddrs = configuredAddrs('network.announceAddrs', network?.announceAddrs);
|
|
35
|
+
const appendAnnounceAddrs = configuredAddrs('network.appendAnnounceAddrs', network?.appendAnnounceAddrs);
|
|
36
|
+
return {
|
|
37
|
+
...(announceAddrs && { announceAddrs }),
|
|
38
|
+
...(appendAnnounceAddrs && { appendAnnounceAddrs })
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Whether this node's advertised set will be REPLACED rather than extended — i.e.
|
|
43
|
+
* whether {@link ResolvedAnnounceAddrs.announceAddrs} is in play at all. The single
|
|
44
|
+
* predicate behind `CadreNode.start()`'s operator warning, kept here so the warning
|
|
45
|
+
* and the forwarding agree on what "set" means (non-empty, not merely present).
|
|
46
|
+
*/
|
|
47
|
+
export function replacesAdvertisedAddrs(network) {
|
|
48
|
+
return (network?.announceAddrs?.length ?? 0) > 0;
|
|
49
|
+
}
|
|
50
|
+
/** The entries to forward for one announce field, or `undefined` when it is unset or empty. */
|
|
51
|
+
function configuredAddrs(field, addrs) {
|
|
52
|
+
if (!addrs || addrs.length === 0) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
return addrs.map((addr) => validated(field, addr));
|
|
56
|
+
}
|
|
57
|
+
/** `addr` unchanged, having proved it names a real address — config field named on failure. */
|
|
58
|
+
function validated(field, addr) {
|
|
59
|
+
if (parsed(field, addr).getComponents().length === 0) {
|
|
60
|
+
// `''` and `'/'` PARSE: both yield a component-less multiaddr that stringifies to
|
|
61
|
+
// `/`. Forwarded, they make an announce set that is non-empty but names nothing —
|
|
62
|
+
// which by the replacement rule above costs the node every address it would
|
|
63
|
+
// otherwise advertise, silently. A templated `cadre.yaml` whose address variable went
|
|
64
|
+
// unsubstituted is the realistic way in, so it is rejected rather than forwarded.
|
|
65
|
+
throw new Error(`${field} entry names no address: ${JSON.stringify(addr)}`);
|
|
66
|
+
}
|
|
67
|
+
return addr;
|
|
68
|
+
}
|
|
69
|
+
/** `addr` as a multiaddr, with the config field named on a parse failure. */
|
|
70
|
+
function parsed(field, addr) {
|
|
71
|
+
try {
|
|
72
|
+
return multiaddr(addr);
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
throw new Error(`${field} entry is not a valid multiaddr: ${addr}`, { cause: err });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=announce-addrs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"announce-addrs.js","sourceRoot":"","sources":["../src/announce-addrs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,SAAS,EAAkB,MAAM,yBAAyB,CAAC;AAapE;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAkC;IACrE,MAAM,aAAa,GAAG,eAAe,CAAC,uBAAuB,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IACvF,MAAM,mBAAmB,GAAG,eAAe,CAAC,6BAA6B,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC;IACzG,OAAO;QACL,GAAG,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,CAAC;QACvC,GAAG,CAAC,mBAAmB,IAAI,EAAE,mBAAmB,EAAE,CAAC;KACpD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAkC;IACxE,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;AACnD,CAAC;AAED,+FAA+F;AAC/F,SAAS,eAAe,CAAC,KAAa,EAAE,KAAoC;IAC1E,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;AACrD,CAAC;AAED,+FAA+F;AAC/F,SAAS,SAAS,CAAC,KAAa,EAAE,IAAY;IAC5C,IAAI,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,kFAAkF;QAClF,kFAAkF;QAClF,4EAA4E;QAC5E,sFAAsF;QACtF,kFAAkF;QAClF,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,4BAA4B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6EAA6E;AAC7E,SAAS,MAAM,CAAC,KAAa,EAAE,IAAY;IACzC,IAAI,CAAC;QACH,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,oCAAoC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;IACtF,CAAC;AACH,CAAC"}
|