@serve.zone/interfaces 31.9.0 → 32.0.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/.smartconfig.json +1 -0
- package/changelog.md +467 -0
- package/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/appstore/types.d.ts +4 -6
- package/dist_ts/appstore/types.js +5 -5
- package/dist_ts/data/backup.d.ts +3 -26
- package/dist_ts/data/cluster.d.ts +36 -11
- package/dist_ts/data/cluster.js +33 -22
- package/dist_ts/data/clusteringress.d.ts +8 -0
- package/dist_ts/data/clusteringress.js +13 -8
- package/dist_ts/data/clusternode.d.ts +121 -74
- package/dist_ts/data/clusternode.js +109 -132
- package/dist_ts/data/coremail.d.ts +3 -7
- package/dist_ts/data/coremail.js +2 -2
- package/dist_ts/data/coremail.runtime.d.ts +0 -1
- package/dist_ts/data/coremail.runtime.js +5 -22
- package/dist_ts/data/deploymentadoption.d.ts +0 -2
- package/dist_ts/data/deploymentadoption.js +40 -6
- package/dist_ts/data/deploymentoperation.js +16 -3
- package/dist_ts/data/deploymentpreflight.d.ts +0 -2
- package/dist_ts/data/deploymentpreflight.js +1 -1
- package/dist_ts/data/immutableimage.d.ts +38 -21
- package/dist_ts/data/immutableimage.js +45 -5
- package/dist_ts/data/index.d.ts +1 -1
- package/dist_ts/data/isolatedrestore.d.ts +139 -21
- package/dist_ts/data/isolatedrestore.golden.d.ts +0 -1
- package/dist_ts/data/isolatedrestore.golden.js +6 -9
- package/dist_ts/data/isolatedrestore.js +176 -40
- package/dist_ts/data/mail.d.ts +1 -1
- package/dist_ts/data/networkaddressplan.d.ts +8 -8
- package/dist_ts/data/networkaddressplan.js +4 -4
- package/dist_ts/data/networkauthority.d.ts +20 -22
- package/dist_ts/data/networkauthority.js +26 -28
- package/dist_ts/data/networkcredential.d.ts +10 -10
- package/dist_ts/data/networkcredential.js +16 -16
- package/dist_ts/data/networkdelivery.d.ts +18 -18
- package/dist_ts/data/networkdelivery.js +16 -16
- package/dist_ts/data/networklease.d.ts +18 -7
- package/dist_ts/data/networklease.js +29 -7
- package/dist_ts/data/networknode.d.ts +2 -2
- package/dist_ts/data/networkprojection.d.ts +59 -60
- package/dist_ts/data/networkprojection.js +53 -57
- package/dist_ts/data/networkprotection.d.ts +27 -28
- package/dist_ts/data/networkprotection.js +36 -36
- package/dist_ts/data/networkrouter.d.ts +11 -11
- package/dist_ts/data/networkrouter.js +1 -1
- package/dist_ts/data/networksigning.d.ts +16 -18
- package/dist_ts/data/networksigning.js +20 -21
- package/dist_ts/data/nodecredential.d.ts +4 -6
- package/dist_ts/data/nodeenrollment.d.ts +35 -40
- package/dist_ts/data/nodeenrollment.js +57 -72
- package/dist_ts/data/privatenetwork.d.ts +21 -24
- package/dist_ts/data/privatenetwork.js +39 -54
- package/dist_ts/data/runtimeassignment.d.ts +50 -34
- package/dist_ts/data/runtimeassignment.js +79 -45
- package/dist_ts/data/runtimeconfig.d.ts +21 -22
- package/dist_ts/data/runtimeconfig.js +24 -24
- package/dist_ts/data/runtimesession.d.ts +100 -62
- package/dist_ts/data/runtimesession.js +98 -79
- package/dist_ts/data/runtimeterminalreceipt.d.ts +28 -29
- package/dist_ts/data/runtimeterminalreceipt.js +42 -42
- package/dist_ts/data/secret.d.ts +18 -25
- package/dist_ts/data/secret.js +12 -52
- package/dist_ts/data/servicecredential.d.ts +14 -16
- package/dist_ts/data/servicecredential.js +17 -28
- package/dist_ts/data/serviceruntime.d.ts +7 -7
- package/dist_ts/data/serviceruntime.js +4 -4
- package/dist_ts/data/sparknodereport.d.ts +27 -14
- package/dist_ts/data/sparknodereport.js +35 -28
- package/dist_ts/data/webpush.d.ts +0 -1
- package/dist_ts/index.d.ts +2 -1
- package/dist_ts/index.js +3 -2
- package/dist_ts/platform/objectstorageretention.d.ts +21 -24
- package/dist_ts/platform/objectstorageretention.js +6 -18
- package/dist_ts/platform/storage.d.ts +1 -3
- package/dist_ts/platform/storagemigration.d.ts +0 -7
- package/dist_ts/platform/storagemigration.golden.d.ts +0 -1
- package/dist_ts/platform/storagemigration.golden.js +8 -12
- package/dist_ts/platform/storagemigration.js +6 -51
- package/dist_ts/platform/types.d.ts +2 -2
- package/dist_ts/private/canonicaljson.d.ts +9 -1
- package/dist_ts/private/canonicaljson.js +14 -2
- package/dist_ts/private/dataproperties.d.ts +62 -0
- package/dist_ts/private/dataproperties.js +117 -0
- package/dist_ts/private/networkcontract.d.ts +10 -10
- package/dist_ts/private/networkcontract.js +1 -1
- package/dist_ts/private/releaseversion.d.ts +37 -0
- package/dist_ts/private/releaseversion.js +48 -0
- package/dist_ts/private/runtimepolicy.d.ts +2 -2
- package/dist_ts/private/runtimepolicy.js +1 -1
- package/dist_ts/private/tokenlist.d.ts +9 -0
- package/dist_ts/private/tokenlist.js +23 -0
- package/dist_ts/protocol.d.ts +137 -0
- package/dist_ts/protocol.js +255 -0
- package/dist_ts/requests/admin.d.ts +8 -8
- package/dist_ts/requests/backup.d.ts +102 -112
- package/dist_ts/requests/cluster.d.ts +10 -10
- package/dist_ts/requests/clusteringress.d.ts +9 -0
- package/dist_ts/requests/clusteringress.js +1 -1
- package/dist_ts/requests/config.d.ts +3 -3
- package/dist_ts/requests/corestore.d.ts +0 -3
- package/dist_ts/requests/corestore.js +5 -9
- package/dist_ts/requests/network.d.ts +30 -30
- package/dist_ts/requests/node.d.ts +15 -28
- package/dist_ts/requests/pallet.d.ts +13 -13
- package/dist_ts/requests/runtimesession.d.ts +53 -41
- package/dist_ts/requests/secret.d.ts +4 -5
- package/dist_ts/requests/secret.js +1 -5
- package/dist_ts/runtime.corestore.d.ts +56 -74
- package/dist_ts/runtime.corestore.databaseexportpackage.d.ts +30 -36
- package/dist_ts/runtime.corestore.databaseexportpackage.golden.d.ts +11 -12
- package/dist_ts/runtime.corestore.databaseexportpackage.golden.js +54 -71
- package/dist_ts/runtime.corestore.databaseexportpackage.js +9 -25
- package/dist_ts/runtime.corestore.js +35 -135
- package/dist_ts/runtime.corestore.relay.js +2 -7
- package/dist_ts/runtime.d.ts +38 -48
- package/dist_ts/runtime.js +20 -77
- package/dist_ts/runtime.networkprojection.d.ts +4 -4
- package/dist_ts/runtime.networkprojection.js +18 -18
- package/dist_ts/runtime.workloadinit.d.ts +23 -24
- package/dist_ts/runtime.workloadinit.js +6 -13
- package/package.json +2 -2
- package/readme.md +421 -270
- package/ts/00_commitinfo_data.ts +3 -3
- package/ts/appstore/types.ts +4 -6
- package/ts/data/backup.ts +3 -38
- package/ts/data/cluster.ts +51 -34
- package/ts/data/clusteringress.ts +12 -12
- package/ts/data/clusternode.ts +204 -232
- package/ts/data/coremail.runtime.ts +4 -21
- package/ts/data/coremail.ts +3 -7
- package/ts/data/deploymentadoption.ts +46 -4
- package/ts/data/deploymentoperation.ts +16 -1
- package/ts/data/deploymentpreflight.ts +0 -2
- package/ts/data/immutableimage.ts +71 -24
- package/ts/data/index.ts +1 -1
- package/ts/data/isolatedrestore.golden.ts +5 -9
- package/ts/data/isolatedrestore.ts +339 -54
- package/ts/data/mail.ts +1 -1
- package/ts/data/networkaddressplan.ts +13 -13
- package/ts/data/networkauthority.ts +42 -46
- package/ts/data/networkcredential.ts +24 -24
- package/ts/data/networkdelivery.ts +27 -27
- package/ts/data/networklease.ts +40 -13
- package/ts/data/networknode.ts +2 -2
- package/ts/data/networkprojection.ts +119 -124
- package/ts/data/networkprotection.ts +54 -55
- package/ts/data/networkrouter.ts +14 -14
- package/ts/data/networksigning.ts +29 -32
- package/ts/data/nodecredential.ts +4 -6
- package/ts/data/nodeenrollment.ts +96 -114
- package/ts/data/privatenetwork.ts +58 -74
- package/ts/data/runtimeassignment.ts +143 -94
- package/ts/data/runtimeconfig.ts +45 -46
- package/ts/data/runtimesession.ts +185 -138
- package/ts/data/runtimeterminalreceipt.ts +72 -73
- package/ts/data/secret.ts +28 -76
- package/ts/data/servicecredential.ts +33 -43
- package/ts/data/serviceruntime.ts +11 -11
- package/ts/data/sparknodereport.ts +48 -36
- package/ts/data/webpush.ts +0 -1
- package/ts/index.ts +2 -0
- package/ts/platform/objectstorageretention.ts +36 -55
- package/ts/platform/storage.ts +1 -3
- package/ts/platform/storagemigration.golden.ts +7 -11
- package/ts/platform/storagemigration.ts +5 -55
- package/ts/platform/types.ts +2 -2
- package/ts/private/canonicaljson.ts +13 -1
- package/ts/private/dataproperties.ts +139 -0
- package/ts/private/networkcontract.ts +9 -9
- package/ts/private/releaseversion.ts +70 -0
- package/ts/private/runtimepolicy.ts +2 -2
- package/ts/private/tokenlist.ts +30 -0
- package/ts/protocol.ts +364 -0
- package/ts/requests/admin.ts +11 -11
- package/ts/requests/backup.ts +112 -117
- package/ts/requests/cluster.ts +13 -13
- package/ts/requests/clusteringress.ts +9 -0
- package/ts/requests/config.ts +3 -3
- package/ts/requests/corestore.ts +4 -16
- package/ts/requests/network.ts +40 -40
- package/ts/requests/node.ts +21 -38
- package/ts/requests/pallet.ts +17 -17
- package/ts/requests/runtimesession.ts +63 -51
- package/ts/requests/secret.ts +5 -10
- package/ts/runtime.corestore.databaseexportpackage.golden.ts +77 -95
- package/ts/runtime.corestore.databaseexportpackage.ts +51 -73
- package/ts/runtime.corestore.relay.ts +1 -10
- package/ts/runtime.corestore.ts +118 -268
- package/ts/runtime.networkprojection.ts +30 -30
- package/ts/runtime.ts +83 -158
- package/ts/runtime.workloadinit.ts +36 -48
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.d.ts +0 -902
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.golden.d.ts +0 -35
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.golden.js +0 -315
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.js +0 -3315
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.d.ts +0 -291
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.d.ts +0 -30
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.js +0 -408
- package/dist_ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.js +0 -1126
- package/ts/runtime.cloudlylegacydeploymentsettlement.golden.ts +0 -421
- package/ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.golden.ts +0 -510
- package/ts/runtime.cloudlylegacydeploymentsettlement.offlineexport.ts +0 -2470
- package/ts/runtime.cloudlylegacydeploymentsettlement.ts +0 -6630
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import type { TSha256Digest } from './immutableimage.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { IRuntimeAuthorityReference, IRuntimeController } from './runtimeassignment.js';
|
|
3
3
|
import { canonicalizeStrictJson, createCanonicalJsonSha256Hex } from '../private/canonicaljson.js';
|
|
4
4
|
import { networkPrefix, networkPrivatePrefix } from '../private/networkcontract.js';
|
|
5
5
|
|
|
6
6
|
/** Controller declaration; a digest does not authenticate completeness or activate a pool. */
|
|
7
|
-
export interface
|
|
8
|
-
schemaVersion: 1;
|
|
7
|
+
export interface IRuntimeNetworkProtectedAuthority {
|
|
9
8
|
id: string;
|
|
10
9
|
generation: number;
|
|
11
|
-
controller:
|
|
12
|
-
previous:
|
|
10
|
+
controller: IRuntimeController;
|
|
11
|
+
previous: IRuntimeAuthorityReference | null;
|
|
13
12
|
/** Complete canonical IPv4 union, including all pools and protected endpoints. */
|
|
14
13
|
prefixes: string[];
|
|
15
14
|
pools: Array<{ id: string; purpose: 'workload' | 'transit'; prefix: string }>;
|
|
@@ -21,33 +20,32 @@ export interface IRuntimeNetworkProtectedAuthorityV1 {
|
|
|
21
20
|
digest: TSha256Digest;
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
export interface
|
|
23
|
+
export interface IRuntimeNetworkHandoffPortRange {
|
|
25
24
|
protocol: 'tcp' | 'udp';
|
|
26
25
|
first: number;
|
|
27
26
|
last: number;
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
/** Immutable allocation, retained unchanged while active or quarantined. No expiry implies reuse. */
|
|
31
|
-
export interface
|
|
32
|
-
schemaVersion: 1;
|
|
30
|
+
export interface IRuntimeNetworkHandoffLease {
|
|
33
31
|
id: string;
|
|
34
32
|
generation: number;
|
|
35
|
-
controller:
|
|
33
|
+
controller: IRuntimeController;
|
|
36
34
|
nodeId: string;
|
|
37
35
|
runtimeNamespace: string;
|
|
38
|
-
protectedAuthority:
|
|
36
|
+
protectedAuthority: IRuntimeAuthorityReference;
|
|
39
37
|
/** Logical allocation incarnation, never a path, PID, inode, descriptor or native capability. */
|
|
40
38
|
routerIncarnationId: string;
|
|
41
39
|
transit: { poolId: string; prefix: string; routerAddress: string; hostAddress: string };
|
|
42
|
-
sourcePortRanges:
|
|
40
|
+
sourcePortRanges: IRuntimeNetworkHandoffPortRange[];
|
|
43
41
|
conntrackZone: number;
|
|
44
42
|
conntrackLabel: string;
|
|
45
43
|
digest: TSha256Digest;
|
|
46
44
|
}
|
|
47
45
|
|
|
48
|
-
export const
|
|
49
|
-
protectedDigestDomain: 'serve.zone/runtime-network-protected-authority
|
|
50
|
-
handoffDigestDomain: 'serve.zone/runtime-network-handoff-lease
|
|
46
|
+
export const runtimeNetworkAuthorityContract = Object.freeze({
|
|
47
|
+
protectedDigestDomain: 'serve.zone/runtime-network-protected-authority',
|
|
48
|
+
handoffDigestDomain: 'serve.zone/runtime-network-handoff-lease',
|
|
51
49
|
maximumPrefixes: 128,
|
|
52
50
|
maximumPools: 64,
|
|
53
51
|
maximumResolvers: 16,
|
|
@@ -101,12 +99,12 @@ const digest = (value: unknown): TSha256Digest => {
|
|
|
101
99
|
requireValue(typeof value === 'string' && /^sha256:[a-f0-9]{64}$/.test(value));
|
|
102
100
|
return value as TSha256Digest;
|
|
103
101
|
};
|
|
104
|
-
const controller = (value: unknown):
|
|
102
|
+
const controller = (value: unknown): IRuntimeController => {
|
|
105
103
|
const item = record(value, ['kind', 'id', 'epoch']);
|
|
106
104
|
requireValue(item.kind === 'cloudly' || item.kind === 'onebox');
|
|
107
105
|
return { kind: item.kind, id: id(item.id), epoch: id(item.epoch) };
|
|
108
106
|
};
|
|
109
|
-
const reference = (value: unknown):
|
|
107
|
+
const reference = (value: unknown): IRuntimeAuthorityReference => {
|
|
110
108
|
const item = record(value, ['id', 'generation', 'digest']);
|
|
111
109
|
return { id: id(item.id), generation: integer(item.generation), digest: digest(item.digest) };
|
|
112
110
|
};
|
|
@@ -151,21 +149,20 @@ const canonical = (value: unknown): string => canonicalizeStrictJson(value, fail
|
|
|
151
149
|
const equals = (left: unknown, right: unknown): boolean => canonical(left) === canonical(right);
|
|
152
150
|
|
|
153
151
|
/** Structural snapshot only. Complete inventory, signatures and activation barriers are caller-owned. */
|
|
154
|
-
export const
|
|
155
|
-
const item = record(value, ['
|
|
152
|
+
export const snapshotRuntimeNetworkProtectedAuthority = (value: unknown): IRuntimeNetworkProtectedAuthority => safe(() => {
|
|
153
|
+
const item = record(value, ['id', 'generation', 'controller', 'previous', 'prefixes',
|
|
156
154
|
'pools', 'resolvers', 'platformEndpoints', 'egressAuthorities', 'digest']);
|
|
157
|
-
requireValue(item.schemaVersion === 1);
|
|
158
155
|
const identity = id(item.id), generation = integer(item.generation);
|
|
159
156
|
const previous = item.previous === null ? null : reference(item.previous);
|
|
160
157
|
requireValue(generation === 1 ? previous === null : previous?.id === identity && previous.generation === generation - 1);
|
|
161
|
-
const prefixes = sorted(list(item.prefixes,
|
|
158
|
+
const prefixes = sorted(list(item.prefixes, runtimeNetworkAuthorityContract.maximumPrefixes, networkPrefix), value => value);
|
|
162
159
|
requireValue(prefixes.length > 0);
|
|
163
160
|
nonoverlapping(prefixes);
|
|
164
161
|
const protectedPrefix = (value: string) => requireValue(prefixes.some(range => contains(range, value)));
|
|
165
|
-
const pools = sorted(list(item.pools,
|
|
162
|
+
const pools = sorted(list(item.pools, runtimeNetworkAuthorityContract.maximumPools, value => {
|
|
166
163
|
const pool = record(value, ['id', 'purpose', 'prefix']);
|
|
167
164
|
requireValue(pool.purpose === 'workload' || pool.purpose === 'transit');
|
|
168
|
-
const result:
|
|
165
|
+
const result: IRuntimeNetworkProtectedAuthority['pools'][number] = {
|
|
169
166
|
id: id(pool.id), purpose: pool.purpose, prefix: networkPrivatePrefix(pool.prefix),
|
|
170
167
|
};
|
|
171
168
|
protectedPrefix(result.prefix);
|
|
@@ -179,26 +176,25 @@ export const snapshotRuntimeNetworkProtectedAuthorityV1 = (value: unknown): IRun
|
|
|
179
176
|
requireValue(pools.every(pool => !contains(pool.prefix, `${result.address}/32`)));
|
|
180
177
|
return withProtocol ? { ...result, protocol: protocol(endpoint.protocol) } : result;
|
|
181
178
|
};
|
|
182
|
-
const resolvers = sorted(list(item.resolvers,
|
|
179
|
+
const resolvers = sorted(list(item.resolvers, runtimeNetworkAuthorityContract.maximumResolvers,
|
|
183
180
|
value => readEndpoint(value, false)), value => value.id);
|
|
184
|
-
const platformEndpoints = sorted(list(item.platformEndpoints,
|
|
185
|
-
value => readEndpoint(value, true) as
|
|
181
|
+
const platformEndpoints = sorted(list(item.platformEndpoints, runtimeNetworkAuthorityContract.maximumPlatformEndpoints,
|
|
182
|
+
value => readEndpoint(value, true) as IRuntimeNetworkProtectedAuthority['platformEndpoints'][number]), value => value.id);
|
|
186
183
|
const allEndpointKeys = [...resolvers.flatMap(value => ['tcp', 'udp'].map(transport => `${value.address}:${value.port}:${transport}`)),
|
|
187
184
|
...platformEndpoints.map(value => `${value.address}:${value.port}:${value.protocol}`)];
|
|
188
185
|
requireValue(new Set(allEndpointKeys).size === allEndpointKeys.length);
|
|
189
|
-
const egressAuthorities = sorted(list(item.egressAuthorities,
|
|
186
|
+
const egressAuthorities = sorted(list(item.egressAuthorities, runtimeNetworkAuthorityContract.maximumEgressAuthorities, value => {
|
|
190
187
|
const authority = record(value, ['nodeId', 'runtimeNamespace']);
|
|
191
188
|
return { nodeId: id(authority.nodeId), runtimeNamespace: id(authority.runtimeNamespace) };
|
|
192
189
|
}), value => canonical([value.nodeId, value.runtimeNamespace]));
|
|
193
190
|
requireValue(egressAuthorities.length > 0);
|
|
194
|
-
return {
|
|
191
|
+
return { id: identity, generation, controller: controller(item.controller), previous,
|
|
195
192
|
prefixes, pools, resolvers, platformEndpoints, egressAuthorities, digest: digest(item.digest) };
|
|
196
193
|
});
|
|
197
194
|
|
|
198
|
-
export const
|
|
199
|
-
const item = record(value, ['
|
|
195
|
+
export const snapshotRuntimeNetworkHandoffLease = (value: unknown): IRuntimeNetworkHandoffLease => safe(() => {
|
|
196
|
+
const item = record(value, ['id', 'generation', 'controller', 'nodeId', 'runtimeNamespace',
|
|
200
197
|
'protectedAuthority', 'routerIncarnationId', 'transit', 'sourcePortRanges', 'conntrackZone', 'conntrackLabel', 'digest']);
|
|
201
|
-
requireValue(item.schemaVersion === 1);
|
|
202
198
|
const transit = record(item.transit, ['poolId', 'prefix', 'routerAddress', 'hostAddress']);
|
|
203
199
|
const transitPrefix = networkPrivatePrefix(transit.prefix), [first, last] = bounds(transitPrefix);
|
|
204
200
|
const routerAddress = endpointAddress(transit.routerAddress), hostAddress = endpointAddress(transit.hostAddress);
|
|
@@ -207,7 +203,7 @@ export const snapshotRuntimeNetworkHandoffLeaseV1 = (value: unknown): IRuntimeNe
|
|
|
207
203
|
const number = numericAddress(value);
|
|
208
204
|
requireValue(number >= first && number <= last && (last - first === 1 || (number !== first && number !== last)));
|
|
209
205
|
}
|
|
210
|
-
const sourcePortRanges = list(item.sourcePortRanges,
|
|
206
|
+
const sourcePortRanges = list(item.sourcePortRanges, runtimeNetworkAuthorityContract.maximumPortRanges, value => {
|
|
211
207
|
const range = record(value, ['protocol', 'first', 'last']);
|
|
212
208
|
const result = { protocol: protocol(range.protocol), first: integer(range.first, 65535), last: integer(range.last, 65535) };
|
|
213
209
|
requireValue(result.first <= result.last);
|
|
@@ -220,7 +216,7 @@ export const snapshotRuntimeNetworkHandoffLeaseV1 = (value: unknown): IRuntimeNe
|
|
|
220
216
|
}
|
|
221
217
|
requireValue(typeof item.conntrackLabel === 'string' && /^[a-f0-9]{32}$/.test(item.conntrackLabel)
|
|
222
218
|
&& item.conntrackLabel !== '0'.repeat(32));
|
|
223
|
-
return {
|
|
219
|
+
return { id: id(item.id), generation: integer(item.generation), controller: controller(item.controller),
|
|
224
220
|
nodeId: id(item.nodeId), runtimeNamespace: id(item.runtimeNamespace), protectedAuthority: reference(item.protectedAuthority),
|
|
225
221
|
routerIncarnationId: id(item.routerIncarnationId), transit: { poolId: id(transit.poolId), prefix: transitPrefix, routerAddress, hostAddress },
|
|
226
222
|
sourcePortRanges, conntrackZone: integer(item.conntrackZone, 65535), conntrackLabel: item.conntrackLabel, digest: digest(item.digest) };
|
|
@@ -230,19 +226,19 @@ const computeDigest = async (domain: string, value: { digest: TSha256Digest }):
|
|
|
230
226
|
const { digest: omitted, ...payload } = value;
|
|
231
227
|
return `sha256:${await createCanonicalJsonSha256Hex(canonical({ domain, payload }), fail)}`;
|
|
232
228
|
};
|
|
233
|
-
export const
|
|
234
|
-
computeDigest(
|
|
235
|
-
export const
|
|
236
|
-
computeDigest(
|
|
229
|
+
export const computeRuntimeNetworkProtectedAuthorityDigest = (value: IRuntimeNetworkProtectedAuthority): Promise<TSha256Digest> =>
|
|
230
|
+
computeDigest(runtimeNetworkAuthorityContract.protectedDigestDomain, snapshotRuntimeNetworkProtectedAuthority(value));
|
|
231
|
+
export const computeRuntimeNetworkHandoffLeaseDigest = (value: IRuntimeNetworkHandoffLease): Promise<TSha256Digest> =>
|
|
232
|
+
computeDigest(runtimeNetworkAuthorityContract.handoffDigestDomain, snapshotRuntimeNetworkHandoffLease(value));
|
|
237
233
|
|
|
238
234
|
/** Detached, digest-verified allocation binding. Does not establish pool activation or live link identity. */
|
|
239
|
-
export const
|
|
240
|
-
lease:
|
|
235
|
+
export const bindRuntimeNetworkHandoffLease = async (leaseValue: unknown, authorityValue: unknown): Promise<{
|
|
236
|
+
lease: IRuntimeNetworkHandoffLease; authority: IRuntimeNetworkProtectedAuthority;
|
|
241
237
|
}> => {
|
|
242
|
-
const lease =
|
|
243
|
-
const authority =
|
|
244
|
-
requireValue(lease.digest === await
|
|
245
|
-
requireValue(authority.digest === await
|
|
238
|
+
const lease = snapshotRuntimeNetworkHandoffLease(leaseValue);
|
|
239
|
+
const authority = snapshotRuntimeNetworkProtectedAuthority(authorityValue);
|
|
240
|
+
requireValue(lease.digest === await computeRuntimeNetworkHandoffLeaseDigest(lease));
|
|
241
|
+
requireValue(authority.digest === await computeRuntimeNetworkProtectedAuthorityDigest(authority));
|
|
246
242
|
requireValue(equals(lease.controller, authority.controller)
|
|
247
243
|
&& equals(lease.protectedAuthority, { id: authority.id, generation: authority.generation, digest: authority.digest })
|
|
248
244
|
&& authority.egressAuthorities.some(value => value.nodeId === lease.nodeId && value.runtimeNamespace === lease.runtimeNamespace));
|
|
@@ -256,12 +252,12 @@ export const bindRuntimeNetworkHandoffLeaseV1 = async (leaseValue: unknown, auth
|
|
|
256
252
|
* The owning transactional ledger must supply its complete history and serialize reservations.
|
|
257
253
|
* Namespace replacement, an empty CT dump or process exit never removes an entry from this set.
|
|
258
254
|
*/
|
|
259
|
-
export const
|
|
260
|
-
const leases = safe(() => list(value,
|
|
261
|
-
|
|
255
|
+
export const snapshotRuntimeNetworkHandoffLedger = async (value: unknown): Promise<IRuntimeNetworkHandoffLease[]> => {
|
|
256
|
+
const leases = safe(() => list(value, runtimeNetworkAuthorityContract.maximumRetainedHandoffLeases,
|
|
257
|
+
snapshotRuntimeNetworkHandoffLease));
|
|
262
258
|
for (let index = 0; index < leases.length; index++) {
|
|
263
259
|
const lease = leases[index];
|
|
264
|
-
requireValue(lease.digest === await
|
|
260
|
+
requireValue(lease.digest === await computeRuntimeNetworkHandoffLeaseDigest(lease));
|
|
265
261
|
for (let other = 0; other < index; other++) {
|
|
266
262
|
const previous = leases[other];
|
|
267
263
|
requireValue(lease.nodeId === previous.nodeId && equals(lease.controller, previous.controller));
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { IRuntimeAuthorityReference } from './runtimeassignment.js';
|
|
2
|
+
import { snapshotRuntimeSessionBinding, type IRuntimeSessionBinding } from './runtimesession.js';
|
|
3
|
+
import { validateRuntimeNetworkProjection, type IRuntimeNetworkProjection } from './networkprojection.js';
|
|
4
4
|
import { snapshotRuntimeNetworkDnsLeaseRenewal, validateRuntimeNetworkDnsLeaseRenewal } from './networklease.js';
|
|
5
5
|
import { captureNetwork, failNetwork, networkCounter, networkEffectiveDnsWindow, networkEqual, networkId, networkIpv4,
|
|
6
6
|
networkRecord, networkReference, networkReferenceOf, networkSafe, networkSameScope, requireNetwork } from '../private/networkcontract.js';
|
|
7
7
|
|
|
8
|
-
export interface
|
|
9
|
-
session:
|
|
10
|
-
projection:
|
|
8
|
+
export interface IGetRuntimeManagedVpnCredentialRequest {
|
|
9
|
+
session: IRuntimeSessionBinding;
|
|
10
|
+
projection: IRuntimeAuthorityReference;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/** Secret response over the current authenticated physical peer only. Never
|
|
14
14
|
* persist, hash, log, or include it in a signed network projection. The native
|
|
15
15
|
* Noise owner validates and uses the keys; these shapes confer no TUN readiness. */
|
|
16
|
-
export interface
|
|
16
|
+
export interface IGetRuntimeManagedVpnCredentialResponse extends IGetRuntimeManagedVpnCredentialRequest {
|
|
17
17
|
transport: 'quic';
|
|
18
18
|
relay: { id: string; address: string; port: number };
|
|
19
19
|
authorityId: string;
|
|
@@ -36,35 +36,35 @@ const key = (value: unknown): string => {
|
|
|
36
36
|
return value;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
export const
|
|
39
|
+
export const snapshotGetRuntimeManagedVpnCredentialRequest = (value: unknown): IGetRuntimeManagedVpnCredentialRequest => networkSafe(() => {
|
|
40
40
|
const item = networkRecord(captureNetwork(value), ['session', 'projection']);
|
|
41
|
-
return { session:
|
|
41
|
+
return { session: snapshotRuntimeSessionBinding(item.session), projection: networkReference(item.projection) };
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
export const
|
|
44
|
+
export const snapshotGetRuntimeManagedVpnCredentialResponse = (value: unknown): IGetRuntimeManagedVpnCredentialResponse => networkSafe(() => {
|
|
45
45
|
const item = networkRecord(captureNetwork(value), ['session', 'projection', 'transport', 'relay', 'authorityId',
|
|
46
46
|
'serverPublicKey', 'clientPublicKey', 'clientPrivateKey', 'expiresAt']);
|
|
47
47
|
const relay = networkRecord(item.relay, ['id', 'address', 'port']); requireNetwork(item.transport === 'quic');
|
|
48
|
-
return { session:
|
|
48
|
+
return { session: snapshotRuntimeSessionBinding(item.session), projection: networkReference(item.projection), transport: 'quic',
|
|
49
49
|
relay: { id: networkId(relay.id), address: networkIpv4(relay.address), port: networkCounter(relay.port, 65535) },
|
|
50
50
|
authorityId: networkId(item.authorityId), serverPublicKey: key(item.serverPublicKey), clientPublicKey: key(item.clientPublicKey),
|
|
51
51
|
clientPrivateKey: key(item.clientPrivateKey), expiresAt: networkCounter(item.expiresAt) };
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
const bindRequest = (request:
|
|
55
|
-
projection:
|
|
54
|
+
const bindRequest = (request: IGetRuntimeManagedVpnCredentialRequest,
|
|
55
|
+
projection: IRuntimeNetworkProjection, trusted: IRuntimeSessionBinding): void => {
|
|
56
56
|
requireNetwork(networkEqual(request.session, trusted) && networkEqual(request.projection, networkReferenceOf(projection))
|
|
57
57
|
&& networkSameScope(projection, trusted) && projection.handoff);
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
/** Content binding only. The caller must resolve the exact current projection
|
|
61
61
|
* and authenticate/fence the current physical peer before and after native work. */
|
|
62
|
-
export const
|
|
63
|
-
trustedSessionValue: unknown): Promise<
|
|
62
|
+
export const bindGetRuntimeManagedVpnCredentialRequest = async (value: unknown, projectionValue: unknown,
|
|
63
|
+
trustedSessionValue: unknown): Promise<IGetRuntimeManagedVpnCredentialRequest> => {
|
|
64
64
|
try {
|
|
65
|
-
const request =
|
|
66
|
-
const trusted =
|
|
67
|
-
const projection = await
|
|
65
|
+
const request = snapshotGetRuntimeManagedVpnCredentialRequest(value);
|
|
66
|
+
const trusted = snapshotRuntimeSessionBinding(trustedSessionValue);
|
|
67
|
+
const projection = await validateRuntimeNetworkProjection(projectionValue);
|
|
68
68
|
bindRequest(request, projection, trusted);
|
|
69
69
|
return request;
|
|
70
70
|
} catch { return failNetwork(); }
|
|
@@ -76,15 +76,15 @@ export const bindGetRuntimeManagedVpnCredentialRequestV1 = async (value: unknown
|
|
|
76
76
|
* projection, or null; this helper verifies no signature. Time is caller-qualified;
|
|
77
77
|
* this helper does not sample a clock, authenticate a transport, admit policy or
|
|
78
78
|
* prove a running managed connection. */
|
|
79
|
-
export const
|
|
79
|
+
export const bindGetRuntimeManagedVpnCredentialResponse = async (value: unknown, requestValue: unknown,
|
|
80
80
|
projectionValue: unknown, trustedSessionValue: unknown, nowValue: unknown,
|
|
81
|
-
renewalValue: unknown | null = null): Promise<
|
|
81
|
+
renewalValue: unknown | null = null): Promise<IGetRuntimeManagedVpnCredentialResponse> => {
|
|
82
82
|
try {
|
|
83
|
-
const response =
|
|
84
|
-
const request =
|
|
85
|
-
const trusted =
|
|
83
|
+
const response = snapshotGetRuntimeManagedVpnCredentialResponse(value);
|
|
84
|
+
const request = snapshotGetRuntimeManagedVpnCredentialRequest(requestValue);
|
|
85
|
+
const trusted = snapshotRuntimeSessionBinding(trustedSessionValue), now = networkCounter(nowValue);
|
|
86
86
|
const renewalInput = renewalValue === null ? null : snapshotRuntimeNetworkDnsLeaseRenewal(renewalValue);
|
|
87
|
-
const projection = await
|
|
87
|
+
const projection = await validateRuntimeNetworkProjection(projectionValue);
|
|
88
88
|
const renewal = renewalInput === null ? null : await validateRuntimeNetworkDnsLeaseRenewal(renewalInput);
|
|
89
89
|
const window = networkEffectiveDnsWindow(projection, renewal);
|
|
90
90
|
bindRequest(request, projection, trusted);
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
5
|
-
import {
|
|
1
|
+
import type { IRuntimeAuthorityReference } from './runtimeassignment.js';
|
|
2
|
+
import type { IRuntimeSessionBinding } from './runtimesession.js';
|
|
3
|
+
import { snapshotRuntimeSessionBinding } from './runtimesession.js';
|
|
4
|
+
import type { IRuntimeNetworkSigningAuthority, ISignedRuntimeNetworkProjection } from './networksigning.js';
|
|
5
|
+
import { snapshotRuntimeNetworkSigningAuthority, snapshotSignedRuntimeNetworkProjection } from './networksigning.js';
|
|
6
6
|
import type { IRuntimeNetworkDnsLeaseRenewalReference, ISignedRuntimeNetworkDnsLeaseRenewal } from './networklease.js';
|
|
7
7
|
import { getRuntimeNetworkDnsLeaseRenewalReference, snapshotRuntimeNetworkDnsLeaseRenewal,
|
|
8
8
|
snapshotRuntimeNetworkDnsLeaseRenewalReference, snapshotSignedRuntimeNetworkDnsLeaseRenewal } from './networklease.js';
|
|
9
9
|
import { captureNetwork, networkEqual, networkRecord, networkReference, networkReferenceOf, networkSafe, networkSameScope,
|
|
10
10
|
requireNetwork } from '../private/networkcontract.js';
|
|
11
11
|
|
|
12
|
-
export interface
|
|
13
|
-
session:
|
|
14
|
-
authority:
|
|
12
|
+
export interface IApplyRuntimeNetworkSigningAuthorityRequest {
|
|
13
|
+
session: IRuntimeSessionBinding;
|
|
14
|
+
authority: IRuntimeNetworkSigningAuthority;
|
|
15
15
|
}
|
|
16
|
-
export interface
|
|
17
|
-
session:
|
|
18
|
-
signed:
|
|
16
|
+
export interface IApplyRuntimeNetworkProjectionRequest {
|
|
17
|
+
session: IRuntimeSessionBinding;
|
|
18
|
+
signed: ISignedRuntimeNetworkProjection;
|
|
19
19
|
}
|
|
20
20
|
/** Durable admission only. No packet, DNS, pool-activation, fencing or readiness assertion. */
|
|
21
|
-
export interface
|
|
21
|
+
export interface IApplyRuntimeNetworkAuthorityResponse {
|
|
22
22
|
status: 'accepted' | 'replay';
|
|
23
|
-
authority:
|
|
23
|
+
authority: IRuntimeAuthorityReference;
|
|
24
24
|
}
|
|
25
25
|
export interface IApplyRuntimeNetworkDnsLeaseRenewalRequest {
|
|
26
|
-
session:
|
|
26
|
+
session: IRuntimeSessionBinding;
|
|
27
27
|
signed: ISignedRuntimeNetworkDnsLeaseRenewal;
|
|
28
28
|
}
|
|
29
29
|
/** Durable admission only. It does not assert that the node converted the window or serves DNS. */
|
|
@@ -36,22 +36,22 @@ const admissionStatus = (value: unknown): 'accepted' | 'replay' => {
|
|
|
36
36
|
requireNetwork(value === 'accepted' || value === 'replay'); return value;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
export const
|
|
39
|
+
export const snapshotApplyRuntimeNetworkSigningAuthorityRequest = (value: unknown): IApplyRuntimeNetworkSigningAuthorityRequest => networkSafe(() => {
|
|
40
40
|
const item = networkRecord(captureNetwork(value), ['session', 'authority']);
|
|
41
|
-
return { session:
|
|
41
|
+
return { session: snapshotRuntimeSessionBinding(item.session), authority: snapshotRuntimeNetworkSigningAuthority(item.authority) };
|
|
42
42
|
});
|
|
43
|
-
export const
|
|
43
|
+
export const snapshotApplyRuntimeNetworkProjectionRequest = (value: unknown): IApplyRuntimeNetworkProjectionRequest => networkSafe(() => {
|
|
44
44
|
const item = networkRecord(captureNetwork(value), ['session', 'signed']);
|
|
45
|
-
return { session:
|
|
45
|
+
return { session: snapshotRuntimeSessionBinding(item.session), signed: snapshotSignedRuntimeNetworkProjection(item.signed) };
|
|
46
46
|
});
|
|
47
|
-
export const
|
|
47
|
+
export const snapshotApplyRuntimeNetworkAuthorityResponse = (value: unknown): IApplyRuntimeNetworkAuthorityResponse => networkSafe(() => {
|
|
48
48
|
const item = networkRecord(captureNetwork(value), ['status', 'authority']);
|
|
49
49
|
return { status: admissionStatus(item.status), authority: networkReference(item.authority) };
|
|
50
50
|
});
|
|
51
51
|
|
|
52
52
|
export const snapshotApplyRuntimeNetworkDnsLeaseRenewalRequest = (value: unknown): IApplyRuntimeNetworkDnsLeaseRenewalRequest => networkSafe(() => {
|
|
53
53
|
const item = networkRecord(captureNetwork(value), ['session', 'signed']);
|
|
54
|
-
return { session:
|
|
54
|
+
return { session: snapshotRuntimeSessionBinding(item.session), signed: snapshotSignedRuntimeNetworkDnsLeaseRenewal(item.signed) };
|
|
55
55
|
});
|
|
56
56
|
export const snapshotApplyRuntimeNetworkDnsLeaseRenewalResponse = (value: unknown): IApplyRuntimeNetworkDnsLeaseRenewalResponse => networkSafe(() => {
|
|
57
57
|
const item = networkRecord(captureNetwork(value), ['status', 'renewal']);
|
|
@@ -59,22 +59,22 @@ export const snapshotApplyRuntimeNetworkDnsLeaseRenewalResponse = (value: unknow
|
|
|
59
59
|
});
|
|
60
60
|
|
|
61
61
|
/** trustedSessionValue must come from the receiving CURRENT physical connection. */
|
|
62
|
-
export const
|
|
63
|
-
const request =
|
|
62
|
+
export const bindApplyRuntimeNetworkSigningAuthorityRequest = (value: unknown, trustedSessionValue: unknown): IApplyRuntimeNetworkSigningAuthorityRequest => networkSafe(() => {
|
|
63
|
+
const request = snapshotApplyRuntimeNetworkSigningAuthorityRequest(value), session = snapshotRuntimeSessionBinding(trustedSessionValue);
|
|
64
64
|
requireNetwork(networkEqual(request.session, session) && networkEqual(request.authority.controller, session.controller));
|
|
65
65
|
return request;
|
|
66
66
|
});
|
|
67
67
|
|
|
68
68
|
/** Content binding only. Verify signature with stored trust and atomically fence admission. */
|
|
69
|
-
export const
|
|
70
|
-
const request =
|
|
69
|
+
export const bindApplyRuntimeNetworkProjectionRequest = (value: unknown, trustedSessionValue: unknown): IApplyRuntimeNetworkProjectionRequest => networkSafe(() => {
|
|
70
|
+
const request = snapshotApplyRuntimeNetworkProjectionRequest(value), session = snapshotRuntimeSessionBinding(trustedSessionValue);
|
|
71
71
|
requireNetwork(networkEqual(request.session, session) && networkSameScope(request.signed.projection, session));
|
|
72
72
|
return request;
|
|
73
73
|
});
|
|
74
74
|
|
|
75
75
|
/** Compare ACK with the exact SENT key or projection reference, never with a response-derived value. */
|
|
76
|
-
export const
|
|
77
|
-
const response =
|
|
76
|
+
export const bindApplyRuntimeNetworkAuthorityResponse = (value: unknown, sentReferenceValue: unknown): IApplyRuntimeNetworkAuthorityResponse => networkSafe(() => {
|
|
77
|
+
const response = snapshotApplyRuntimeNetworkAuthorityResponse(value);
|
|
78
78
|
const expected = networkReference(captureNetwork(sentReferenceValue));
|
|
79
79
|
requireNetwork(networkEqual(response.authority, networkReferenceOf(expected)));
|
|
80
80
|
return response;
|
|
@@ -87,7 +87,7 @@ export const bindApplyRuntimeNetworkAuthorityResponseV1 = (value: unknown, sentR
|
|
|
87
87
|
* stored trust, then admit and fence atomically.
|
|
88
88
|
*/
|
|
89
89
|
export const bindApplyRuntimeNetworkDnsLeaseRenewalRequest = (value: unknown, trustedSessionValue: unknown): IApplyRuntimeNetworkDnsLeaseRenewalRequest => networkSafe(() => {
|
|
90
|
-
const request = snapshotApplyRuntimeNetworkDnsLeaseRenewalRequest(value), session =
|
|
90
|
+
const request = snapshotApplyRuntimeNetworkDnsLeaseRenewalRequest(value), session = snapshotRuntimeSessionBinding(trustedSessionValue);
|
|
91
91
|
requireNetwork(networkEqual(request.session, session) && networkSameScope(request.signed.renewal, session));
|
|
92
92
|
return request;
|
|
93
93
|
});
|
package/ts/data/networklease.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { TSha256Digest } from './immutableimage.js';
|
|
2
|
-
import type {
|
|
3
|
-
import type { IRuntimeNetworkDnsWindow,
|
|
4
|
-
import {
|
|
2
|
+
import type { IRuntimeAuthorityReference } from './runtimeassignment.js';
|
|
3
|
+
import type { IRuntimeNetworkDnsWindow, IRuntimeNetworkNodeScope } from './networkprojection.js';
|
|
4
|
+
import { snapshotRuntimeNetworkNodeScope, snapshotRuntimeNetworkProjection, validateRuntimeNetworkProjection } from './networkprojection.js';
|
|
5
5
|
import { captureNetwork, failNetwork, networkCounter, networkDigest, networkDnsWindow, networkEffectiveDnsWindow, networkEqual,
|
|
6
6
|
networkHash, networkId, networkList, networkMaximumDnsLeaseMs, networkRecord, networkReference, networkReferenceOf,
|
|
7
7
|
networkRenewsProjection, networkSafe, networkSameScope, networkScope, networkSignature, requireNetwork } from '../private/networkcontract.js';
|
|
@@ -15,8 +15,8 @@ import { captureNetwork, failNetwork, networkCounter, networkDigest, networkDnsW
|
|
|
15
15
|
* projection by exact reference, so it never joins the projection chain and stops being
|
|
16
16
|
* admissible the moment a successor projection is admitted.
|
|
17
17
|
*/
|
|
18
|
-
export interface IRuntimeNetworkDnsLeaseRenewal extends
|
|
19
|
-
projection:
|
|
18
|
+
export interface IRuntimeNetworkDnsLeaseRenewal extends IRuntimeNetworkNodeScope {
|
|
19
|
+
projection: IRuntimeAuthorityReference;
|
|
20
20
|
/** Orders the renewals of one projection. A receiver may skip sequences, never go back. */
|
|
21
21
|
sequence: number;
|
|
22
22
|
/**
|
|
@@ -29,14 +29,14 @@ export interface IRuntimeNetworkDnsLeaseRenewal extends IRuntimeNetworkNodeScope
|
|
|
29
29
|
|
|
30
30
|
/** Names one renewal without its window: what a receiver records and what an ACK repeats. */
|
|
31
31
|
export interface IRuntimeNetworkDnsLeaseRenewalReference {
|
|
32
|
-
projection:
|
|
32
|
+
projection: IRuntimeAuthorityReference;
|
|
33
33
|
sequence: number;
|
|
34
34
|
digest: TSha256Digest;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export interface ISignedRuntimeNetworkDnsLeaseRenewal {
|
|
38
38
|
/** The signing authority revision that also signs this controller's projections. */
|
|
39
|
-
authority:
|
|
39
|
+
authority: IRuntimeAuthorityReference;
|
|
40
40
|
renewal: IRuntimeNetworkDnsLeaseRenewal;
|
|
41
41
|
/** Ed25519 signature of the complete domain-separated envelope, lowercase hex. */
|
|
42
42
|
signature: string;
|
|
@@ -51,7 +51,7 @@ export interface ISignedRuntimeNetworkDnsLeaseRenewal {
|
|
|
51
51
|
export interface IHoldRuntimeNetworkDnsLeaseRenewalsRequest {
|
|
52
52
|
/** The relay's own socket names the cluster; one relay carries every node of it, so the node is named here. */
|
|
53
53
|
nodeId: string;
|
|
54
|
-
projection:
|
|
54
|
+
projection: IRuntimeAuthorityReference;
|
|
55
55
|
/** Ascending by sequence. Empty holds nothing for this node. */
|
|
56
56
|
renewals: ISignedRuntimeNetworkDnsLeaseRenewal[];
|
|
57
57
|
}
|
|
@@ -75,6 +75,33 @@ export const runtimeNetworkDnsLeaseRenewalContract = Object.freeze({
|
|
|
75
75
|
revocationLatency: 'a-detached-cluster-keeps-dns-authority-until-its-last-held-window-ends',
|
|
76
76
|
} as const);
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Every reason a relay refuses to hold a run, in the words the refusal leads with.
|
|
80
|
+
*
|
|
81
|
+
* A hold is the one call whose outcome a controller cannot read back from its own records: the
|
|
82
|
+
* run lives in the relay's memory, so the refusal is the only statement about whether that node's
|
|
83
|
+
* windows are carried. The relay writes `<name>: <reason>` and the controller matches the name,
|
|
84
|
+
* which is why the names are stated here instead of being spelled out on both sides.
|
|
85
|
+
*/
|
|
86
|
+
export const holdRuntimeNetworkDnsLeaseRenewalsRefusals = Object.freeze([
|
|
87
|
+
/** The run itself is not a valid one, so nothing of it was held. */
|
|
88
|
+
'escrow-run-invalid',
|
|
89
|
+
/** This relay carries no session for that node; its renewals were not held. */
|
|
90
|
+
'escrow-node-not-carried',
|
|
91
|
+
/** The node's session changed while the run waited, so the run is for a session that is gone. */
|
|
92
|
+
'escrow-run-foreign-session',
|
|
93
|
+
/** The relay already holds a run that is provably newer for the same projection. */
|
|
94
|
+
'escrow-run-stale',
|
|
95
|
+
/** The run renews a projection that cannot be ordered against the held one. */
|
|
96
|
+
'escrow-run-unordered',
|
|
97
|
+
/** A node reached this method: a run is held only for the controller, over the relay's session. */
|
|
98
|
+
'escrow-cloudly-only',
|
|
99
|
+
] as const);
|
|
100
|
+
|
|
101
|
+
/** One of the reasons a relay answers instead of holding a run. */
|
|
102
|
+
export type THoldRuntimeNetworkDnsLeaseRenewalsRefusal =
|
|
103
|
+
typeof holdRuntimeNetworkDnsLeaseRenewalsRefusals[number];
|
|
104
|
+
|
|
78
105
|
export const snapshotRuntimeNetworkDnsLeaseRenewal = (value: unknown): IRuntimeNetworkDnsLeaseRenewal => networkSafe(() => {
|
|
79
106
|
const item = networkRecord(captureNetwork(value), ['controller', 'nodeId', 'runtimeNamespace', 'projection', 'sequence', 'dns', 'digest']);
|
|
80
107
|
return { ...networkScope(item), projection: networkReference(item.projection), sequence: networkCounter(item.sequence),
|
|
@@ -130,9 +157,9 @@ export const getRuntimeNetworkEffectiveDnsWindow = async (
|
|
|
130
157
|
projectionValue: unknown, renewalValue: unknown | null,
|
|
131
158
|
): Promise<IRuntimeNetworkDnsWindow> => {
|
|
132
159
|
try {
|
|
133
|
-
const projectionInput =
|
|
160
|
+
const projectionInput = snapshotRuntimeNetworkProjection(projectionValue);
|
|
134
161
|
const renewalInput = renewalValue === null ? null : snapshotRuntimeNetworkDnsLeaseRenewal(renewalValue);
|
|
135
|
-
const projection = await
|
|
162
|
+
const projection = await validateRuntimeNetworkProjection(projectionInput);
|
|
136
163
|
const renewal = renewalInput === null ? null : await validateRuntimeNetworkDnsLeaseRenewal(renewalInput);
|
|
137
164
|
return networkEffectiveDnsWindow(projection, renewal);
|
|
138
165
|
} catch { return failNetwork(); }
|
|
@@ -158,12 +185,12 @@ export const admitRuntimeNetworkDnsLeaseRenewal = async (
|
|
|
158
185
|
try {
|
|
159
186
|
// Snapshot ALL caller-owned inputs before the first asynchronous operation.
|
|
160
187
|
const incoming = snapshotRuntimeNetworkDnsLeaseRenewal(value);
|
|
161
|
-
const projectionInput =
|
|
188
|
+
const projectionInput = snapshotRuntimeNetworkProjection(currentProjectionValue);
|
|
162
189
|
const previousInput = previousValue === null ? null : snapshotRuntimeNetworkDnsLeaseRenewal(previousValue);
|
|
163
|
-
const trusted =
|
|
190
|
+
const trusted = snapshotRuntimeNetworkNodeScope(trustedScopeValue);
|
|
164
191
|
const now = networkCounter(nowValue);
|
|
165
192
|
const renewal = await validateRuntimeNetworkDnsLeaseRenewal(incoming);
|
|
166
|
-
const projection = await
|
|
193
|
+
const projection = await validateRuntimeNetworkProjection(projectionInput);
|
|
167
194
|
requireNetwork(networkSameScope(projection, trusted) && networkRenewsProjection(renewal, projection));
|
|
168
195
|
const previous = previousInput === null ? null : await validateRuntimeNetworkDnsLeaseRenewal(previousInput);
|
|
169
196
|
if (previous !== null) {
|
package/ts/data/networknode.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { IRuntimeNetworkProtectedAuthority } from './networkauthority.js';
|
|
2
2
|
import { captureNetwork, networkCounter, networkId, networkRecord, networkSafe } from '../private/networkcontract.js';
|
|
3
3
|
|
|
4
|
-
type TEgressOwner =
|
|
4
|
+
type TEgressOwner = IRuntimeNetworkProtectedAuthority['egressAuthorities'][number];
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* One unmet condition of a node's runtime network readiness, in the order the node producer meets
|