querysub 0.489.0 → 0.491.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.
Files changed (41) hide show
  1. package/.claude/settings.local.json +5 -1
  2. package/package.json +2 -1
  3. package/src/-b-authorities/dnsAuthority.ts +80 -42
  4. package/src/-c-identity/IdentityController.ts +13 -12
  5. package/src/-d-trust/NetworkTrust2.ts +6 -6
  6. package/src/-e-certs/EdgeCertController.ts +4 -4
  7. package/src/-e-certs/certAuthority.ts +13 -3
  8. package/src/-f-node-discovery/NodeDiscovery.ts +10 -10
  9. package/src/-g-core-values/NodeCapabilities.ts +4 -3
  10. package/src/-h-path-value-serialize/PathValueSerializer.ts +4 -3
  11. package/src/0-path-value-core/PathValueCommitter.ts +5 -4
  12. package/src/0-path-value-core/PathValueController.ts +4 -4
  13. package/src/0-path-value-core/archiveLocks/ArchiveLocks2.ts +3 -3
  14. package/src/0-path-value-core/pathValueArchives.ts +4 -4
  15. package/src/0-path-value-core/pathValueCore.ts +2 -0
  16. package/src/1-path-client/pathValueClientWatcher.ts +3 -3
  17. package/src/2-proxy/PathValueProxyWatcher.ts +1 -1
  18. package/src/3-path-functions/PathFunctionHelpers.ts +2 -2
  19. package/src/3-path-functions/PathFunctionRunnerMain.ts +1 -1
  20. package/src/3-path-functions/tests/rejectTest.ts +3 -2
  21. package/src/4-deploy/deployGetFunctionsInner.ts +2 -2
  22. package/src/4-deploy/edgeNodes.ts +3 -3
  23. package/src/4-querysub/Querysub.ts +14 -10
  24. package/src/4-querysub/querysubPrediction.ts +0 -11
  25. package/src/deployManager/components/ServiceDetailPage.tsx +1 -1
  26. package/src/deployManager/machineApplyMainCode.ts +4 -4
  27. package/src/deployManager/machineSchema.ts +1 -1
  28. package/src/diagnostics/MachineThreadInfo.tsx +3 -2
  29. package/src/diagnostics/NodeViewer.tsx +7 -1
  30. package/src/diagnostics/logs/IndexedLogs/IndexedLogs.ts +2 -2
  31. package/src/diagnostics/logs/IndexedLogs/MCPIndexedLogs.ts +3 -2
  32. package/src/diagnostics/logs/diskLogGlobalContext.ts +4 -3
  33. package/src/diagnostics/misc-pages/DNSPage.tsx +16 -6
  34. package/src/diagnostics/pathAuditer.ts +4 -4
  35. package/src/diagnostics/watchdog.ts +1 -1
  36. package/src/server.ts +1 -1
  37. package/src/user-implementation/UserPage.tsx +4 -3
  38. package/test.ts +8 -50
  39. package/testEntry2.ts +1 -1
  40. package/tsconfig.json +14 -1
  41. package/src/-a-auth/certs.ts +0 -541
@@ -8,9 +8,9 @@ import { pathValueSerializer } from "../-h-path-value-serialize/PathValueSeriali
8
8
  import debugbreak from "debugbreak";
9
9
  import { formatNumber, formatTime } from "socket-function/src/formatting/format";
10
10
  import { list } from "socket-function/src/misc";
11
- import { NodeIdParts, decodeNodeId, decodeNodeIdAssert, encodeNodeId } from "../-a-auth/certs";
11
+ import { NodeIdParts, decodeNodeId, decodeNodeIdAssert, encodeNodeId } from "sliftutils/misc/https/certs";
12
12
  import { createArchiveLocker2 } from "./archiveLocks/ArchiveLocks2";
13
- import { devDebugbreak, isNoNetwork } from "../config";
13
+ import { devDebugbreak, isNoNetwork, getDomain } from "../config";
14
14
  import { wrapArchivesWithCache } from "../-a-archives/archiveCache";
15
15
  import { AuthoritySpec, PathRouter, debugSpec } from "./PathRouter";
16
16
  import { authorityLookup } from "./AuthorityLookup";
@@ -86,7 +86,7 @@ export class PathValueArchives {
86
86
  let parts = fileName.split("_");
87
87
  if (parts[0] !== "data") return defaultDecodedValuePath(dataPath);
88
88
  let nodeId = parts[1];
89
- let decodedNodeId = decodeNodeId(nodeId);
89
+ let decodedNodeId = decodeNodeId(nodeId, getDomain());
90
90
  if (!decodedNodeId) return defaultDecodedValuePath(dataPath);
91
91
  let time = +parts[2] || 0;
92
92
  let seqNum = +parts[3] || 0;
@@ -111,7 +111,7 @@ export class PathValueArchives {
111
111
 
112
112
  public getDefaultValuePathInput(): DecodedValuePathInput {
113
113
  return {
114
- ...decodeNodeIdAssert(getOwnNodeIdAssert()),
114
+ ...decodeNodeIdAssert(getOwnNodeIdAssert(), getDomain()),
115
115
  time: Date.now(),
116
116
  seqNum: this.nextWriteSeqNum++,
117
117
  valueCount: 0,
@@ -27,7 +27,9 @@ import { decodeParentFilter, filterChildPathsBase } from "./hackedPackedPathPare
27
27
  import { isDiskAudit } from "../config";
28
28
  import { removeRange } from "../rangeMath";
29
29
  import { remoteWatcher } from "../1-path-client/RemoteWatcher";
30
+ import { setFlag } from "socket-function/require/compileFlags";
30
31
  import { sha256 } from "js-sha256";
32
+ setFlag(require, "js-sha256", "allowclient", true);
31
33
  import { evaluateValidStates, isServer } from "../config2";
32
34
 
33
35
  setImmediate(async () => {
@@ -27,10 +27,10 @@ import { runInfinitePoll } from "socket-function/src/batching";
27
27
  import { registerResource } from "../diagnostics/trackResources";
28
28
  import { getOwnNodeId } from "../-f-node-discovery/NodeDiscovery";
29
29
  import { PromiseObj } from "../promise";
30
- import { getOwnMachineId } from "../-a-auth/certs";
30
+ import { getOwnMachineId } from "sliftutils/misc/https/certs";
31
31
  import { remoteWatcher } from "./RemoteWatcher";
32
32
  import { heapTagObj } from "../diagnostics/heapTag";
33
- import { isDevDebugbreak } from "../config";
33
+ import { isDevDebugbreak, getDomain } from "../config";
34
34
  import { matchesParentRangeFilter } from "../0-path-value-core/hackedPackedPathParentFiltering";
35
35
  import { LOCAL_DOMAIN_PATH } from "../0-path-value-core/PathRouter";
36
36
 
@@ -718,7 +718,7 @@ export class ClientWatcher {
718
718
  let source = config.source;
719
719
 
720
720
  if (!source) {
721
- let debugName = getOwnMachineId().slice(0, 8);
721
+ let debugName = getOwnMachineId(getDomain()).slice(0, 8);
722
722
  if (this.activeWatchSpec?.debugName) {
723
723
  debugName += "|" + this.activeWatchSpec.debugName;
724
724
  }
@@ -8,7 +8,7 @@ import { delay, runInSerial, runInfinitePoll } from "socket-function/src/batchin
8
8
  import { errorify, logErrors } from "../errors";
9
9
  import { appendToPathStr, getLastPathPart, getParentPathStr, getPathDepth, getPathFromStr, getPathIndex, getPathIndexAssert, getPathPrefix, getPathStr1, getPathStr2, getPathSuffix, slicePathStrToDepth } from "../path";
10
10
  import { addEpsilons, getTimeUnique } from "socket-function/src/bits";
11
- import { getThreadKeyCert } from "../-a-auth/certs";
11
+ import { getThreadKeyCert } from "sliftutils/misc/https/certs";
12
12
  import { ActionsHistory } from "../diagnostics/ActionsHistory";
13
13
  import { registerResource } from "../diagnostics/trackResources";
14
14
  import { ClientWatcher, WatchSpecData, clientWatcher } from "../1-path-client/pathValueClientWatcher";
@@ -1,4 +1,4 @@
1
- import { getOwnMachineId } from "../-a-auth/certs";
1
+ import { getOwnMachineId } from "sliftutils/misc/https/certs";
2
2
  import { atomicObjectWrite, proxyWatcher, specialObjectWriteSymbol } from "../2-proxy/PathValueProxyWatcher";
3
3
  import { pathValueCommitter } from "../0-path-value-core/PathValueController";
4
4
  import { getNextTime } from "../0-path-value-core/pathValueCore";
@@ -181,7 +181,7 @@ export function writeFunctionCall(config: {
181
181
  DomainName: domainName,
182
182
  FunctionId: functionId,
183
183
  runAtTime: getNextTime(),
184
- callerMachineId: getOwnMachineId(),
184
+ callerMachineId: getOwnMachineId(getDomain()),
185
185
  // Will be updated by Querysub to be correct (unless we are directly writing, then...
186
186
  // this is fine).
187
187
  callerIP: "127.0.0.1",
@@ -13,7 +13,7 @@ let yargObj = yargs(process.argv)
13
13
  import { logErrors } from "../errors";
14
14
  import { PathFunctionRunner } from "./PathFunctionRunner";
15
15
  import { SocketFunction } from "socket-function/SocketFunction";
16
- import { getThreadKeyCert } from "../-a-auth/certs";
16
+ import { getThreadKeyCert } from "sliftutils/misc/https/certs";
17
17
  import { ClientWatcher } from "../1-path-client/pathValueClientWatcher";
18
18
  import { timeInMinute } from "socket-function/src/misc";
19
19
  import { getDomain, isLocal, isPublic } from "../config";
@@ -1,6 +1,7 @@
1
1
  import { SocketFunction } from "socket-function/SocketFunction";
2
2
  import { delay } from "socket-function/src/batching";
3
- import { getThreadKeyCert } from "../../-a-auth/certs";
3
+ import { getThreadKeyCert } from "sliftutils/misc/https/certs";
4
+ import { getDomain } from "../../config";
4
5
  import { ActionsHistory } from "../../diagnostics/ActionsHistory";
5
6
  import { errorToUndefined } from "../../errors";
6
7
  import { rawSchema } from "../../2-proxy/pathDatabaseProxyBase";
@@ -56,7 +57,7 @@ async function main() {
56
57
  PathValueProxyWatcher.TRACE = true;
57
58
  PathFunctionRunner.DEBUG_CALLS = true;
58
59
 
59
- await SocketFunction.mount({ port: 0, ...await getThreadKeyCert() });
60
+ await SocketFunction.mount({ port: 0, ...await getThreadKeyCert(getDomain()) });
60
61
  if (process.argv.includes("--reader")) {
61
62
  ActionsHistory.LOG_ACTION_HISTORY = "reader";
62
63
  await reader();
@@ -1,7 +1,7 @@
1
1
  import path from "path";
2
2
  import { deployBlock } from "./deployBlock";
3
3
  import { SocketFunction } from "socket-function/SocketFunction";
4
- import { getThreadKeyCert } from "../-a-auth/certs";
4
+ import { getThreadKeyCert } from "sliftutils/misc/https/certs";
5
5
  import { getDomain, isPublic } from "../config";
6
6
  import { getSchemaObject, getModuleRelativePath, PERMISSIONS_FUNCTION_ID, getExportPath, getPrefixesForDeploy } from "../3-path-functions/syncSchema";
7
7
  import { getPathStr2 } from "../path";
@@ -20,7 +20,7 @@ async function main() {
20
20
  await deployBlock();
21
21
 
22
22
  // Mount, so we can write directly to the database
23
- await SocketFunction.mount({ port: 0, ...await getThreadKeyCert(), public: isPublic() });
23
+ await SocketFunction.mount({ port: 0, ...await getThreadKeyCert(getDomain()), public: isPublic() });
24
24
 
25
25
  let folderRoot = path.resolve(".").replaceAll("\\", "/");
26
26
  const deployPath = path.resolve("./deploy.ts");
@@ -1,5 +1,5 @@
1
1
  import { waitForFirstTimeSync } from "socket-function/time/trueTimeShim";
2
- import { getOwnMachineId } from "../-a-auth/certs";
2
+ import { getOwnMachineId } from "sliftutils/misc/https/certs";
3
3
  import { devDebugbreak, getDomain, isLocal, isPublic, noSyncing } from "../config";
4
4
  import child_process from "child_process";
5
5
  import { getAllNodeIds, getOwnNodeId } from "../-f-node-discovery/NodeDiscovery";
@@ -144,7 +144,7 @@ export async function registerEdgeNode(config: {
144
144
  let gitHash = await getGitRefLive();
145
145
 
146
146
  let nodeId = getOwnNodeId();
147
- let machineId = getOwnMachineId();
147
+ let machineId = getOwnMachineId(getDomain());
148
148
 
149
149
  let edgeNodeConfig: EdgeNodeConfig = {
150
150
  nodeId,
@@ -194,7 +194,7 @@ const loadEntryPointsByHash = runInSerial(async function loadEntryPointsByHash(c
194
194
  entryPaths = entryPaths.map(x => path.resolve(rootPath + x).replaceAll("\\", "/"));
195
195
 
196
196
  let nodeId = getOwnNodeId();
197
- let machineId = getOwnMachineId();
197
+ let machineId = getOwnMachineId(getDomain());
198
198
 
199
199
  let edgeNodeConfig: EdgeNodeConfig = {
200
200
  nodeId,
@@ -16,7 +16,7 @@ import { SocketFunction } from "socket-function/SocketFunction";
16
16
  import { isHotReloading, watchFilesAndTriggerHotReloading } from "socket-function/hot/HotReloadController";
17
17
  import { RequireController, setRequireBootRequire } from "socket-function/require/RequireController";
18
18
  import { cache, cacheLimited, lazy } from "socket-function/src/caching";
19
- import { getOwnMachineId, getOwnThreadId, getThreadKeyCert, verifyMachineIdForPublicKey } from "../-a-auth/certs";
19
+ import { getIdentityCAPromise, getOwnMachineId, getOwnThreadId, getThreadKeyCert, verifyMachineIdForPublicKey } from "sliftutils/misc/https/certs";
20
20
  import { getHostedIP, getSNICerts, publishMachineARecords } from "../-e-certs/EdgeCertController";
21
21
  import { debugCoreMode, registerGetCompressNetwork, authorityStorage, enableDebugRejections } from "../0-path-value-core/pathValueCore";
22
22
  import { clientWatcher, ClientWatcher } from "../1-path-client/pathValueClientWatcher";
@@ -28,7 +28,7 @@ import { logErrors } from "../errors";
28
28
  import { getLastPathPart, getPathIndexAssert, getPathStr2 } from "../path";
29
29
  import { PermissionsCheck } from "./permissions";
30
30
  import { inlineNestedCalls, syncSchema } from "../3-path-functions/syncSchema";
31
- import type { identityStorageKey, IdentityStorageType } from "../-a-auth/certs";
31
+ import type { identityStorageKey, IdentityStorageType } from "sliftutils/misc/https/certs";
32
32
 
33
33
  import { ExternalRenderClass, qreact } from "../4-dom/qreact";
34
34
  import { configRootDiscoveryLocation, getOwnNodeId, onNodeBroadcasted, onNodeDiscoveryReady } from "../-f-node-discovery/NodeDiscovery";
@@ -185,7 +185,8 @@ export class Querysub {
185
185
  public static DEBUG_CALLS = false;
186
186
  public static DEBUG_PREDICTIONS = false;
187
187
  public static PREDICT_CALLS = true;
188
- public static AUDIT_PREDICTIONS = true;
188
+ // These audits are mostly wrong, so I'm just disabling them.
189
+ public static AUDIT_PREDICTIONS = false;
189
190
  public static SIMULATE_LAG = 0;
190
191
 
191
192
  public static registerAliveChecker = <T>(config: AliveChecker<T>) => registerAliveChecker(config);
@@ -235,7 +236,7 @@ export class Querysub {
235
236
 
236
237
  public static getCallerMachineId() {
237
238
  let call = getCurrentCallAllowUndefined();
238
- if (!call) return getOwnMachineId();
239
+ if (!call) return getOwnMachineId(getDomain());
239
240
  return getCurrentCall().callerMachineId;
240
241
  }
241
242
  public static getCallerIP = () => getCurrentCall().callerIP;
@@ -553,12 +554,12 @@ export class Querysub {
553
554
  };
554
555
  public static onCommitPredictFinished = this.onCallPredict;
555
556
 
556
- public static getOwnMachineId = getOwnMachineId;
557
- public static getSelfMachineId = getOwnMachineId;
557
+ public static getOwnMachineId = () => getOwnMachineId(getDomain());
558
+ public static getSelfMachineId = () => getOwnMachineId(getDomain());
558
559
 
559
560
  public static getOwnNodeId = () => getOwnNodeId();
560
561
  public static getSelfNodeId = () => getOwnNodeId();
561
- public static getOwnThreadId = () => getOwnThreadId();
562
+ public static getOwnThreadId = () => getOwnThreadId(getDomain());
562
563
 
563
564
  /** Set ClientWatcher.DEBUG_SOURCES to true for to be populated */
564
565
  public static getTriggerReason() {
@@ -758,6 +759,8 @@ export class Querysub {
758
759
 
759
760
  sourceCheck?: MachineSourceCheck<any>;
760
761
  }) {
762
+ await getIdentityCAPromise(getDomain());
763
+
761
764
  console.log(`Hosting server with config: ${JSON.stringify(config)}`);
762
765
  this.socketFunctionInit();
763
766
 
@@ -839,7 +842,7 @@ export class Querysub {
839
842
  public: isPublic(),
840
843
  port: config.port,
841
844
  autoForwardPort: true,
842
- ...await getThreadKeyCert(),
845
+ ...await getThreadKeyCert(getDomain()),
843
846
  SNICerts: {
844
847
  ...await getSNICerts({
845
848
  publicPort: config.port,
@@ -903,7 +906,7 @@ export class Querysub {
903
906
  globalThis.remapImportRequestsClientside = globalThis.remapImportRequestsClientside || [];
904
907
  globalThis.remapImportRequestsClientside.push(async (args) => {
905
908
  try {
906
- let key: typeof identityStorageKey = "machineCA_9";
909
+ let key: typeof identityStorageKey = "machineCA_14";
907
910
  let storageValueJSON = localStorage.getItem(key);
908
911
  if (!storageValueJSON) return args;
909
912
  let storageValue = JSON.parse(storageValueJSON) as IdentityStorageType;
@@ -1055,6 +1058,7 @@ export class Querysub {
1055
1058
  if (isClient()) {
1056
1059
  throw new Error(`--client processes cannot host a service. Either stop passing --client and keep the process on the network and trusted, or stop calling hostServer and call Querysub.configRootDiscoveryLocation instead. You MUST provide configRootDiscoveryLocation a valid nodeId. Which means either you do server selection manually, or if you are developing, just point it to "127-0-0-1.${getDomain()}:your local port here"`);
1057
1060
  }
1061
+ await getIdentityCAPromise(getDomain());
1058
1062
  let times: {
1059
1063
  name: string;
1060
1064
  duration: number
@@ -1069,7 +1073,7 @@ export class Querysub {
1069
1073
  let mountPromise = SocketFunction.mount({
1070
1074
  public: isPublic(),
1071
1075
  port,
1072
- ...await getThreadKeyCert(),
1076
+ ...await getThreadKeyCert(getDomain()),
1073
1077
  });
1074
1078
 
1075
1079
  let publishPromise = publishMachineARecords();
@@ -351,7 +351,6 @@ function predictCallBase(config: {
351
351
  // which create a memory leak.
352
352
  rejectPrediction();
353
353
 
354
-
355
354
  if (Querysub.AUDIT_PREDICTIONS && predictions) {
356
355
  // Wait to receive all parts of the prediction
357
356
  await delay(10_000);
@@ -370,16 +369,6 @@ function predictCallBase(config: {
370
369
  let predictBuffer = cborEncoder().encode(predictValue);
371
370
  // If they are different, warn
372
371
  if (!finalBuffer.equals(predictBuffer)) {
373
- // NOTE: This MIGHT be due to delayCommit on another function. We can't know when to force flush
374
- // delayCommit values, and so we only force flush if other (non-delayCommit) functions are committed
375
- // in the same schema, which will be wrong if data is accessed cross schema.
376
- // - If this happens, and is a problem, we COULD handle it, but... it is very difficult, as we would need
377
- // to evaluate the other function, detect it conflicts with a delayCommit functions, then run the delayCommit
378
- // function, then re-evaluated the conflicted prediction (which is a lot of communication and reruns
379
- // between a lot of systems... especially because in a second this will resolve by the server
380
- // clobbering our prediction).
381
- // - AND, we can't commit the pending calls until we sort out the order, so this necessarily requires
382
- // slowing down commits if we are delaying other calls.
383
372
  console.warn(`${red("Prediction was wrong")}: for ${call.DomainName}.${call.FunctionId} value path ${getPathFromStr(predict.path).join(".")} predict != finalValue. ${config.metadata.delayCommit && "This function is using delay commit. It's likely that you are using the time from Querysub.now() (or accessing the function call time in some other way). This doesn't work with delay commit because the server will rewrite the commit time, instead you should pass the timestamp as a parameter (And then make sure it's not some kind of privilege value that the user could cheat)" || ""} It might be the case that you shouldn't even predict the call client side (you can use the functionMetadata to set it as nopredict). It might also be the case that you do want to predict it, but you should batch the calls, so you only make one call, instead of many calls at once.`, predictValue, finalValue);
384
373
  }
385
374
  }
@@ -25,7 +25,7 @@ import { managementPageURL } from "../../diagnostics/managementPages";
25
25
  import { getLogViewerParams } from "../../diagnostics/logs/IndexedLogs/LogViewerParams";
26
26
  import { getScreenName } from "../machineApplyMainCode";
27
27
  import { getOwnThreadId } from "../../-f-node-discovery/NodeDiscovery";
28
- import { decodeNodeId } from "../../-a-auth/certs";
28
+ import { decodeNodeId } from "sliftutils/misc/https/certs";
29
29
 
30
30
 
31
31
 
@@ -1,7 +1,7 @@
1
1
  import "../inject";
2
2
 
3
3
  import { measureWrap } from "socket-function/src/profiling/measure";
4
- import { getOwnMachineId } from "../-a-auth/certs";
4
+ import { getOwnMachineId } from "sliftutils/misc/https/certs";
5
5
  import { forceRemoveNode, getOurNodeId, getOurNodeIdAssert } from "../-f-node-discovery/NodeDiscovery";
6
6
  import { Querysub } from "../4-querysub/Querysub";
7
7
  import { MACHINE_RESYNC_INTERVAL, MachineServiceControllerBase, MachineInfo, ServiceConfig, serviceConfigs, SERVICE_FOLDER, machineInfos, SERVICE_NODE_FILE_NAME, getEffectiveServiceConfigs, recordLaunch } from "./machineSchema";
@@ -86,7 +86,7 @@ const getDiskInfo = measureWrap(async function getDiskInfo(): Promise<{ value: n
86
86
 
87
87
  const getLiveMachineInfo = measureWrap(async function getLiveMachineInfo() {
88
88
  let machineInfo: MachineInfo = {
89
- machineId: getOwnMachineId(),
89
+ machineId: getOwnMachineId(getDomain()),
90
90
  applyNodeId: getOurNodeIdAssert(),
91
91
  heartbeat: Date.now(),
92
92
  info: {},
@@ -661,7 +661,7 @@ let launchesPerService = new Map<string, number>();
661
661
  let lastLaunchedTimePerService = new Map<string, number>();
662
662
 
663
663
  async function quickIsOutdated() {
664
- let machineId = getOwnMachineId();
664
+ let machineId = getOwnMachineId(getDomain());
665
665
  // If any rolling are ready to restart, we are outdated
666
666
  for (let [rollingScreenName, rollingInfo] of rollingKeepScreenAlive) {
667
667
  if (rollingInfo.pinnedTime + rollingInfo.pinnedDuration < Date.now()) {
@@ -697,7 +697,7 @@ async function quickIsOutdated() {
697
697
 
698
698
  const resyncServicesBase = runInSerial(measureWrap(async function resyncServices() {
699
699
  console.log(magenta("Resyncing services"));
700
- let machineId = getOwnMachineId();
700
+ let machineId = getOwnMachineId(getDomain());
701
701
  let configs = await getEffectiveServiceConfigs();
702
702
  let relevantConfigs = configs.filter(config => config.machineIds.includes(machineId)).filter(x => x.parameters.deploy);
703
703
 
@@ -9,7 +9,7 @@ import { getCallObj } from "socket-function/src/nodeProxy";
9
9
  import { getSyncedController } from "../library-components/SyncedController";
10
10
  import { requiresNetworkTrustHook } from "../-d-trust/NetworkTrust2";
11
11
  import { extractType } from "../misc/extractType";
12
- import { getOwnMachineId } from "../-a-auth/certs";
12
+ import { getOwnMachineId } from "sliftutils/misc/https/certs";
13
13
  import { delay, runInSerial, runInfinitePollCallAtStart } from "socket-function/src/batching";
14
14
  import { lazy } from "socket-function/src/caching";
15
15
  import { errorToUndefinedSilent } from "../errors";
@@ -9,7 +9,8 @@ import { getNodeIdDomain, getNodeIdLocation, getNodeIdDomainMaybeUndefined } fro
9
9
  import { assertIsNetworkTrusted } from "../-d-trust/NetworkTrust2";
10
10
  import { runPromise } from "../functional/runCommand";
11
11
  import { errorToUndefinedSilent } from "../errors";
12
- import { decodeNodeId } from "../-a-auth/certs";
12
+ import { decodeNodeId } from "sliftutils/misc/https/certs";
13
+ import { getDomain } from "../config";
13
14
  import { keyBy, keyByArray, timeInSecond, timeoutToUndefined, timeoutToUndefinedSilent } from "socket-function/src/misc";
14
15
  import dns from "dns";
15
16
  import { isDefined } from "../misc";
@@ -193,7 +194,7 @@ class MachineThreadInfoBase {
193
194
  }> {
194
195
  let nodeIds = await getAllNodeIds();
195
196
  let specialInfos = await Promise.all(nodeIds.map(async (nodeId): Promise<NodeSpecialInfo | undefined> => {
196
- const nodeParts = decodeNodeId(nodeId);
197
+ const nodeParts = decodeNodeId(nodeId, getDomain());
197
198
  if (!nodeParts) return undefined;
198
199
 
199
200
  const location = getNodeIdLocation(nodeId);
@@ -64,13 +64,17 @@ export class NodeViewer extends qreact.Component {
64
64
  // atomic
65
65
  [nodeId: string]: NodeData
66
66
  },
67
+ nodesVersion: 0,
67
68
  };
68
69
  populateNodeInfos = lazy(() => {
69
70
  logErrors((async () => {
70
71
  try {
71
72
  const controller = NodeViewerController.nodes[getBrowserUrlNode()];
72
73
  let nodeIds = await controller.getAllNodeIds();
73
- Querysub.commit(() => this.state.nodeIds = nodeIds);
74
+ Querysub.commit(() => {
75
+ this.state.nodeIds = nodeIds;
76
+ this.state.nodesVersion++;
77
+ });
74
78
 
75
79
  let ourIP = await controller.getCallerIP();
76
80
  let ourExternalIP = await getExternalIP();
@@ -109,6 +113,7 @@ export class NodeViewer extends qreact.Component {
109
113
  data.loadTime = time;
110
114
  Querysub.commit(() => {
111
115
  this.state.nodes[nodeId] = atomicObjectWrite(data);
116
+ this.state.nodesVersion++;
112
117
  });
113
118
  }));
114
119
  } catch (e: any) {
@@ -146,6 +151,7 @@ export class NodeViewer extends qreact.Component {
146
151
  if (this.state.access === "verifying") {
147
152
  return <div>Verifying access...</div>;
148
153
  }
154
+ void this.state.nodesVersion;
149
155
  let nodeDatas = Object.values(this.state.nodes);
150
156
  let deadCount = 0;
151
157
  if (!showNotReadyNodes.value) {
@@ -7,7 +7,7 @@ import { IndexedLogResults, Reader, SearchParams, addReadToResults, createEmptyI
7
7
  import { getDomain, isPublic } from "../../../config";
8
8
  import { getArchivesHome, getArchivesLocal } from "../../../-a-archives/archivesDisk";
9
9
  import { getArchivesBackblaze, getArchivesBackblazePrivateImmutable } from "../../../-a-archives/archivesBackBlaze";
10
- import { getMachineId, getOwnThreadId } from "../../../-a-auth/certs";
10
+ import { getMachineId, getOwnThreadId } from "sliftutils/misc/https/certs";
11
11
  import { ArchivesMemoryCacheStats, createArchivesMemoryCache } from "../../../-a-archives/archivesMemoryCache";
12
12
  import { registerShutdownHandler } from "../../periodic";
13
13
  import { measureBlock, measureFnc, measureWrap } from "socket-function/src/profiling/measure";
@@ -278,7 +278,7 @@ export class IndexedLogs<T> {
278
278
  private async getMachineNodes(): Promise<string[]> {
279
279
  let nodeIds = await getAllNodeIds();
280
280
  nodeIds = nodeIds.filter(x => !isNodeIdOnOwnMachineId(x));
281
- let byMachineId = keyByArray(nodeIds, x => getMachineId(x));
281
+ let byMachineId = keyByArray(nodeIds, x => getMachineId(x, getDomain()));
282
282
 
283
283
  let nextCache = new Map<string, string>();
284
284
 
@@ -1,6 +1,7 @@
1
1
  import { sort, timeInHour, timeInMinute, timeInSecond, timeoutToError, timeoutToUndefined, timeoutToUndefinedSilent } from "socket-function/src/misc";
2
2
  import { lazy } from "socket-function/src/caching";
3
- import { getMachineId } from "../../../-a-auth/certs";
3
+ import { getMachineId } from "sliftutils/misc/https/certs";
4
+ import { getDomain } from "../../../config";
4
5
  import { getAllNodeIds, getOwnMachineId, isOwnNodeId } from "../../../-f-node-discovery/NodeDiscovery";
5
6
  import { NodeCapabilitiesController } from "../../../-g-core-values/NodeCapabilities";
6
7
  import { getLoggers2Async, LogDatum } from "../diskLogger";
@@ -537,7 +538,7 @@ export class MCPIndexedLogs {
537
538
  // list and tries each until one services the request.
538
539
  private async findRemoteNodesOnMachine(machineId: string): Promise<string[]> {
539
540
  let allIds = await getAllNodeIds();
540
- let candidates = allIds.filter(id => !isOwnNodeId(id) && getMachineId(id) === machineId);
541
+ let candidates = allIds.filter(id => !isOwnNodeId(id) && getMachineId(id, getDomain()) === machineId);
541
542
  if (candidates.length === 0) return [];
542
543
 
543
544
  let preferred: string[] = [];
@@ -1,8 +1,9 @@
1
1
  import { SocketFunction } from "socket-function/SocketFunction";
2
2
  import { lazy } from "socket-function/src/caching";
3
3
  import { getExternalIP } from "socket-function/src/networking";
4
- import { decodeNodeId, getOwnMachineId, getOwnThreadId } from "../../-a-auth/certs";
4
+ import { decodeNodeId, getOwnMachineId, getOwnThreadId } from "sliftutils/misc/https/certs";
5
5
  import { getOwnNodeId } from "../../-f-node-discovery/NodeDiscovery";
6
+ import { getDomain } from "../../config";
6
7
  import { logErrors } from "../../errors";
7
8
  import { addGlobalContext } from "./diskLogger";
8
9
  import child_process from "child_process";
@@ -19,9 +20,9 @@ export function addBuiltInContext() {
19
20
  let nodeId = getOwnNodeId();
20
21
  let nodeParts = getNodeIdLocation(nodeId);
21
22
  return {
22
- __machineId: getOwnMachineId(),
23
+ __machineId: getOwnMachineId(getDomain()),
23
24
  __mountId: SocketFunction.mountedNodeId,
24
- __threadId: getOwnThreadId(),
25
+ __threadId: getOwnThreadId(getDomain()),
25
26
  __port: nodeParts?.port,
26
27
  __nodeId: nodeId,
27
28
  __entry: process.argv[1],
@@ -28,12 +28,16 @@ export type DNSRecord = {
28
28
  ttl: number;
29
29
  createdOn: number;
30
30
  modifiedOn: number;
31
+ // Time we last asserted this record, parsed from our freshness comment tag, falling back to
32
+ // Cloudflare's modified_on when the tag is absent. This is the time used for staleness.
33
+ setOn: number;
31
34
  };
32
35
 
33
36
  class DNSPageControllerBase {
34
37
  public async getAllRecords(): Promise<DNSRecord[]> {
35
38
  if (!isNode()) throw new Error(`getAllRecords must be called serverside`);
36
39
  const { cloudflareGETCall } = await import("../../-b-authorities/cloudflareHelpers");
40
+ const { freshnessTime } = await import("../../-b-authorities/dnsAuthority");
37
41
  const { getDomain } = await import("../../config");
38
42
 
39
43
  let zones = await cloudflareGETCall<{ id: string; name: string }[]>("/zones", {
@@ -55,11 +59,13 @@ class DNSPageControllerBase {
55
59
  ttl: number;
56
60
  created_on: string;
57
61
  modified_on: string;
62
+ comment?: string;
58
63
  }[]>(`/zones/${zone.id}/dns_records`, {
59
64
  per_page: String(RECORDS_PER_PAGE),
60
65
  page: String(page),
61
66
  });
62
67
  for (let record of records) {
68
+ let modifiedOn = new Date(record.modified_on).getTime();
63
69
  allRecords.push({
64
70
  id: record.id,
65
71
  zoneId: zone.id,
@@ -70,7 +76,8 @@ class DNSPageControllerBase {
70
76
  proxied: record.proxied,
71
77
  ttl: record.ttl,
72
78
  createdOn: new Date(record.created_on).getTime(),
73
- modifiedOn: new Date(record.modified_on).getTime(),
79
+ modifiedOn,
80
+ setOn: freshnessTime(record.comment) || modifiedOn,
74
81
  });
75
82
  }
76
83
  if (records.length < RECORDS_PER_PAGE) break;
@@ -161,7 +168,7 @@ export class DNSPage extends qreact.Component {
161
168
  }
162
169
 
163
170
  private async deleteStaleHexRecords(content: string, matching: DNSRecord[]) {
164
- let listText = matching.map(r => ` ${r.type} ${r.name} (modified ${new Date(r.modifiedOn).toISOString()})`).join("\n");
171
+ let listText = matching.map(r => ` ${r.type} ${r.name} (set ${new Date(r.setOn).toISOString()})`).join("\n");
165
172
  let typed = prompt(`Type "${content}" to confirm deleting ${matching.length} stale hex-subdomain record(s):\n\n${listText}`);
166
173
  if (typed === null) return;
167
174
  if (typed !== content) {
@@ -237,7 +244,7 @@ export class DNSPage extends qreact.Component {
237
244
  let groupEntries = Array.from(groups.entries()).map(([content, list]) => ({ content, records: list }));
238
245
  sort(groupEntries, x => -x.records.length);
239
246
  for (let group of groupEntries) {
240
- sort(group.records, r => -r.modifiedOn);
247
+ sort(group.records, r => -r.setOn);
241
248
  }
242
249
 
243
250
  return <div className={css.vbox(12).pad2(16).fillWidth}>
@@ -289,13 +296,13 @@ export class DNSPage extends qreact.Component {
289
296
  {(() => {
290
297
  let staleHex = list.filter(r =>
291
298
  HEX_SUBDOMAIN_REGEX.test(r.name)
292
- && Date.now() - r.modifiedOn > STALE_HEX_SUBDOMAIN_AGE
299
+ && Date.now() - r.setOn > STALE_HEX_SUBDOMAIN_AGE
293
300
  );
294
301
  if (staleHex.length === 0) return undefined;
295
302
  let staleHexBusy = !!this.state.busyKeys[`staleHex:${content}`];
296
303
  return <div className={css.vbox(4).pad2(8).bord2(30, 60, 60).hsl(30, 70, 96)}>
297
304
  <div className={css.hbox(10).alignItems("center")}>
298
- <span className={css.boldStyle}>Stale hex-subdomain records (modified &gt;7d ago): {staleHex.length}</span>
305
+ <span className={css.boldStyle}>Stale hex-subdomain records (set &gt;7d ago): {staleHex.length}</span>
299
306
  <div className={css.flexGrow(1)} />
300
307
  <button
301
308
  className={css.pad2(10, 6).button.bord2(0, 80, 50)
@@ -307,7 +314,7 @@ export class DNSPage extends qreact.Component {
307
314
  </button>
308
315
  </div>
309
316
  <div className={css.vbox(2).fontFamily("monospace").colorhsl(0, 0, 30)}>
310
- {staleHex.map(r => <div key={r.id}>{r.type} {r.name} — modified {formatDateJSX(r.modifiedOn)}</div>)}
317
+ {staleHex.map(r => <div key={r.id}>{r.type} {r.name} — set {formatDateJSX(r.setOn)}</div>)}
311
318
  </div>
312
319
  </div>;
313
320
  })()}
@@ -324,6 +331,9 @@ export class DNSPage extends qreact.Component {
324
331
  <span className={css.colorhsl(0, 0, 50)}>
325
332
  modified {formatDateJSX(record.modifiedOn)}
326
333
  </span>
334
+ <span className={css.colorhsl(0, 0, 50)}>
335
+ set {formatDateJSX(record.setOn)}
336
+ </span>
327
337
  <span className={css.colorhsl(0, 0, 50)}>{record.zoneName}</span>
328
338
  <button
329
339
  className={css.pad2(8, 4).button.bord2(0, 0, 60)
@@ -12,12 +12,12 @@ import { authorityLookup } from "../0-path-value-core/AuthorityLookup";
12
12
  import { pathValueSerializer } from "../-h-path-value-serialize/PathValueSerializer";
13
13
  import { validStateComputer } from "../0-path-value-core/ValidStateComputer";
14
14
  import { SocketFunction } from "socket-function/SocketFunction";
15
- import { decodeNodeId } from "../-a-auth/certs";
15
+ import { decodeNodeId } from "sliftutils/misc/https/certs";
16
16
  import { requiresNetworkTrustHook } from "../-d-trust/NetworkTrust2";
17
17
  import { assertIsManagementUser } from "./managementPages";
18
18
  import { isNode } from "typesafecss";
19
19
  import { isClient } from "../config2";
20
- import { isLocal } from "../config";
20
+ import { isLocal, getDomain } from "../config";
21
21
  import { pathWatcher } from "../0-path-value-core/PathWatcher";
22
22
  import { debugNodeId } from "../-c-identity/IdentityController";
23
23
  import debugbreak from "debugbreak";
@@ -253,7 +253,7 @@ function trackSyncAge(config: {
253
253
  ourValid: config.ourValid,
254
254
  remoteValid: config.remoteValid,
255
255
  remoteNodeId: config.remoteNodeId,
256
- remoteNodeThreadId: decodeNodeId(config.remoteNodeId)?.threadId,
256
+ remoteNodeThreadId: decodeNodeId(config.remoteNodeId, getDomain())?.threadId,
257
257
  });
258
258
  } else if (age >= WARN_THRESHOLD) {
259
259
  stats.warningCount++;
@@ -265,7 +265,7 @@ function trackSyncAge(config: {
265
265
  ourValid: config.ourValid,
266
266
  remoteValid: config.remoteValid,
267
267
  remoteNodeId: config.remoteNodeId,
268
- remoteNodeThreadId: decodeNodeId(config.remoteNodeId)?.threadId,
268
+ remoteNodeThreadId: decodeNodeId(config.remoteNodeId, getDomain())?.threadId,
269
269
  });
270
270
  } else {
271
271
  stats.fixedCount++;
@@ -4,7 +4,7 @@ import { logErrors } from "../errors";
4
4
  import { isNode, sort } from "socket-function/src/misc";
5
5
  import debugbreak from "debugbreak";
6
6
  import { registerPeriodic } from "./periodic";
7
- import { getOwnMachineId } from "../-a-auth/certs";
7
+ import { getOwnMachineId } from "sliftutils/misc/https/certs";
8
8
  import { SocketFunction } from "socket-function/SocketFunction";
9
9
  import { formatPercent, formatTime } from "socket-function/src/formatting/format";
10
10
  import { pathWatcher } from "../0-path-value-core/PathWatcher";
package/src/server.ts CHANGED
@@ -3,7 +3,7 @@ import "./inject";
3
3
 
4
4
  import { isNode, isNodeTrue } from "socket-function/src/misc";
5
5
  import { SocketFunction } from "socket-function/SocketFunction";
6
- import { getThreadKeyCert } from "./-a-auth/certs";
6
+ import { getThreadKeyCert } from "sliftutils/misc/https/certs";
7
7
  import { logErrors } from "./errors";
8
8
  import { green } from "socket-function/src/formatting/logColors";
9
9
  import { formatTime } from "socket-function/src/formatting/format";