Files
p2ns/test-scripts/network-manifest.test.js
T
Raven Scott b1a02e2e84 feat(experimental)!: multi-master one ledger (Option B)
Remove the last layer of soft centralization: a lone `--master` on empty
storage could still implicitly genesis a separate Autopass and split the
network on the same TOPIC_SEED. Genesis is now explicit (`--master
--genesis`); secondary masters pair via invite into the same dnsPass as
joiners, with a shared network manifest, split-brain diagnostics, and
writer-aware quorum.

- Genesis vs secondary master boot paths; auto-adopt manifest on upgrade
- Masters without dnsPass accept invites; masters with pass ignore them
- NETWORK_MANIFEST_FILE, P2NS_GENESIS, MASTER_LOAD_DOMAINS, MASTER_INVITE_ONLY
- core.status networkId; admin diagnostics; docs and multi-master tests

BREAKING: operators must run one genesis per network; additional masters
use `node p2ns.js --master` (not `--genesis`) on empty storage.
2026-05-29 05:34:50 -04:00

78 lines
2.4 KiB
JavaScript

#!/usr/bin/env node
/**
* Unit tests for network manifest helpers.
*/
const assert = require('assert');
const fs = require('fs').promises;
const path = require('path');
const os = require('os');
const {
extractNetworkIdentity,
validateManifestAgainstPass,
readManifest,
writeManifest,
storageDirHasCorestoreData
} = require('../includes/infrastructure/network-manifest');
function mockPass(discoveryHex, writerHex) {
const discoveryKey = Buffer.from(discoveryHex, 'hex');
const writerKey = Buffer.from(writerHex, 'hex');
return {
discoveryKey,
writerKey,
base: { key: writerKey }
};
}
async function testStorageDirEmpty() {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'p2ns-manifest-'));
assert.strictEqual(await storageDirHasCorestoreData(dir), false);
await fs.writeFile(path.join(dir, 'core'), 'x');
assert.strictEqual(await storageDirHasCorestoreData(dir), true);
await fs.rm(dir, { recursive: true, force: true });
}
async function testManifestRoundTrip() {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'p2ns-manifest-'));
const manifestPath = path.join(dir, 'network.json');
const pass = mockPass('aa'.repeat(32), 'bb'.repeat(32));
const identity = extractNetworkIdentity(pass, 'bb'.repeat(64));
await writeManifest(manifestPath, {
...identity,
topicSeed: 'p2ns-dns',
isGenesis: true
});
const read = await readManifest(manifestPath);
assert.strictEqual(read.networkId, identity.networkId);
assert.strictEqual(read.topicSeed, 'p2ns-dns');
const validation = validateManifestAgainstPass(read, pass, 'p2ns-dns');
assert.strictEqual(validation.ok, true);
await fs.rm(dir, { recursive: true, force: true });
}
async function testTopicMismatch() {
const pass = mockPass('cc'.repeat(32), 'dd'.repeat(32));
const manifest = {
version: 1,
networkId: pass.discoveryKey.toString('hex'),
topicSeed: 'other-seed',
autopassDiscoveryKey: pass.discoveryKey.toString('hex')
};
const validation = validateManifestAgainstPass(manifest, pass, 'p2ns-dns');
assert.strictEqual(validation.ok, false);
assert.strictEqual(validation.error, 'topic_seed_mismatch');
}
async function run() {
await testStorageDirEmpty();
await testManifestRoundTrip();
await testTopicMismatch();
console.log('network-manifest.test.js: all passed');
}
run().catch((err) => {
console.error(err);
process.exit(1);
});