Verify signed node registration claims
This commit is contained in:
parent
f45113b861
commit
2bfede2376
9 changed files with 965 additions and 54 deletions
|
|
@ -0,0 +1,111 @@
|
|||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { generateKeyPairSync } from 'node:crypto';
|
||||
import {
|
||||
assertLoadedNodeRegistrationSnapshot,
|
||||
NodeRegistrationSnapshotLoader,
|
||||
} from './node-registration-snapshot.js';
|
||||
|
||||
const COMMIT = 'a'.repeat(40);
|
||||
const ANCHOR_URL = 'https://guanghulab.com/api/ai/v1/anchor';
|
||||
const REGISTRY_URL = `https://guanghulab.com/code/bingshuo/guanghu-ice-heart/raw/commit/${COMMIT}/routing/node-registration-endpoints.json`;
|
||||
const { publicKey } = generateKeyPairSync('ed25519');
|
||||
|
||||
function anchor(includeMap = true) {
|
||||
return {
|
||||
schema: 'guanghu.public-navigation-anchor/v1',
|
||||
anchor_id: 'GLW-PUBLIC-NAV-ANCHOR-001',
|
||||
state: 'CURRENT_CANONICAL',
|
||||
repository_id: 'REPO-012',
|
||||
branch: 'main',
|
||||
public_entry: ANCHOR_URL,
|
||||
code_entry: 'https://guanghulab.com/code/bingshuo/guanghu-ice-heart',
|
||||
maps: includeMap ? {
|
||||
node_registration_endpoints: {
|
||||
path: 'routing/node-registration-endpoints.json',
|
||||
id: 'GH-AIOS-NODE-REGISTRATION-ENDPOINTS-001',
|
||||
version: '1.0.0',
|
||||
},
|
||||
} : {},
|
||||
navigation_source: {
|
||||
anchor_id: 'GLW-PUBLIC-NAV-ANCHOR-001',
|
||||
source_commit: COMMIT,
|
||||
source_mode: 'REPO-012_MAIN_GIT_SNAPSHOT',
|
||||
source_degraded: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function registry(version = '1.0.0') {
|
||||
return {
|
||||
endpoints: [{
|
||||
algorithm: 'Ed25519',
|
||||
domainIds: ['DOM-FIFTH-0001'],
|
||||
endpointId: 'GH-NODE-REG-001',
|
||||
nodeTypes: ['local-terminal'],
|
||||
publicKeyPem: publicKey.export({ format: 'pem', type: 'spki' }).toString(),
|
||||
signerId: 'GH-NODE-REG-SIGNER-001',
|
||||
status: 'ACTIVE',
|
||||
url: 'https://guanghulab.com/api/ai/v1/node-registrations/claims',
|
||||
}],
|
||||
registryId: 'GH-AIOS-NODE-REGISTRATION-ENDPOINTS-001',
|
||||
schema: 'gh-aios.node-registration-endpoints/v1',
|
||||
state: 'CURRENT',
|
||||
version,
|
||||
};
|
||||
}
|
||||
|
||||
function loader(readAnchor: () => unknown, readRegistry: () => unknown) {
|
||||
return new NodeRegistrationSnapshotLoader({
|
||||
async fetchJson(url) {
|
||||
if (url === ANCHOR_URL) return readAnchor();
|
||||
if (url === REGISTRY_URL) return readRegistry();
|
||||
throw new Error('unexpected_url');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
test('loads one exact registry from the anchor source commit', async () => {
|
||||
const snapshot = await loader(() => anchor(), () => registry()).refresh();
|
||||
assert.equal(snapshot.receipt.status, 'CURRENT');
|
||||
assert.equal(snapshot.receipt.sourceCommit, COMMIT);
|
||||
assert.equal(snapshot.receipt.endpointCount, 1);
|
||||
assert.equal(assertLoadedNodeRegistrationSnapshot(snapshot), snapshot);
|
||||
});
|
||||
|
||||
test('the current public anchor without a registration map is explicitly unavailable', async () => {
|
||||
const snapshot = await loader(() => anchor(false), () => registry()).refresh();
|
||||
assert.deepEqual(snapshot.receipt, {
|
||||
endpointCount: 0,
|
||||
reason: 'REGISTRY_UNREGISTERED',
|
||||
registryVersion: null,
|
||||
sourceCommit: null,
|
||||
status: 'UNAVAILABLE',
|
||||
});
|
||||
assert.equal(snapshot.registry, null);
|
||||
});
|
||||
|
||||
test('source and registry mismatches fail closed', async () => {
|
||||
const unavailable = await loader(() => { throw new Error('offline'); }, () => registry()).refresh();
|
||||
assert.equal(unavailable.receipt.reason, 'SOURCE_UNAVAILABLE');
|
||||
const invalid = await loader(() => anchor(), () => registry('2.0.0')).refresh();
|
||||
assert.equal(invalid.receipt.reason, 'REGISTRY_INVALID');
|
||||
});
|
||||
|
||||
test('last-known-good state is reported degraded and cannot be mistaken for current', async () => {
|
||||
let currentAnchor: unknown = anchor();
|
||||
const snapshotLoader = loader(() => currentAnchor, () => registry());
|
||||
await snapshotLoader.refresh();
|
||||
currentAnchor = anchor(false);
|
||||
const degraded = await snapshotLoader.refresh();
|
||||
assert.equal(degraded.receipt.status, 'DEGRADED_LAST_KNOWN_GOOD');
|
||||
assert.equal(degraded.receipt.reason, 'REGISTRY_UNREGISTERED');
|
||||
assert.equal(degraded.receipt.sourceCommit, COMMIT);
|
||||
});
|
||||
|
||||
test('caller-created snapshots are rejected', () => {
|
||||
assert.throws(() => assertLoadedNodeRegistrationSnapshot({
|
||||
receipt: { endpointCount: 0, registryVersion: null, sourceCommit: null, status: 'UNAVAILABLE' },
|
||||
registry: null,
|
||||
}), /snapshot_unregistered/);
|
||||
});
|
||||
Loading…
Reference in a new issue