@serfab/cadre-core 1.16.0 → 1.18.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 +4 -3
- package/dist/bootstrap-peer-store-file.js +1 -1
- package/dist/bootstrap-peer-store.d.ts +1 -1
- package/dist/bootstrap-peer-store.js +4 -4
- package/dist/cadre-invite-protocol.d.ts +81 -142
- package/dist/cadre-invite-protocol.js +168 -458
- package/dist/cadre-invite-protocol.js.map +1 -1
- package/dist/cadre-join-request.d.ts +15 -2
- package/dist/cadre-join-request.js +22 -3
- package/dist/cadre-join-request.js.map +1 -1
- package/dist/cadre-node.d.ts +1089 -475
- package/dist/cadre-node.js +2170 -1037
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-authorization.d.ts +36 -14
- package/dist/control-authorization.js +20 -3
- package/dist/control-authorization.js.map +1 -1
- package/dist/control-cohort.d.ts +88 -32
- package/dist/control-cohort.js +91 -33
- package/dist/control-cohort.js.map +1 -1
- package/dist/control-database.d.ts +856 -318
- package/dist/control-database.js +1422 -701
- package/dist/control-database.js.map +1 -1
- package/dist/control-formation-recorder.d.ts +46 -43
- package/dist/control-formation-recorder.js +77 -78
- package/dist/control-formation-recorder.js.map +1 -1
- package/dist/control-protocol-guard.d.ts +11 -4
- package/dist/control-protocol-guard.js +20 -5
- package/dist/control-protocol-guard.js.map +1 -1
- package/dist/control-schema-version.d.ts +97 -0
- package/dist/control-schema-version.js +225 -0
- package/dist/control-schema-version.js.map +1 -0
- package/dist/control-schema.d.ts +45 -5
- package/dist/control-schema.js +262 -78
- package/dist/control-schema.js.map +1 -1
- package/dist/control-write-retry.d.ts +45 -10
- package/dist/control-write-retry.js +92 -22
- package/dist/control-write-retry.js.map +1 -1
- package/dist/delegate-admission.d.ts +13 -0
- package/dist/delegate-admission.js +27 -0
- package/dist/delegate-admission.js.map +1 -1
- package/dist/ed25519-key.d.ts +10 -7
- package/dist/ed25519-key.js +23 -20
- package/dist/ed25519-key.js.map +1 -1
- package/dist/edge-node/config.d.ts +122 -0
- package/dist/edge-node/config.js +199 -0
- package/dist/edge-node/config.js.map +1 -0
- package/dist/edge-node/dissolve.d.ts +95 -0
- package/dist/edge-node/dissolve.js +184 -0
- package/dist/edge-node/dissolve.js.map +1 -0
- package/dist/edge-node/edge-join.d.ts +44 -0
- package/dist/edge-node/edge-join.js +227 -0
- package/dist/edge-node/edge-join.js.map +1 -0
- package/dist/edge-node/edge-node.d.ts +295 -0
- package/dist/edge-node/edge-node.js +704 -0
- package/dist/edge-node/edge-node.js.map +1 -0
- package/dist/edge-node/index.d.ts +18 -0
- package/dist/edge-node/index.js +18 -0
- package/dist/edge-node/index.js.map +1 -0
- package/dist/edge-node/join-credential.d.ts +11 -0
- package/dist/edge-node/join-credential.js +11 -0
- package/dist/edge-node/join-credential.js.map +1 -0
- package/dist/edge-node/lazy-raw-storage.d.ts +40 -0
- package/dist/edge-node/lazy-raw-storage.js +134 -0
- package/dist/edge-node/lazy-raw-storage.js.map +1 -0
- package/dist/edge-node/node-local.d.ts +60 -0
- package/dist/edge-node/node-local.js +58 -0
- package/dist/edge-node/node-local.js.map +1 -0
- package/dist/edge-node/options.d.ts +83 -0
- package/dist/edge-node/options.js +110 -0
- package/dist/edge-node/options.js.map +1 -0
- package/dist/edge-node/owner-grant.d.ts +41 -0
- package/dist/edge-node/owner-grant.js +38 -0
- package/dist/edge-node/owner-grant.js.map +1 -0
- package/dist/edge-node/platform.d.ts +140 -0
- package/dist/edge-node/platform.js +12 -0
- package/dist/edge-node/platform.js.map +1 -0
- package/dist/edge-node/strand-move.d.ts +115 -0
- package/dist/edge-node/strand-move.js +223 -0
- package/dist/edge-node/strand-move.js.map +1 -0
- package/dist/edge-node/strands.d.ts +28 -0
- package/dist/edge-node/strands.js +60 -0
- package/dist/edge-node/strands.js.map +1 -0
- package/dist/enrolled-machine-store.d.ts +3 -3
- package/dist/enrolled-machine-store.js +3 -3
- package/dist/formation-token.d.ts +48 -0
- package/dist/formation-token.js +26 -0
- package/dist/formation-token.js.map +1 -0
- package/dist/index.d.ts +27 -17
- package/dist/index.js +39 -17
- package/dist/index.js.map +1 -1
- package/dist/joined-strand-store.d.ts +29 -12
- package/dist/joined-strand-store.js +66 -27
- package/dist/joined-strand-store.js.map +1 -1
- package/dist/key-store.d.ts +9 -4
- package/dist/key-store.js +9 -4
- package/dist/key-store.js.map +1 -1
- package/dist/link-budget.d.ts +9 -7
- package/dist/link-budget.js +9 -7
- package/dist/link-budget.js.map +1 -1
- package/dist/machine-removal.d.ts +19 -39
- package/dist/machine-removal.js +24 -98
- package/dist/machine-removal.js.map +1 -1
- package/dist/member-redemption.d.ts +256 -0
- package/dist/member-redemption.js +490 -0
- package/dist/member-redemption.js.map +1 -0
- package/dist/membership-view.d.ts +91 -0
- package/dist/membership-view.js +110 -0
- package/dist/membership-view.js.map +1 -0
- package/dist/owner-anchor-sync.d.ts +4 -4
- package/dist/owner-anchor-sync.js +16 -15
- package/dist/owner-anchor-sync.js.map +1 -1
- package/dist/owner-grant-protocol.d.ts +251 -0
- package/dist/owner-grant-protocol.js +344 -0
- package/dist/owner-grant-protocol.js.map +1 -0
- package/dist/owner-key-export.d.ts +70 -0
- package/dist/owner-key-export.js +279 -0
- package/dist/owner-key-export.js.map +1 -0
- package/dist/owner-key-flows.d.ts +55 -0
- package/dist/owner-key-flows.js +60 -0
- package/dist/owner-key-flows.js.map +1 -0
- package/dist/owner-key-store.d.ts +31 -0
- package/dist/owner-key-store.js +81 -0
- package/dist/owner-key-store.js.map +1 -0
- package/dist/owner-keys.d.ts +78 -0
- package/dist/owner-keys.js +133 -0
- package/dist/owner-keys.js.map +1 -0
- package/dist/owner-signer.d.ts +54 -0
- package/dist/owner-signer.js +51 -0
- package/dist/owner-signer.js.map +1 -0
- package/dist/peer-addr-book.d.ts +10 -1
- package/dist/peer-addr-book.js +4 -3
- package/dist/peer-addr-book.js.map +1 -1
- package/dist/peer-authorization.d.ts +83 -18
- package/dist/peer-authorization.js +123 -53
- package/dist/peer-authorization.js.map +1 -1
- package/dist/peer-join-backfill.d.ts +89 -20
- package/dist/peer-join-backfill.js +265 -108
- package/dist/peer-join-backfill.js.map +1 -1
- package/dist/pending-join-runner.d.ts +48 -18
- package/dist/pending-join-runner.js +74 -56
- package/dist/pending-join-runner.js.map +1 -1
- package/dist/provider/rent-node.js +1 -1
- package/dist/provider/rent-node.js.map +1 -1
- package/dist/seed-bootstrap.d.ts +162 -133
- package/dist/seed-bootstrap.js +300 -283
- package/dist/seed-bootstrap.js.map +1 -1
- package/dist/seed-trust-policy.js +4 -4
- package/dist/strand-addr-protocol.d.ts +4 -1
- package/dist/strand-addr-protocol.js +8 -2
- package/dist/strand-addr-protocol.js.map +1 -1
- package/dist/strand-cohort.d.ts +3 -0
- package/dist/strand-cohort.js.map +1 -1
- package/dist/strand-database.d.ts +24 -2
- package/dist/strand-database.js +29 -6
- package/dist/strand-database.js.map +1 -1
- package/dist/strand-first-sync-gate.d.ts +176 -88
- package/dist/strand-first-sync-gate.js +288 -121
- package/dist/strand-first-sync-gate.js.map +1 -1
- package/dist/strand-formation-deadlines.d.ts +9 -9
- package/dist/strand-formation-deadlines.js +9 -9
- package/dist/strand-formation-manager.d.ts +23 -17
- package/dist/strand-formation-manager.js +46 -44
- package/dist/strand-formation-manager.js.map +1 -1
- package/dist/strand-formation-protocol.d.ts +5 -8
- package/dist/strand-formation-protocol.js +101 -16
- package/dist/strand-formation-protocol.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +27 -18
- package/dist/strand-instance-manager.js +119 -50
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-membership-reconciler.d.ts +16 -13
- package/dist/strand-membership-reconciler.js +30 -22
- package/dist/strand-membership-reconciler.js.map +1 -1
- package/dist/strand-membership-writer.d.ts +45 -22
- package/dist/strand-membership-writer.js +226 -131
- package/dist/strand-membership-writer.js.map +1 -1
- package/dist/strand-move.d.ts +6 -5
- package/dist/strand-move.js +36 -32
- package/dist/strand-move.js.map +1 -1
- package/dist/strand-peer-redial.js +2 -3
- package/dist/strand-peer-redial.js.map +1 -1
- package/dist/strand-revocation-enforcer.d.ts +134 -60
- package/dist/strand-revocation-enforcer.js +144 -71
- package/dist/strand-revocation-enforcer.js.map +1 -1
- package/dist/strand-solicitation.d.ts +50 -39
- package/dist/strand-solicitation.js +10 -3
- package/dist/strand-solicitation.js.map +1 -1
- package/dist/strand-watcher.d.ts +80 -13
- package/dist/strand-watcher.js +152 -48
- package/dist/strand-watcher.js.map +1 -1
- package/dist/table-change-watch.d.ts +63 -0
- package/dist/table-change-watch.js +209 -0
- package/dist/table-change-watch.js.map +1 -0
- package/dist/timeout-scheduler.d.ts +4 -3
- package/dist/timeout-scheduler.js +4 -3
- package/dist/timeout-scheduler.js.map +1 -1
- package/dist/types.d.ts +374 -150
- package/dist/types.js +4 -4
- package/dist/types.js.map +1 -1
- package/package.json +17 -8
- package/src/bootstrap-peer-store-file.ts +44 -44
- package/src/bootstrap-peer-store.ts +214 -214
- package/src/cadre-invite-protocol.ts +740 -1052
- package/src/cadre-join-request.ts +24 -3
- package/src/cadre-node.ts +2402 -1079
- package/src/control-authorization.ts +47 -14
- package/src/control-cohort.ts +204 -128
- package/src/control-database.ts +1749 -820
- package/src/control-formation-recorder.ts +359 -353
- package/src/control-protocol-guard.ts +23 -6
- package/src/control-schema-version.ts +301 -0
- package/src/control-schema.ts +273 -78
- package/src/control-write-retry.ts +641 -567
- package/src/delegate-admission.ts +351 -314
- package/src/ed25519-key.ts +174 -171
- package/src/edge-node/config.ts +277 -0
- package/src/edge-node/dissolve.ts +251 -0
- package/src/edge-node/edge-join.ts +319 -0
- package/src/edge-node/edge-node.ts +1045 -0
- package/src/edge-node/index.ts +59 -0
- package/src/edge-node/join-credential.ts +16 -0
- package/src/edge-node/lazy-raw-storage.ts +178 -0
- package/src/edge-node/node-local.ts +84 -0
- package/src/edge-node/options.ts +179 -0
- package/src/edge-node/owner-grant.ts +63 -0
- package/src/edge-node/platform.ts +151 -0
- package/src/edge-node/strand-move.ts +270 -0
- package/src/edge-node/strands.ts +72 -0
- package/src/enrolled-machine-store.ts +3 -3
- package/src/formation-token.ts +63 -0
- package/src/index.ts +899 -789
- package/src/joined-strand-store.ts +73 -28
- package/src/key-store.ts +10 -4
- package/src/link-budget.ts +9 -7
- package/src/machine-removal.ts +26 -111
- package/src/member-redemption.ts +649 -0
- package/src/membership-view.ts +144 -0
- package/src/owner-anchor-sync.ts +19 -18
- package/src/owner-grant-protocol.ts +547 -0
- package/src/owner-key-export.ts +348 -0
- package/src/owner-key-flows.ts +109 -0
- package/src/owner-key-store.ts +85 -0
- package/src/owner-keys.ts +178 -0
- package/src/owner-signer.ts +94 -0
- package/src/peer-addr-book.ts +4 -3
- package/src/peer-authorization.ts +558 -488
- package/src/peer-join-backfill.ts +971 -761
- package/src/pending-join-runner.ts +76 -53
- package/src/provider/rent-node.ts +1 -1
- package/src/seed-bootstrap.ts +343 -349
- package/src/seed-trust-policy.ts +4 -4
- package/src/strand-addr-protocol.ts +547 -538
- package/src/strand-cohort.ts +4 -0
- package/src/strand-database.ts +352 -319
- package/src/strand-first-sync-gate.ts +334 -133
- package/src/strand-formation-deadlines.ts +227 -227
- package/src/strand-formation-manager.ts +731 -725
- package/src/strand-formation-protocol.ts +122 -24
- package/src/strand-instance-manager.ts +2092 -2026
- package/src/strand-membership-reconciler.ts +33 -25
- package/src/strand-membership-writer.ts +2093 -1974
- package/src/strand-move.ts +50 -38
- package/src/strand-peer-redial.ts +2 -3
- package/src/strand-revocation-enforcer.ts +740 -654
- package/src/strand-solicitation.ts +61 -34
- package/src/strand-watcher.ts +175 -56
- package/src/table-change-watch.ts +285 -0
- package/src/timeout-scheduler.ts +29 -28
- package/src/types.ts +391 -152
package/dist/seed-bootstrap.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { Libp2p } from '@libp2p/interface';
|
|
2
2
|
import { type PeerDialBudget } from './peer-dial.js';
|
|
3
|
-
import type { ControlNetworkSeed, SeedPeer, SeedAckMessage, SeedDeliveryTarget, AuthorizePeerOptions, ApplySeedResult, AddDroneOptions, DroneInitResult, CadreInviteRow, PeerAddressRecord, DeviceTokenRecord, RevocationRow,
|
|
4
|
-
import type {
|
|
3
|
+
import type { ControlNetworkSeed, SeedPeer, SeedDialTarget, SeedAckMessage, SeedDeliveryTarget, AuthorizePeerOptions, ApplySeedResult, AddDroneOptions, DroneInitResult, CadreInviteRow, OwnerGrantRow, PeerAddressRecord, DeviceTokenRecord, RevocationRow, MachineRemovalResult } from './types.js';
|
|
4
|
+
import type { CadrePeerRetouchMode, CadrePeerRetouchOutcome, ControlDatabase } from './control-database.js';
|
|
5
5
|
import { type SeedTrustPolicy } from './seed-trust-policy.js';
|
|
6
6
|
import type { TrustedOwnerStore } from './trusted-owner-store.js';
|
|
7
|
+
import { type OwnerSign, type OwnerSigner } from './owner-signer.js';
|
|
7
8
|
/** Protocol ID for seed delivery */
|
|
8
9
|
export declare const SEED_PROTOCOL = "/sereus/seed/1.0.0";
|
|
9
10
|
/**
|
|
@@ -32,6 +33,15 @@ export declare function canonicalSeedPayload(seed: Pick<ControlNetworkSeed, 'par
|
|
|
32
33
|
* proof to one seed through this value) all name the same bytes.
|
|
33
34
|
*/
|
|
34
35
|
export declare function seedDigest(seed: Pick<ControlNetworkSeed, 'partyId' | 'peers'>): string;
|
|
36
|
+
/**
|
|
37
|
+
* The peers `seed` nominates for dialing: its preferred peers (`SeedPeer.preferred`: the machine
|
|
38
|
+
* that minted it and every always-on machine) that have an address and are not `selfPeerId`.
|
|
39
|
+
*
|
|
40
|
+
* Self is dropped because `createSeed` projects every non-revoked CadrePeer row, so a preferred
|
|
41
|
+
* machine applying a seed minted after it joined finds itself in the list, and a dial of self
|
|
42
|
+
* always throws. An undefined `selfPeerId` matches nothing.
|
|
43
|
+
*/
|
|
44
|
+
export declare function seedDialTargets(seed: ControlNetworkSeed, selfPeerId: string | undefined): SeedDialTarget[];
|
|
35
45
|
/**
|
|
36
46
|
* Merge a peer list's addresses into `node`'s peer store, so the node can dial them: the
|
|
37
47
|
* seed's peers after its signature and trust checks, the dial hints a member returns on
|
|
@@ -47,10 +57,12 @@ export declare function mergeSeedPeers(node: Libp2p, peers: readonly SeedPeer[])
|
|
|
47
57
|
export interface SeedBootstrapConfig {
|
|
48
58
|
/** Party ID for this cadre */
|
|
49
59
|
partyId: string;
|
|
50
|
-
/**
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
60
|
+
/**
|
|
61
|
+
* The owner signer every seed and owner-signed write of this service goes through
|
|
62
|
+
* (`owner-signer.ts`). Unset for a listener-only service, which receives and applies seeds
|
|
63
|
+
* but refuses every owner write.
|
|
64
|
+
*/
|
|
65
|
+
ownerSigner?: OwnerSigner;
|
|
54
66
|
/**
|
|
55
67
|
* Trust anchor for incoming seeds. Decides whether a signature-verified
|
|
56
68
|
* `signerKey` should be trusted, against the receiver's anchored owner
|
|
@@ -107,7 +119,7 @@ export interface SeedBootstrapConfig {
|
|
|
107
119
|
* sized for the forms that dial inside it. Delivery does not set `runOnLimitedConnection`,
|
|
108
120
|
* so it does not use a limited relayed connection today; the relayed-dial count is the upper
|
|
109
121
|
* bound on the dial it can use, the same choice `CadreNode.controlDialBudget` makes for every
|
|
110
|
-
* address. It holds only link work because the receiver acks before
|
|
122
|
+
* address. It holds only link work because the receiver acks before it dials the seed's peers.
|
|
111
123
|
*
|
|
112
124
|
* NOTE: no transfer allowance — a seed is a peer list of a few KB, and `MAX_SEED_SIZE` (1 MiB)
|
|
113
125
|
* is a defensive cap. If seeds ever grow toward that cap, add an allowance the way
|
|
@@ -116,7 +128,7 @@ export interface SeedBootstrapConfig {
|
|
|
116
128
|
seedDeliverTimeoutMs?: number;
|
|
117
129
|
/**
|
|
118
130
|
* Time limits for each peer this service dials from a list of addresses —
|
|
119
|
-
* {@link SeedBootstrapService.applySeed}'s
|
|
131
|
+
* {@link SeedBootstrapService.applySeed}'s dials of the seed's preferred peers and
|
|
120
132
|
* {@link SeedBootstrapService.deliverSeed}'s dial of a peer id with addresses — per
|
|
121
133
|
* address and per peer (see `peer-dial.ts`). Defaults to {@link DEFAULT_PEER_DIAL_BUDGET}; a `CadreNode`
|
|
122
134
|
* passes its `network.controlCohort` limits.
|
|
@@ -130,12 +142,13 @@ export interface SeedEventCallbacks {
|
|
|
130
142
|
/** Called when a seed is received via the protocol */
|
|
131
143
|
onSeedReceived?: (partyId: string, peerId: string) => void;
|
|
132
144
|
/**
|
|
133
|
-
* Called when a seed
|
|
145
|
+
* Called when a seed delivered over the protocol has been verified, merged and
|
|
146
|
+
* acknowledged; the dials of its preferred peers follow, so this waits on no connection.
|
|
134
147
|
*
|
|
135
148
|
* `seed` is the applied seed itself: the inbound protocol handler applies it
|
|
136
149
|
* INSIDE the service, so this callback is the only seam through which a
|
|
137
150
|
* `CadreNode` sees a wire-delivered seed's contents — which it needs to
|
|
138
|
-
* retain the
|
|
151
|
+
* retain the preferred peers as cold-start bootstrap dial targets.
|
|
139
152
|
*/
|
|
140
153
|
onSeedApplied?: (partyId: string, peersAdded: number, seed: ControlNetworkSeed) => void;
|
|
141
154
|
/** Called when seed application fails */
|
|
@@ -152,7 +165,6 @@ export declare class SeedBootstrapService {
|
|
|
152
165
|
private readonly config;
|
|
153
166
|
private libp2pNode;
|
|
154
167
|
private controlDatabase;
|
|
155
|
-
private readonly ownerPublicKey;
|
|
156
168
|
private readonly trustPolicy;
|
|
157
169
|
private readonly seedReadTimeoutMs;
|
|
158
170
|
private readonly maxConcurrentSeeds;
|
|
@@ -168,20 +180,21 @@ export declare class SeedBootstrapService {
|
|
|
168
180
|
*/
|
|
169
181
|
setEventCallbacks(callbacks: SeedEventCallbacks): void;
|
|
170
182
|
/**
|
|
171
|
-
* Whether this service holds an owner
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
* drain to skip owner work on a non-owner node.
|
|
183
|
+
* Whether this service holds an owner signer, i.e. can produce the owner signatures that
|
|
184
|
+
* gate `CadrePeer` / `DeviceToken` inserts, deletes, and re-authorizations. A
|
|
185
|
+
* seed-listener-only service (`enableSeedListener`, no signer) returns false: it can
|
|
186
|
+
* receive/apply seeds but cannot author or re-issue owner writes. Used by the
|
|
187
|
+
* write-while-alone re-replication drain to skip owner work on a non-owner node.
|
|
177
188
|
*/
|
|
178
189
|
canAuthorize(): boolean;
|
|
190
|
+
/** The owner signer this service was built with, or null for a listener-only service. */
|
|
191
|
+
get ownerSigner(): OwnerSigner | null;
|
|
179
192
|
/**
|
|
180
193
|
* Initialize the service with libp2p node and control database.
|
|
181
194
|
*
|
|
182
195
|
* `registerHandler` (default true) gates registration of the shared inbound
|
|
183
196
|
* `/sereus/seed/1.0.0` handler on `libp2pNode`. Persistent services
|
|
184
|
-
* (`
|
|
197
|
+
* (`CadreNode.useOwnerSigner`, `enableSeedListener`) own that handler and leave
|
|
185
198
|
* it on. The throwaway temp service CadreNode builds in `applySeed` passes
|
|
186
199
|
* `false`: it only needs the stored `libp2pNode` / `controlDatabase` for
|
|
187
200
|
* dialing and known-key lookup, and must NOT bind a discarded closure to the
|
|
@@ -207,8 +220,11 @@ export declare class SeedBootstrapService {
|
|
|
207
220
|
* `UpdatedAt` but no self-signature (`Sig` null) — the owner cannot produce
|
|
208
221
|
* the peer's self-signature, so the peer must self-publish (see
|
|
209
222
|
* {@link CadreNode.registerSelf}) before the row resolves.
|
|
223
|
+
*
|
|
224
|
+
* @param sign - The signature function of an owner approval the caller already holds, so a
|
|
225
|
+
* multi-step action asks once; omitted, this write asks for its own approval.
|
|
210
226
|
*/
|
|
211
|
-
authorizePeer(options: AuthorizePeerOptions): Promise<void>;
|
|
227
|
+
authorizePeer(options: AuthorizePeerOptions, sign?: OwnerSign): Promise<void>;
|
|
212
228
|
/**
|
|
213
229
|
* Owner-signed INSERT of this node's OWN self-signed address record.
|
|
214
230
|
*
|
|
@@ -222,17 +238,16 @@ export declare class SeedBootstrapService {
|
|
|
222
238
|
* in which case the row in the database is NOT this record and carries whatever
|
|
223
239
|
* `Sig` that writer had, so the caller must self-update to publish its signature.
|
|
224
240
|
*/
|
|
225
|
-
insertSelfPeerRecord(record: PeerAddressRecord): Promise<boolean>;
|
|
241
|
+
insertSelfPeerRecord(record: PeerAddressRecord, sign?: OwnerSign): Promise<boolean>;
|
|
226
242
|
/**
|
|
227
|
-
* Shared owner-signed `CadrePeer` INSERT — the row fields and the owner-
|
|
243
|
+
* Shared owner-signed `CadrePeer` INSERT — the row fields and the owner-signer
|
|
228
244
|
* precondition; the stamp mint, voucher signature, write lock, existence check and
|
|
229
245
|
* membership notify are all {@link ControlDatabase.insertCadrePeer}'s (see there for
|
|
230
246
|
* the anti-replay and insert-race rationale). No `CadrePeer` write may bypass that
|
|
231
247
|
* method: the write is what admits the peer's traffic.
|
|
232
248
|
*
|
|
233
|
-
* The DB check precedes the owner-
|
|
234
|
-
* always surfaced them
|
|
235
|
-
* DB check).
|
|
249
|
+
* The DB check precedes the owner-signer check here, matching the order this method has
|
|
250
|
+
* always surfaced them.
|
|
236
251
|
*
|
|
237
252
|
* @returns `true` when this call performed the INSERT, `false` when the row was
|
|
238
253
|
* already seated by a concurrent writer. The loser needs to know: an authorize seats
|
|
@@ -257,7 +272,7 @@ export declare class SeedBootstrapService {
|
|
|
257
272
|
* fresh signature — unaffected by the cleared row's retired stamp
|
|
258
273
|
* (`DeviceToken.NotRevoked`).
|
|
259
274
|
*/
|
|
260
|
-
insertSelfDeviceToken(record: DeviceTokenRecord): Promise<void>;
|
|
275
|
+
insertSelfDeviceToken(record: DeviceTokenRecord, sign?: OwnerSign): Promise<void>;
|
|
261
276
|
/**
|
|
262
277
|
* Owner-signed DELETE of a peer's `DeviceToken` row (logout / token
|
|
263
278
|
* invalidation). The `DeviceToken.AuthorizedDelete` constraint validates an owner
|
|
@@ -276,44 +291,27 @@ export declare class SeedBootstrapService {
|
|
|
276
291
|
* Both digests, the stamp read, and the transaction come from
|
|
277
292
|
* {@link ControlDatabase.deleteDeviceToken} — one shared implementation across
|
|
278
293
|
* `CadrePeer` / `DeviceToken` / `Strand` / `ValidationKey`. What stays here is the
|
|
279
|
-
* owner-
|
|
294
|
+
* owner-signer precondition; a no-op on an already-absent row is the shared body's
|
|
280
295
|
* behavior, and unlike {@link removePeer} nothing here rides on it.
|
|
281
296
|
*/
|
|
282
|
-
deleteDeviceToken(peerId: string): Promise<void>;
|
|
283
|
-
/**
|
|
284
|
-
* Return the configured owner private key, or throw if none is set. The single
|
|
285
|
-
* precondition gate for every owner-signed write. {@link removePeer} /
|
|
286
|
-
* {@link reauthorizePeer} read the row's `StampId` from the DB BEFORE they sign, so
|
|
287
|
-
* they call this up front — otherwise a keyless service would either surface the
|
|
288
|
-
* wrong "Control database not initialized" error or, worse, silently no-op when the
|
|
289
|
-
* target row is absent (the early `stampId === null` return) instead of rejecting.
|
|
290
|
-
*/
|
|
291
|
-
private requireOwnerPrivateKey;
|
|
297
|
+
deleteDeviceToken(peerId: string, sign?: OwnerSign): Promise<void>;
|
|
292
298
|
/**
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
* their first line and get the owner-key precondition for free.
|
|
300
|
-
*/
|
|
301
|
-
private requireOwnerPublicKey;
|
|
302
|
-
/**
|
|
303
|
-
* Sign a base64url digest with the owner key (ed25519). The single place the
|
|
304
|
-
* owner private key is applied; callers pass the canonical domain-tagged digest for
|
|
305
|
-
* the specific action ({@link deviceTokenAddDigest}), or the raw-bytes form via
|
|
306
|
-
* {@link signMessageBytes}. Throws if no owner key is set.
|
|
299
|
+
* Return the configured owner signer, or throw if none is set. The single precondition
|
|
300
|
+
* gate for every owner-signed write. {@link removePeer} / {@link reauthorizePeer} read the
|
|
301
|
+
* row from the DB BEFORE they sign, so they call this up front — otherwise a signerless
|
|
302
|
+
* service would either surface the wrong "Control database not initialized" error or,
|
|
303
|
+
* worse, silently no-op when the target row is absent (their early absent return) instead
|
|
304
|
+
* of rejecting.
|
|
307
305
|
*/
|
|
308
|
-
private
|
|
306
|
+
private requireOwnerSigner;
|
|
307
|
+
/** The control database {@link initialize} attached, or a throw. */
|
|
308
|
+
private requireControlDatabase;
|
|
309
309
|
/**
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
* satisfies the same schema CHECK as one from the callers that sign the bytes directly — see
|
|
314
|
-
* `control-revocation-replay.spec.ts`'s "raw-bytes and digest-string signers agree".
|
|
310
|
+
* Run `body` with an owner signature function: the caller's `sign` when it passes one (a
|
|
311
|
+
* `CadreNode` action already inside its approval), otherwise one approval of this service's
|
|
312
|
+
* signer for `action`, the plain-words description a prompting signer shows.
|
|
315
313
|
*/
|
|
316
|
-
private
|
|
314
|
+
private withOwnerSign;
|
|
317
315
|
/**
|
|
318
316
|
* Remove a peer from the cadre by owner signature.
|
|
319
317
|
*
|
|
@@ -336,64 +334,69 @@ export declare class SeedBootstrapService {
|
|
|
336
334
|
* Both digests, the stamp read, the transaction, and the post-commit membership notify
|
|
337
335
|
* come from {@link ControlDatabase.deleteCadrePeer} — one shared implementation across
|
|
338
336
|
* `CadrePeer` / `DeviceToken` / `Strand` / `ValidationKey`. What stays here is the
|
|
339
|
-
* owner-
|
|
337
|
+
* owner-signer precondition and the absent-row gate the notify depends on (below).
|
|
340
338
|
*/
|
|
341
|
-
removePeer(peerId: string): Promise<void>;
|
|
339
|
+
removePeer(peerId: string, sign?: OwnerSign): Promise<void>;
|
|
342
340
|
/**
|
|
343
|
-
* Seat `ownerPublicKey` as a further owner, signed by this service's owner
|
|
341
|
+
* Seat `ownerPublicKey` as a further owner, signed by this service's owner signer. The
|
|
344
342
|
* liveness check, the stamp, the signature and the membership notify are
|
|
345
|
-
* {@link ControlDatabase.insertOwnerKeyVouched}'s; what stays here is the owner-
|
|
343
|
+
* {@link ControlDatabase.insertOwnerKeyVouched}'s; what stays here is the owner-signer
|
|
346
344
|
* precondition, checked before any read (see {@link removePeer}).
|
|
347
345
|
*
|
|
346
|
+
* @param label - the user's name for the key, bound into the signature
|
|
347
|
+
* ({@link ControlDatabase.insertOwnerKey} has the rule).
|
|
348
348
|
* @returns `true` when the row was seated, `false` when the key is already a live owner.
|
|
349
349
|
*/
|
|
350
|
-
addOwner(ownerPublicKey: string): Promise<boolean>;
|
|
350
|
+
addOwner(ownerPublicKey: string, label?: string, sign?: OwnerSign): Promise<boolean>;
|
|
351
351
|
/**
|
|
352
|
-
* Remove `ownerPublicKey` from the owners, signed by this service's owner
|
|
352
|
+
* Remove `ownerPublicKey` from the owners, signed by this service's owner signer: the delete
|
|
353
353
|
* and its `Revocation` tombstone in one transaction. The by-name refusals (self-removal,
|
|
354
354
|
* the last owner), the digests and the membership notify are
|
|
355
|
-
* {@link ControlDatabase.deleteOwnerKey}'s; what stays here is the owner-
|
|
355
|
+
* {@link ControlDatabase.deleteOwnerKey}'s; what stays here is the owner-signer precondition,
|
|
356
356
|
* checked before any read (see {@link removePeer}).
|
|
357
357
|
*
|
|
358
358
|
* @returns `true` when the row was removed, `false` when the key is not a live owner here.
|
|
359
359
|
*/
|
|
360
|
-
removeOwner(ownerPublicKey: string): Promise<boolean>;
|
|
360
|
+
removeOwner(ownerPublicKey: string, sign?: OwnerSign): Promise<boolean>;
|
|
361
361
|
/**
|
|
362
|
-
* Re-vouch another owner's row under this service's owner
|
|
362
|
+
* Re-vouch another owner's row under this service's owner signer, so it stands on a remaining
|
|
363
363
|
* owner's signature before the owner that added it is removed
|
|
364
|
-
* ({@link ControlDatabase.revouchOwnerKey}; for `CadreNode.
|
|
365
|
-
* here is the owner-
|
|
364
|
+
* ({@link ControlDatabase.revouchOwnerKey}; for `CadreNode.removeOwner` only). What stays
|
|
365
|
+
* here is the owner-signer precondition, checked before any read (see {@link removePeer}).
|
|
366
366
|
*
|
|
367
367
|
* @returns `true` when the row was re-vouched, `false` when the key is not a live owner here.
|
|
368
368
|
*/
|
|
369
|
-
revouchOwner(ownerPublicKey: string): Promise<boolean>;
|
|
369
|
+
revouchOwner(ownerPublicKey: string, sign?: OwnerSign): Promise<boolean>;
|
|
370
370
|
/**
|
|
371
|
-
* Remove a machine completely, signed by this service's owner
|
|
372
|
-
* `
|
|
373
|
-
*
|
|
374
|
-
* ({@link
|
|
375
|
-
* checked before any read (see {@link removePeer}).
|
|
371
|
+
* Remove a machine completely, signed by this service's owner signer: its `CadrePeer` row, its
|
|
372
|
+
* `DeviceToken` row, and the withdrawal of every invitation in `target.inviteKeys`, all in one
|
|
373
|
+
* transaction ({@link ControlDatabase.removeMachine}). What stays here is the owner-signer
|
|
374
|
+
* precondition, checked before any read (see {@link removePeer}).
|
|
376
375
|
*/
|
|
377
|
-
removeMachine(target: Parameters<ControlDatabase['removeMachine']>[0]): Promise<
|
|
376
|
+
removeMachine(target: Parameters<ControlDatabase['removeMachine']>[0], sign?: OwnerSign): Promise<MachineRemovalResult>;
|
|
378
377
|
/**
|
|
379
|
-
* Owner "re-touch" of an existing `CadrePeer` membership row
|
|
380
|
-
*
|
|
381
|
-
* the write-while-alone re-replication
|
|
382
|
-
* a membership row that committed local-only
|
|
383
|
-
* pushed to the cohort once it grows
|
|
378
|
+
* Owner "re-touch" of an existing `CadrePeer` membership row, in one of two modes
|
|
379
|
+
* ({@link CadrePeerRetouchMode}): `'rebroadcast'` bumps `UpdatedAt` and re-vouches the row so
|
|
380
|
+
* it is re-emitted as a fresh, broadcasting transaction — the write-while-alone re-replication
|
|
381
|
+
* primitive (`control-write-ensure-replicated`): a membership row that committed local-only
|
|
382
|
+
* (its block's cluster ≤1 at insert) is pushed to the cohort once it grows — and writes only
|
|
383
|
+
* while the machine has not self-published; `'revouch'` rebinds the voucher to this node's
|
|
384
|
+
* owner key, leaving `UpdatedAt` alone, whether or not the machine has self-published
|
|
385
|
+
* (`CadreNode.removeOwner`).
|
|
384
386
|
*
|
|
385
|
-
* The
|
|
387
|
+
* The row read, the mode's decision, the stamp bump, the voucher signature, the write lock,
|
|
388
|
+
* the lost-update retry and the membership notify are
|
|
386
389
|
* {@link ControlDatabase.reauthorizeCadrePeer}'s — including the caveat that it rebinds
|
|
387
|
-
* `VouchOwner` to this node's owner key. What stays here is the owner-
|
|
388
|
-
*
|
|
389
|
-
* A no-op (no throw, no notify) when the row does not exist.
|
|
390
|
+
* `VouchOwner` to this node's owner key. What stays here is the owner-signer precondition.
|
|
390
391
|
*
|
|
391
392
|
* @param peerId - the membership row to re-touch.
|
|
392
|
-
* @param
|
|
393
|
-
* @
|
|
393
|
+
* @param mode - re-broadcast or re-vouch.
|
|
394
|
+
* @returns what was found and done ({@link CadrePeerRetouchOutcome}); an absent row, or a
|
|
395
|
+
* self-published one in `'rebroadcast'` mode, writes nothing and does not throw.
|
|
396
|
+
* @throws if no owner signer is configured (a non-owner cannot
|
|
394
397
|
* re-sign another peer's row) or the control database is not initialized.
|
|
395
398
|
*/
|
|
396
|
-
reauthorizePeer(peerId: string,
|
|
399
|
+
reauthorizePeer(peerId: string, mode: CadrePeerRetouchMode, sign?: OwnerSign): Promise<CadrePeerRetouchOutcome>;
|
|
397
400
|
/**
|
|
398
401
|
* Owner re-issue of a batch of `Revocation` tombstones: bump each row's
|
|
399
402
|
* `ReissuedAt` so the storage layer re-broadcasts a tombstone that committed
|
|
@@ -404,51 +407,68 @@ export declare class SeedBootstrapService {
|
|
|
404
407
|
*
|
|
405
408
|
* The signatures, the single transaction, and the strictly-monotonic
|
|
406
409
|
* `reissuedAt` contract are {@link ControlDatabase.reissueRevocations}'s. What
|
|
407
|
-
* stays here is the owner-
|
|
410
|
+
* stays here is the owner-signer precondition.
|
|
408
411
|
*
|
|
409
412
|
* @returns how many tombstones were re-issued (`rows.length` on success).
|
|
410
|
-
* @throws if no owner
|
|
413
|
+
* @throws if no owner signer is configured or the control database is not
|
|
411
414
|
* initialized.
|
|
412
415
|
*/
|
|
413
|
-
reissueRevocations(rows: readonly RevocationRow[], reissuedAt: number): Promise<number>;
|
|
414
|
-
/**
|
|
415
|
-
* Owner filing of the singleton `Revocation` ledger marker, so the table is never a
|
|
416
|
-
* never-written block that the storage layer re-consults on every read.
|
|
417
|
-
*
|
|
418
|
-
* The signature, the insert-if-absent guard and the `'already-open'` mapping are
|
|
419
|
-
* {@link ControlDatabase.openRevocationLedger}'s. What stays here is the owner-key
|
|
420
|
-
* precondition.
|
|
421
|
-
*
|
|
422
|
-
* @throws if no owner private key is configured or the control database is not
|
|
423
|
-
* initialized.
|
|
424
|
-
*/
|
|
425
|
-
openRevocationLedger(): Promise<RevocationLedgerOpenResult>;
|
|
416
|
+
reissueRevocations(rows: readonly RevocationRow[], reissuedAt: number, sign?: OwnerSign): Promise<number>;
|
|
426
417
|
/**
|
|
427
418
|
* Owner-signed INSERT of a `CadreInvite` row — an invitation any member machine can redeem
|
|
428
419
|
* on this owner's behalf ({@link ControlDatabase.insertCadreInvite}). The keypair mint, the
|
|
429
420
|
* expiry and use-count defaults, and the bundle the holder receives are
|
|
430
|
-
* `CadreNode.createCadreInvitation`'s; what stays here is the owner-
|
|
431
|
-
* the
|
|
421
|
+
* `CadreNode.createCadreInvitation`'s; what stays here is the owner-signer precondition and
|
|
422
|
+
* the approval, as {@link insertSelfDeviceToken} keeps them for device tokens.
|
|
432
423
|
*
|
|
433
424
|
* @returns the row as stored, which the invitation bundle carries verbatim.
|
|
434
|
-
* @throws if no owner
|
|
425
|
+
* @throws if no owner signer is configured or the control database is not initialized.
|
|
435
426
|
*/
|
|
436
|
-
insertCadreInvite(invite: Parameters<ControlDatabase['insertCadreInvite']>[0]): Promise<CadreInviteRow>;
|
|
427
|
+
insertCadreInvite(invite: Parameters<ControlDatabase['insertCadreInvite']>[0], sign?: OwnerSign): Promise<CadreInviteRow>;
|
|
437
428
|
/**
|
|
438
429
|
* Owner-signed WITHDRAWAL of a `CadreInvite`: the `Revocation` tombstone over its stamp, with
|
|
439
430
|
* the row kept ({@link ControlDatabase.withdrawCadreInvite}). What stays here is the
|
|
440
|
-
* owner-
|
|
431
|
+
* owner-signer precondition.
|
|
441
432
|
*
|
|
442
433
|
* @returns `true` when this call filed the tombstone, `false` when the row is absent here or
|
|
443
434
|
* already withdrawn.
|
|
444
|
-
* @throws if no owner
|
|
435
|
+
* @throws if no owner signer is configured or the control database is not initialized.
|
|
436
|
+
*/
|
|
437
|
+
withdrawCadreInvite(key: string, sign?: OwnerSign): Promise<boolean>;
|
|
438
|
+
/**
|
|
439
|
+
* Owner-signed INSERT of an `OwnerGrant` row — a grant of ownership any member machine can
|
|
440
|
+
* redeem on this owner's behalf ({@link ControlDatabase.insertOwnerGrant}). The keypair mint,
|
|
441
|
+
* the lifetime default and the bundle the holder receives are `CadreNode.createOwnerGrant`'s;
|
|
442
|
+
* what stays here is the owner-signer precondition and the approval, as for
|
|
443
|
+
* {@link insertCadreInvite}. The label is checked before the approval opens, so one the row
|
|
444
|
+
* would refuse never prompts the user.
|
|
445
|
+
*
|
|
446
|
+
* @returns the row as stored, which the grant bundle carries verbatim.
|
|
447
|
+
* @throws if no owner signer is configured, the control database is not initialized, or the label is too long.
|
|
445
448
|
*/
|
|
446
|
-
|
|
449
|
+
insertOwnerGrant(grant: Parameters<ControlDatabase['insertOwnerGrant']>[0], sign?: OwnerSign): Promise<OwnerGrantRow>;
|
|
450
|
+
/**
|
|
451
|
+
* Owner-signed WITHDRAWAL of an `OwnerGrant`: the `Revocation` tombstone over its stamp, with
|
|
452
|
+
* the row kept ({@link ControlDatabase.withdrawOwnerGrant}). What stays here is the
|
|
453
|
+
* owner-signer precondition.
|
|
454
|
+
*
|
|
455
|
+
* @returns `true` when this call filed the tombstone, `false` when the row is absent here or
|
|
456
|
+
* already withdrawn.
|
|
457
|
+
* @throws if no owner signer is configured or the control database is not initialized.
|
|
458
|
+
*/
|
|
459
|
+
withdrawOwnerGrant(key: string, sign?: OwnerSign): Promise<boolean>;
|
|
447
460
|
/**
|
|
448
461
|
* Create a seed from the current control network state.
|
|
449
|
-
* The seed contains peer information and is signed by an owner
|
|
462
|
+
* The seed contains peer information and is signed by an owner; its `signerKey` is the
|
|
463
|
+
* owner signer's key.
|
|
450
464
|
*/
|
|
451
|
-
createSeed(): Promise<ControlNetworkSeed>;
|
|
465
|
+
createSeed(sign?: OwnerSign): Promise<ControlNetworkSeed>;
|
|
466
|
+
/**
|
|
467
|
+
* {@link createSeed}, with `selfRelayAddr` added to this node's own peer entry before the
|
|
468
|
+
* seed is signed: the signature covers every address ({@link seedDigest}), so nothing may
|
|
469
|
+
* be added after it.
|
|
470
|
+
*/
|
|
471
|
+
private mintSeed;
|
|
452
472
|
/**
|
|
453
473
|
* Apply a seed to populate the peer cache and enable connections.
|
|
454
474
|
*
|
|
@@ -456,9 +476,8 @@ export declare class SeedBootstrapService {
|
|
|
456
476
|
* `signerKey` that does NOT come from the seed body: the receiver's
|
|
457
477
|
* node-local {@link SeedBootstrapConfig.trustedOwners} anchor, optionally
|
|
458
478
|
* augmented by pinned keys or TOFU via the configured/overriding
|
|
459
|
-
* `SeedTrustPolicy`. A forged self-
|
|
460
|
-
*
|
|
461
|
-
* by a key a stranger genesis-inserted into the replicated `OwnerKey` table.
|
|
479
|
+
* `SeedTrustPolicy`. A forged self-signed seed does not pass, and neither does
|
|
480
|
+
* one signed by a key a stranger genesis-inserted into the replicated `OwnerKey` table.
|
|
462
481
|
*
|
|
463
482
|
* A key accepted via a pin/TOFU is persisted into the anchor (the policy says
|
|
464
483
|
* so via `SeedTrustDecision.anchorAs`), so the next seed from that owner is
|
|
@@ -475,22 +494,26 @@ export declare class SeedBootstrapService {
|
|
|
475
494
|
/**
|
|
476
495
|
* The first half of {@link applySeed}: check the signature and the signer's trust, then merge
|
|
477
496
|
* the seed's peer addresses into the peer store. Every rejection happens here, so this result is
|
|
478
|
-
* what the inbound handler acks with; the
|
|
497
|
+
* what the inbound handler acks with; the dials that follow cannot change it.
|
|
479
498
|
*/
|
|
480
499
|
private verifyAndMergeSeed;
|
|
481
500
|
/**
|
|
482
|
-
* The second half of {@link applySeed}: dial the seed's
|
|
501
|
+
* The second half of {@link applySeed}: dial the seed's preferred peers (`SeedPeer.preferred`:
|
|
502
|
+
* the machine that minted it and every always-on machine) to establish connections.
|
|
483
503
|
*
|
|
484
|
-
* Best-effort and COUNTED:
|
|
504
|
+
* Best-effort and COUNTED: a peer that is momentarily down leaves this node seeded but
|
|
485
505
|
* unconnected, which the caller can only see if the outcome is reported (see
|
|
486
|
-
* `ApplySeedResult.
|
|
506
|
+
* `ApplySeedResult.preferredDialsFailed`). Recovery is not this loop's job —
|
|
487
507
|
* `CadreNode.dialColdStartBootstrap` retries these same addresses on every control-cohort
|
|
488
508
|
* reconcile pass until the control database has siblings.
|
|
489
509
|
*
|
|
490
|
-
* The inbound handler runs this AFTER it has acked and
|
|
491
|
-
* ({@link handleSeedStream}), because an unreachable
|
|
510
|
+
* The inbound handler runs this AFTER it has acked, closed the stream and reported the seed
|
|
511
|
+
* applied ({@link handleSeedStream}), because an unreachable peer can take `dialBudget.totalMs`.
|
|
512
|
+
* The node may stop while these dials are in flight (cadre-cli restarts a claimed node on
|
|
513
|
+
* `seed:applied`): the node's stop aborts the dial in flight and every later one is refused
|
|
514
|
+
* at once (`dialAddr`), and each is counted as failed here.
|
|
492
515
|
*/
|
|
493
|
-
private
|
|
516
|
+
private dialPreferredPeers;
|
|
494
517
|
/**
|
|
495
518
|
* Persist a signer that a pin/TOFU accepted into the node-local anchor, so a
|
|
496
519
|
* later seed from the same owner is anchored without re-supplying the pin
|
|
@@ -603,10 +626,10 @@ export declare class SeedBootstrapService {
|
|
|
603
626
|
*/
|
|
604
627
|
validateSeedSignature(seed: ControlNetworkSeed, digestB64?: string): boolean;
|
|
605
628
|
/**
|
|
606
|
-
* The peers a seed carries: the control database's own projection
|
|
629
|
+
* The peers a seed `minterPeerId` mints carries: the control database's own projection
|
|
607
630
|
* ({@link ControlDatabase.querySeedPeers}, shared with the cadre invitation redemption
|
|
608
|
-
* reply), which reads through the revocation filter and
|
|
609
|
-
*
|
|
631
|
+
* reply), which reads through the revocation filter and marks the minter and every
|
|
632
|
+
* always-on machine preferred — a dial hint, not a trust decision.
|
|
610
633
|
*/
|
|
611
634
|
private queryPeers;
|
|
612
635
|
/**
|
|
@@ -617,14 +640,16 @@ export declare class SeedBootstrapService {
|
|
|
617
640
|
private registerProtocolHandler;
|
|
618
641
|
/**
|
|
619
642
|
* Read one inbound seed frame, verify and merge it, write the ack and close the
|
|
620
|
-
* stream, then dial the seed's
|
|
643
|
+
* stream, report the seed applied, then dial the seed's preferred peers.
|
|
621
644
|
*
|
|
622
|
-
* The ack
|
|
623
|
-
* a dial for `dialBudget.totalMs` (86 s at the default declared link), which is
|
|
624
|
-
* link time and does not belong inside the sender's delivery deadline
|
|
625
|
-
*
|
|
626
|
-
*
|
|
627
|
-
*
|
|
645
|
+
* The ack, the close and `onSeedApplied` come BEFORE those dials: an unreachable peer
|
|
646
|
+
* can hold a dial for `dialBudget.totalMs` (86 s at the default declared link), which is
|
|
647
|
+
* not link time and does not belong inside the sender's delivery deadline, nor ahead of
|
|
648
|
+
* a claimed node's restart (which stops this node, so its dials would be wasted). The
|
|
649
|
+
* close is what releases the sender, which reads the ack to end-of-stream, and it is
|
|
650
|
+
* awaited before `onSeedApplied`, so the ack is flushed before anything the callback
|
|
651
|
+
* starts. The stream stays counted in {@link activeStreams} through the dials, so
|
|
652
|
+
* {@link maxConcurrentSeeds} still bounds concurrent dial phases.
|
|
628
653
|
*
|
|
629
654
|
* Hardened against a buggy/compromised own-cadre node: a concurrency cap (over
|
|
630
655
|
* {@link maxConcurrentSeeds}, reply without applying), a read timeout (a peer
|
|
@@ -664,10 +689,12 @@ export declare class SeedBootstrapService {
|
|
|
664
689
|
* does not listen. Call `CadreNode.reconcileControlCohort()` after delivering
|
|
665
690
|
* the seed to dial at once.
|
|
666
691
|
*
|
|
692
|
+
* The vouch and the seed are one owner approval.
|
|
693
|
+
*
|
|
667
694
|
* @param options - Drone peer info from provider API
|
|
668
695
|
* @returns Seed and encoded seed for drone initialization
|
|
669
696
|
*/
|
|
670
|
-
addDrone(options: AddDroneOptions): Promise<DroneInitResult>;
|
|
697
|
+
addDrone(options: AddDroneOptions, sign?: OwnerSign): Promise<DroneInitResult>;
|
|
671
698
|
/**
|
|
672
699
|
* Add a phone to the cadre with relay support.
|
|
673
700
|
*
|
|
@@ -675,8 +702,10 @@ export declare class SeedBootstrapService {
|
|
|
675
702
|
* 1. Authorizes the new phone peer
|
|
676
703
|
* 2. Creates a seed with relay addresses for dialing
|
|
677
704
|
*
|
|
705
|
+
* The vouch and the seed are one owner approval.
|
|
706
|
+
*
|
|
678
707
|
* @param phonePeerId - Peer ID of the new phone
|
|
679
708
|
* @returns Seed with relay addresses for out-of-band delivery
|
|
680
709
|
*/
|
|
681
|
-
addPhoneWithRelay(phonePeerId: string): Promise<DroneInitResult>;
|
|
710
|
+
addPhoneWithRelay(phonePeerId: string, sign?: OwnerSign): Promise<DroneInitResult>;
|
|
682
711
|
}
|