Files
p2ns/test-scripts/consensus-resolver.test.js
T
Raven Scott d230fb3360 EXPERIMENTAL: replace KV-scan consensus with Autobase sidecar engine
Cut over domain resolution to an Autobase apply-based sidecar fed by
claim/vote dual-writes from dnsPass. Remove the legacy full-KV scan
getConsensusState path and wire all reads through consensus-view.

- Add consensus-resolver, consensus-events, consensus-apply,
  consensus-autobase, and consensus-view modules
- Dual-append consensus events on claim/vote dnsPassAdd/Remove
- Bootstrap sidecar from existing KV entries; persist
  consensusAutobaseKey in network manifest
- Expose sidecar health via GET /api/consensus/status and metrics
- Add consensus-resolver and consensus-apply unit tests
- Expand RFC 0001 to Implemented; update CONSENSUS.md

Rollback: deploy prior release; KV data unchanged, sidecar rebuilds on
next startup.
2026-05-30 23:49:48 -04:00

184 lines
5.4 KiB
JavaScript

#!/usr/bin/env node
/**
* Unit tests for consensus-resolver.js
*/
const assert = require('assert');
const {
parseClaimValue,
resolveDomainConsensus,
applyTieBreaker,
LEGACY_CLAIM_TIMESTAMP
} = require('../includes/core/consensus-resolver');
const DEFAULT_CONFIG = {
CONSENSUS_QUORUM_THRESHOLD: 0.5,
CONSENSUS_MIN_VOTES: 2,
CONSENSUS_TIE_BREAKER: 'timestamp',
CONSENSUS_VOTE_VALIDATION: true
};
const LOCAL = 'local-peer-key';
const REMOTE_A = 'remote-a-key';
const REMOTE_B = 'remote-b-key';
function resolve(domain, claims, voterVotes, overrides = {}) {
return resolveDomainConsensus({
domain,
claims,
voterVotes,
config: { ...DEFAULT_CONFIG, ...overrides.config },
localWriter: overrides.localWriter ?? LOCAL,
activePeers: overrides.activePeers ?? 4
});
}
function testLegacyClaimTimestamp() {
const parsed = parseClaimValue('hs://legacy-hash');
assert.strictEqual(parsed.timestamp, LEGACY_CLAIM_TIMESTAMP);
assert.strictEqual(parsed.legacy, true);
}
function testNoClaims() {
const state = resolve('example.test', {}, {});
assert.strictEqual(state.status, 'no_claims');
assert.strictEqual(state.hash, null);
}
function testSingleLocalClaim() {
const state = resolve(
'solo.test',
{ [LOCAL]: { hash: 'hs://solo', timestamp: 1000 } },
{}
);
assert.strictEqual(state.status, 'resolved');
assert.strictEqual(state.resolvedClaimant, LOCAL);
assert.strictEqual(state.hash, 'hs://solo');
}
function testInsufficientQuorum() {
const state = resolve(
'quorum.test',
{
[LOCAL]: { hash: 'hs://local', timestamp: 1000 },
[REMOTE_A]: { hash: 'hs://remote', timestamp: 2000 }
},
{ [LOCAL]: LOCAL },
{ activePeers: 10 }
);
assert.strictEqual(state.status, 'insufficient_quorum');
assert.strictEqual(state.quorumMet, false);
}
function testQuorumResolved() {
const claims = {
[LOCAL]: { hash: 'hs://local', timestamp: 1000 },
[REMOTE_A]: { hash: 'hs://remote', timestamp: 2000 }
};
const votes = {
voter1: LOCAL,
voter2: LOCAL,
voter3: LOCAL
};
const state = resolve('winner.test', claims, votes, { activePeers: 4 });
assert.strictEqual(state.status, 'resolved');
assert.strictEqual(state.resolvedClaimant, LOCAL);
}
function testVoteValidationDisabled() {
const state = resolve(
'noval.test',
{ [LOCAL]: { hash: 'hs://local', timestamp: 1 } },
{ voter1: REMOTE_A, voter2: REMOTE_A, voter3: REMOTE_A },
{ config: { CONSENSUS_VOTE_VALIDATION: false }, activePeers: 4 }
);
assert.strictEqual(state.status, 'resolved');
assert.strictEqual(state.resolvedClaimant, REMOTE_A);
}
function testVoteValidationEnabled() {
const state = resolve(
'val.test',
{
[LOCAL]: { hash: 'hs://local', timestamp: 1 },
[REMOTE_A]: { hash: 'hs://remote', timestamp: 2 }
},
{ voter1: REMOTE_B, voter2: REMOTE_B, voter3: REMOTE_B },
{ activePeers: 4 }
);
assert.strictEqual(state.status, 'insufficient_quorum');
}
function testTieTimestamp() {
const claims = {
[REMOTE_A]: { hash: 'hs://a', timestamp: 5000 },
[REMOTE_B]: { hash: 'hs://b', timestamp: 1000 }
};
const votes = { v1: REMOTE_A, v2: REMOTE_B, v3: REMOTE_A, v4: REMOTE_B };
const state = resolve('tie.test', claims, votes, {
activePeers: 4,
localWriter: 'other-peer'
});
assert.strictEqual(state.status, 'tie');
assert.strictEqual(state.resolvedClaimant, REMOTE_B);
}
function testTieBreakerLexicographicPrefersLocal() {
const winner = applyTieBreaker([REMOTE_B, LOCAL], {}, LOCAL, 'lexicographic');
assert.strictEqual(winner, LOCAL);
}
function testDuplicateVoteLastWinsViaOrderedReplay() {
const { createEmptyViewState, applyEventToView } = require('../includes/core/consensus-apply');
const { EVENT_TYPES } = require('../includes/core/consensus-events');
const view = createEmptyViewState();
const domain = 'dup.test';
applyEventToView(view, {
type: EVENT_TYPES.CLAIM_UPSERT,
domain,
claimant: REMOTE_A,
hash: 'hs://a',
timestamp: 1,
ssl: false,
clients: []
});
applyEventToView(view, {
type: EVENT_TYPES.CLAIM_UPSERT,
domain,
claimant: REMOTE_B,
hash: 'hs://b',
timestamp: 2,
ssl: false,
clients: []
});
applyEventToView(view, { type: EVENT_TYPES.VOTE_UPSERT, domain, claimant: REMOTE_A, voter: 'voter1' });
applyEventToView(view, { type: EVENT_TYPES.VOTE_UPSERT, domain, claimant: REMOTE_B, voter: 'voter1' });
applyEventToView(view, { type: EVENT_TYPES.VOTE_UPSERT, domain, claimant: REMOTE_A, voter: 'voter2' });
applyEventToView(view, { type: EVENT_TYPES.VOTE_UPSERT, domain, claimant: REMOTE_A, voter: 'voter3' });
const domainState = view.domains.get(domain);
assert.strictEqual(domainState.voterVotes.get('voter1'), REMOTE_B);
const { buildDomainSnapshotFromView } = require('../includes/core/consensus-resolver');
const snapshot = buildDomainSnapshotFromView(view, domain);
const state = resolve(domain, snapshot.claims, snapshot.voterVotes, { activePeers: 4, localWriter: 'x' });
assert.strictEqual(state.resolvedClaimant, REMOTE_A);
}
function run() {
testLegacyClaimTimestamp();
testNoClaims();
testSingleLocalClaim();
testInsufficientQuorum();
testQuorumResolved();
testVoteValidationDisabled();
testVoteValidationEnabled();
testTieTimestamp();
testTieBreakerLexicographicPrefersLocal();
testDuplicateVoteLastWinsViaOrderedReplay();
console.log('consensus-resolver.test.js: all passed');
}
run();