Update concensus information RFC 0001

This commit is contained in:
Raven Scott
2026-05-31 00:05:00 -04:00
parent 9ba81425a5
commit 52b6d0b22f
16 changed files with 116 additions and 40 deletions
+2 -2
View File
@@ -303,7 +303,7 @@ export default function AdminPanelPage() {
<li><strong className="text-gray-900 dark:text-white">Plugin logs:</strong> Per-plugin output also available via plugin-log WebSocket messages</li>
</ul>
<p className="text-gray-600 dark:text-gray-300 mb-6">
Use the core channel when debugging invite RPC or consensus issues.
Use the core channel when debugging invite RPC or consensus sidecar init issues. Check <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/consensus/status</code> for sidecar readiness (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">bootstrapComplete</code>, <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">domainCount</code>).
</p>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4 mt-8">Stats</h3>
@@ -553,7 +553,7 @@ export default function AdminPanelPage() {
<li><strong className="text-gray-900 dark:text-white">Clean up interfaces:</strong> Periodically clean unused virtual interfaces to free resources</li>
<li><strong className="text-gray-900 dark:text-white">Manage certificates:</strong> Regenerate certificates if you encounter SSL errors</li>
<li><strong className="text-gray-900 dark:text-white">Use backups for disaster recovery:</strong> Create regular backups using the Backups tab, especially before making major configuration changes. Configure automatic backups via Settings (BACKUP_INTERVAL) and set appropriate retention (BACKUP_RETENTION) to balance disk space and recovery options</li>
<li><strong className="text-gray-900 dark:text-white">Monitor consensus status:</strong> Check consensus badges in the Domains tab to understand network agreement on domain ownership. Resolved status indicates network consensus, while conflicted status may require attention</li>
<li><strong className="text-gray-900 dark:text-white">Monitor consensus status:</strong> Check consensus badges in the Domains tab to understand network agreement on domain ownership. Use <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/consensus/status</code> or the <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">domain.consensus</code> plugin overview for sidecar health</li>
<li><strong className="text-gray-900 dark:text-white">Use diagnostics for troubleshooting:</strong> When experiencing connectivity issues, use the Network Diagnostics tools to test DNS resolution, ping hosts, trace routes, and check port connectivity. This helps isolate network problems quickly</li>
<li><strong className="text-gray-900 dark:text-white">Manage subnet configurations:</strong> Use the Subnet Configuration section in Settings to efficiently manage IP allocation. Monitor IP capacity to ensure you have enough addresses for new domains. Consider adding multiple subnets for better organization</li>
<li><strong className="text-gray-900 dark:text-white">Understand live-reloadable settings:</strong> Take advantage of settings that can be changed without restarting (like LOG_LEVEL) for quick adjustments. Remember that restart-required settings need a node restart to take effect</li>
+4
View File
@@ -86,6 +86,10 @@ export default function APIPage() {
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6 mt-12">Key Endpoints</h2>
<ul className="list-disc pl-6 space-y-2 text-gray-600 dark:text-gray-300">
<li><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/consensus/status</code> - Consensus Autobase sidecar health (bootstrap, event counts)</li>
<li><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/consensus/:domain</code> - Consensus state for a domain (vote counts, quorum, resolved hash)</li>
<li><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/consensus/metrics</code> - Aggregate consensus metrics (includes embedded sidecar status)</li>
<li><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">POST /api/consensus/recalculate</code> - Force consensus recalculation and auto-votes</li>
<li><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/resolved-domains</code> - List all resolved domains with ownership and services</li>
<li><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">POST /api/add-domain</code> - Add a new domain</li>
<li><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">POST /api/remove-domain</code> - Remove a domain</li>
+18 -5
View File
@@ -3,7 +3,7 @@ import ArchitectureDiagram from '@/components/diagrams/ArchitectureDiagram';
export const metadata: Metadata = {
title: 'Architecture - P2NS Documentation',
description: 'P2NS architecture: genesis and secondary masters, joiners, one Autopass ledger, network manifest, and Core RPC.',
description: 'P2NS architecture: genesis and secondary masters, joiners, Autopass write store, Autobase consensus sidecar, network manifest, and Core RPC.',
keywords: ['P2NS architecture', 'system design', 'components', 'technical details', 'P2NS internals'],
authors: [{ name: 'Raven Scott' }],
openGraph: {
@@ -43,10 +43,11 @@ export default function ArchitecturePage() {
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6 mt-12">Core Components</h2>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">Corestore & Autopass</h3>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">Corestore & Autopass (writes)</h3>
<p className="text-gray-600 dark:text-gray-300 mb-4">
Corestore provides decentralized, append-only storage for domain claims and votes. Autopass manages
secure writer additions through an invitation system, ensuring only authorized peers can write to the ledger.
Each claim/vote mutation dual-appends a typed event to the consensus Autobase sidecar.
</p>
<ul className="list-disc pl-6 space-y-2 text-gray-600 dark:text-gray-300">
<li>Stores claims as <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">claim:domain:claimant</code></li>
@@ -57,6 +58,17 @@ export default function ArchitecturePage() {
<li><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">core.status</code> exposes <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">networkId</code> for split-network detection</li>
</ul>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4 mt-8">Autobase Consensus Sidecar (reads)</h3>
<p className="text-gray-600 dark:text-gray-300 mb-4">
Domain resolution reads from a dedicated Autobase apply view (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">p2ns-consensus</code> Corestore namespace)not a per-query scan of Autopass entries.
</p>
<ul className="list-disc pl-6 space-y-2 text-gray-600 dark:text-gray-300">
<li>Sidecar init runs in the background after Autopass pairing (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">startConsensusForNetwork</code>)</li>
<li>Genesis bootstraps by replaying dnsPass claim/vote entries; manifest stores <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">consensusAutobaseKey</code></li>
<li>Joiners replicate the sidecar over swarm connections; read-only nodes hydrate from local dnsPass when needed</li>
<li><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/consensus/status</code> reports sidecar health and bootstrap progress</li>
</ul>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4 mt-8">Core RPC Control Plane</h3>
<p className="text-gray-600 dark:text-gray-300 mb-4">
Core invite and consensus traffic uses protomux RPC on the p2ns swarm connection:
@@ -97,7 +109,7 @@ export default function ArchitecturePage() {
The DNS handler runs a UDP server on port 53 (configurable) that resolves domains through multiple mechanisms:
</p>
<ul className="list-disc pl-6 space-y-2 text-gray-600 dark:text-gray-300">
<li><strong>P2P Resolution:</strong> Queries the Corestore for domain claims</li>
<li><strong>P2P Resolution:</strong> Reads the Autobase consensus sidecar apply view for domain claims</li>
<li><strong>Local DNS:</strong> Checks local_dns.json for custom records</li>
<li><strong>Public DNS Fallback:</strong> Forwards to public DNS servers for non-P2P domains</li>
<li><strong>Conflict Resolution:</strong> Uses selector_cache.json preferences when domains exist in both P2P and public DNS</li>
@@ -128,7 +140,7 @@ export default function ArchitecturePage() {
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6 mt-12">Data Flow</h2>
<ol className="list-decimal pl-6 space-y-3 text-gray-600 dark:text-gray-300">
<li>User queries a domain via DNS (e.g., <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">dig @127.0.0.1 example.tld</code>)</li>
<li>DNS handler checks local_dns.json, then Corestore for P2P claims, then public DNS</li>
<li>DNS handler checks local_dns.json, then the consensus sidecar for P2P claims, then public DNS</li>
<li>If P2P domain, assigns local IP and creates Holesail client if needed</li>
<li>User accesses domain via HTTPS proxy</li>
<li>Proxy routes to local IP, which tunnels through Holesail to the peer</li>
@@ -137,7 +149,8 @@ export default function ArchitecturePage() {
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6 mt-12">Consensus Mechanism</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
P2NS uses a quorum-based voting system for domain claims:
P2NS uses a quorum-based voting system for domain claims. Autopass KV is the durable write store; resolution reads the Autobase sidecar apply view (see{' '}
<a href="https://git.ssh.surf/snxraven/p2ns/src/branch/main/docs/rfcs/0001-autobase-consensus.md" target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:underline">RFC 0001</a>):
</p>
<ul className="list-disc pl-6 space-y-2 text-gray-600 dark:text-gray-300">
<li>When a domain is claimed, peers vote on the claim</li>
+7 -1
View File
@@ -510,7 +510,7 @@ export default function ConfigurationPage() {
<tr>
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-900 dark:text-gray-200"><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">CONSENSUS_TIE_BREAKER</code></td>
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-900 dark:text-gray-200"><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">timestamp</code></td>
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-600 dark:text-gray-300">Strategy for breaking ties between claimants with equal votes. Options: timestamp (prefer oldest claim), claimant_age (prefer longest history), lexicographic (alphabetical ordering).</td>
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-600 dark:text-gray-300">Strategy for breaking ties between claimants with equal votes. Options: timestamp (prefer oldest claim), claimant_age (prefer local writer among tied claimants, else lexicographic), lexicographic (prefer local writer, else alphabetical).</td>
</tr>
<tr>
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-900 dark:text-gray-200"><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">CONSENSUS_VOTE_VALIDATION</code></td>
@@ -522,6 +522,11 @@ export default function ConfigurationPage() {
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-900 dark:text-gray-200"><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">true</code></td>
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-600 dark:text-gray-300">Whether to trigger consensus recalculation immediately when claims or votes change. When false, waits for next periodic check.</td>
</tr>
<tr>
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-900 dark:text-gray-200"><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">CONSENSUS_INIT_TIMEOUT_MS</code></td>
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-900 dark:text-gray-200"><code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">30000</code></td>
<td className="px-4 py-2 border border-gray-300 dark:border-gray-700 text-gray-600 dark:text-gray-300">Timeout for consensus Autobase sidecar ready/update during background init.</td>
</tr>
</tbody>
</table>
</div>
@@ -584,6 +589,7 @@ CONSENSUS_MIN_VOTES=2
CONSENSUS_TIE_BREAKER=timestamp
CONSENSUS_VOTE_VALIDATION=true
CONSENSUS_IMMEDIATE_UPDATE=true
CONSENSUS_INIT_TIMEOUT_MS=30000
# P2P
TOPIC_SEED=p2ns-dns
+1 -1
View File
@@ -75,7 +75,7 @@ cd p2ns`} />
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">Genesis master (once per network)</h3>
<p className="text-gray-600 dark:text-gray-300 mb-4">
Creates the shared Autopass ledger and <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">cache/network.json</code> manifest. Loads <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">domains.json</code> on first run:
Creates the shared Autopass ledger and <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">cache/network.json</code> manifest (including <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">consensusAutobaseKey</code> after sidecar bootstrap). Loads <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">domains.json</code> on first run:
</p>
<CodeBlock code="sudo node p2ns.js --master --genesis" />
<p className="text-gray-600 dark:text-gray-300 mb-4 mt-4">
+23 -14
View File
@@ -66,7 +66,7 @@ export default function HowItWorksPage() {
<P2NSFlowDiagram />
</div>
<p className="text-gray-600 dark:text-gray-300 mb-6">
The key components are: <strong className="text-gray-900 dark:text-white">peers</strong> (Hyperswarm + Corestore/Autopass for DNS state),
The key components are: <strong className="text-gray-900 dark:text-white">peers</strong> (Hyperswarm + Corestore/Autopass for claim/vote writes and an Autobase consensus sidecar for resolution),
<strong className="text-gray-900 dark:text-white"> protomux-rpc</strong> (core invites and plugin traffic),
<strong className="text-gray-900 dark:text-white">Holesail</strong> (per-service tunnels),
<strong className="text-gray-900 dark:text-white">virtual interfaces</strong> (local IPs per domain), and
@@ -97,7 +97,7 @@ export default function HowItWorksPage() {
<p className="text-gray-600 dark:text-gray-300 mb-4">
Next, they register their domain (e.g., <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">example.tld</code>)
by creating a claim in the P2P network. This claim says &quot;I own example.tld and it should point to this Holesail hash.&quot;
Claims live in the shared <strong className="text-gray-900 dark:text-white">Autopass</strong> store (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">dnsPass</code>) on top of Corestore—an append-only, signed log replicated across writers.
Claims live in the shared <strong className="text-gray-900 dark:text-white">Autopass</strong> store (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">dnsPass</code>) on top of Corestore—an append-only, signed log replicated across writers. Each claim/vote write also appends a typed event to the <strong className="text-gray-900 dark:text-white">consensus Autobase sidecar</strong>, which is the sole read path for domain resolution.
</p>
<p className="text-gray-600 dark:text-gray-300 mb-4">
You can add domains via the admin UI (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">https://p2ns.admin</code>),{' '}
@@ -215,12 +215,12 @@ export default function HowItWorksPage() {
<h4 className="text-xl font-semibold text-gray-900 dark:text-white mb-3">4. Querying the P2P Network</h4>
<p className="text-gray-600 dark:text-gray-300 mb-4">
If not in cache, P2NS looks up the domain in the distributed ledger. It searches through all the claims stored locally
(remember, each node has a complete copy) to find any claims for the requested domain.
If not in cache, P2NS resolves the domain through the <strong className="text-gray-900 dark:text-white">consensus Autobase sidecar</strong> apply view.
Claim and vote events are replayed in linearized order; the resolver reads that in-memory view rather than scanning the full Autopass ledger on each query.
</p>
<p className="text-gray-600 dark:text-gray-300 mb-4">
The system looks for entries with keys like <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">claim:example.tld:*</code>
to find all people who have claimed this domain.
Claims originate from Autopass KV keys like <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">claim:example.tld:*</code>;
the sidecar maintains the current per-domain state used for resolution.
</p>
<h4 className="text-xl font-semibold text-gray-900 dark:text-white mb-3">5. Consensus Mechanism</h4>
@@ -387,8 +387,8 @@ export default function HowItWorksPage() {
<li><strong className="text-gray-900 dark:text-white">You type</strong> <code className="bg-gray-200 dark:bg-gray-700 px-1.5 py-0.5 rounded">https://example.tld</code> in your browser</li>
<li><strong className="text-gray-900 dark:text-white">DNS query:</strong> Your system queries the P2NS DNS server (port 53) for <code className="bg-gray-200 dark:bg-gray-700 px-1.5 py-0.5 rounded">example.tld</code></li>
<li><strong className="text-gray-900 dark:text-white">Cache check:</strong> P2NS checks its cache - if found and valid, returns cached result</li>
<li><strong className="text-gray-900 dark:text-white">P2P lookup:</strong> If not cached, P2NS searches the distributed ledger for claims matching <code className="bg-gray-200 dark:bg-gray-700 px-1.5 py-0.5 rounded">example.tld</code></li>
<li><strong className="text-gray-900 dark:text-white">Consensus:</strong> If multiple claims exist, P2NS runs consensus algorithm to determine the correct hash</li>
<li><strong className="text-gray-900 dark:text-white">P2P lookup:</strong> If not cached, P2NS reads the consensus sidecar apply view for claims on <code className="bg-gray-200 dark:bg-gray-700 px-1.5 py-0.5 rounded">example.tld</code></li>
<li><strong className="text-gray-900 dark:text-white">Consensus:</strong> If multiple claims exist, the sidecar resolver applies quorum and tie-break rules to determine the correct hash</li>
<li><strong className="text-gray-900 dark:text-white">Hash retrieved:</strong> P2NS gets the Holesail hash (e.g., <code className="bg-gray-200 dark:bg-gray-700 px-1.5 py-0.5 rounded">hs://s00084bf87dfa89a...</code>)</li>
<li><strong className="text-gray-900 dark:text-white">Virtual interface:</strong> P2NS assigns/uses a local IP (e.g., <code className="bg-gray-200 dark:bg-gray-700 px-1.5 py-0.5 rounded">192.168.3.2</code>) for this domain</li>
<li><strong className="text-gray-900 dark:text-white">Holesail client:</strong> P2NS creates or reuses a Holesail client connection using the hash</li>
@@ -408,9 +408,18 @@ export default function HowItWorksPage() {
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6 mt-12">Consensus and Voting</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
One of the most important aspects of P2NS is how it handles conflicts when multiple people claim the same domain.
The consensus mechanism ensures the network agrees on which service should be associated with each domain.
Autopass KV remains the durable write store; resolution reads from the replicated <strong className="text-gray-900 dark:text-white">Autobase consensus sidecar</strong> (see{' '}
<a href="https://git.ssh.surf/snxraven/p2ns/src/branch/main/docs/rfcs/0001-autobase-consensus.md" target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:underline">RFC 0001</a> in the repository).
</p>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">Dual-store architecture</h3>
<ul className="list-disc pl-6 space-y-2 text-gray-600 dark:text-gray-300 mb-4">
<li><strong className="text-gray-900 dark:text-white">Writes:</strong> Claims and votes are stored in Autopass; each local mutation dual-appends a typed event to the sidecar</li>
<li><strong className="text-gray-900 dark:text-white">Reads:</strong> <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">getConsensusState</code> reads the apply view onlyno KV-scan fallback</li>
<li><strong className="text-gray-900 dark:text-white">Bootstrap:</strong> On first run, existing claim/vote entries are replayed into the sidecar; <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">cache/network.json</code> stores <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">consensusAutobaseKey</code> for joiners</li>
<li><strong className="text-gray-900 dark:text-white">Monitoring:</strong> <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/consensus/status</code> reports sidecar health and bootstrap progress</li>
</ul>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">How Voting Works</h3>
<p className="text-gray-600 dark:text-gray-300 mb-4">
When a peer sees a domain claim, they can vote for it by creating a vote entry in the ledger. The vote key looks like:
@@ -445,8 +454,8 @@ export default function HowItWorksPage() {
</p>
<ul className="list-disc pl-6 space-y-2 text-gray-600 dark:text-gray-300 mb-4">
<li><strong className="text-gray-900 dark:text-white">Timestamp:</strong> Prefer the oldest claim (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">CONSENSUS_TIE_BREAKER=timestamp</code>, default)</li>
<li><strong className="text-gray-900 dark:text-white">Claimant age:</strong> Prefer the claimant with the longest history in the network</li>
<li><strong className="text-gray-900 dark:text-white">Lexicographic:</strong> Alphabetical ordering of claimant IDs</li>
<li><strong className="text-gray-900 dark:text-white">Claimant age:</strong> Prefer the local writer among tied claimants; otherwise lexicographic ordering (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">CONSENSUS_TIE_BREAKER=claimant_age</code>)</li>
<li><strong className="text-gray-900 dark:text-white">Lexicographic:</strong> Prefer local writer, then alphabetical ordering of claimant IDs</li>
</ul>
<p className="text-gray-600 dark:text-gray-300 mb-6">
This deterministic approach ensures all nodes reach the same conclusion when resolving ties, maintaining network consistency.
@@ -473,12 +482,12 @@ export default function HowItWorksPage() {
<strong className="text-gray-900 dark:text-white">Simple analogy:</strong> Several phone lines over one secure callcore control traffic and plugin apps share the same tunnel without mixing messages.
</p>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">Corestore & Autopass</h3>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">Corestore, Autopass & Autobase</h3>
<p className="text-gray-600 dark:text-gray-300 mb-4">
<strong className="text-gray-900 dark:text-white">What it does:</strong> Corestore holds Hypercore append-only logs; Autopass (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">dnsPass</code>) stores claims and votes with invite-gated writers.
<strong className="text-gray-900 dark:text-white">What it does:</strong> Corestore holds Hypercore append-only logs; Autopass (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">dnsPass</code>) stores claims and votes with invite-gated writers. A dedicated Autobase sidecar (<code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">p2ns-consensus</code> namespace) linearizes claim/vote events for deterministic resolution.
</p>
<p className="text-gray-600 dark:text-gray-300 mb-6">
<strong className="text-gray-900 dark:text-white">Simple analogy:</strong> A signed ledger everyone authorized can append toentries are immutable and verifiable by Merkle proofs, not by trusting who sent them.
<strong className="text-gray-900 dark:text-white">Simple analogy:</strong> Autopass is the signed ledger everyone authorized can append to; the sidecar is the ordered replay that tells every node the same current winner for each domain.
</p>
<h3 className="text-2xl font-semibold text-gray-900 dark:text-white mb-4">Holesail</h3>
+1 -1
View File
@@ -63,7 +63,7 @@ const docSections = [
},
{
title: 'Architecture',
description: 'Genesis vs joiner roles, one shared Autopass ledger, and multi-master design',
description: 'Genesis vs joiner roles, Autopass writes, Autobase consensus sidecar, and multi-master design',
icon: Network,
href: '/docs/architecture',
},
+3 -3
View File
@@ -70,9 +70,9 @@ const plugins = [
{
name: 'domain.consensus',
url: null,
description: 'Consensus and domain voting utilities for the network.',
docHref: `${repoBase}/docs/CONSENSUS.md`,
docLabel: 'Consensus docs',
description: 'Consensus dashboard with sidecar health, vote counts, and domain resolution status.',
docHref: `${repoBase}/docs/plugins/domain.consensus.md`,
docLabel: 'domain.consensus plugin docs',
},
{
name: 'example.plugin',
+12
View File
@@ -159,6 +159,18 @@ curl -k https://p2ns.admin/api/interfaces`} />
</p>
<CodeBlock code="sudo node p2ns.js --clean [--master] [--genesis]" />
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6 mt-12">Consensus sidecar not ready</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
If domains show unresolved consensus or logs mention local hash fallback, the Autobase consensus sidecar may not be bootstrapped yet:
</p>
<ul className="list-disc pl-6 space-y-2 text-gray-600 dark:text-gray-300 mb-4">
<li>Check <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/consensus/status</code> confirm <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">open</code>, <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">ready</code>, and <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">bootstrapComplete</code></li>
<li>Ensure dnsPass is initialized (master paired or joiner invited) before expecting resolved consensus</li>
<li>Verify <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">cache/network.json</code> includes <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">consensusAutobaseKey</code> on joiners</li>
<li>Tail the <strong>core</strong> log for <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">ConsensusAutobase</code> errors or <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">CONSENSUS_INIT_TIMEOUT_MS</code> timeouts</li>
<li>Restart the node; bootstrap/hydration replays claim/vote entries from the local dnsPass copy</li>
</ul>
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6 mt-12">Split network / wrong ledger</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
If peers connect on Hyperswarm but claims never converge, you may have two Autopass universes on the same <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">TOPIC_SEED</code> (historically caused by multiple <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">--master</code> nodes on empty storage). Current releases require explicit <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">--genesis</code> to create a ledger.
+18
View File
@@ -73,6 +73,18 @@ export default function UpgradingPage() {
Plugin peer communication is also RPC-only.
</p>
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">Autobase consensus sidecar</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
Current releases use an Autobase apply-based consensus sidecar as the sole read path for domain resolution (RFC 0001).
Autopass KV data is unchangedupgrading rebuilds the sidecar from bootstrap replay of local claim/vote entries.
</p>
<ul className="list-disc pl-6 space-y-2 text-gray-600 dark:text-gray-300 mb-6">
<li>No storage wipe required solely for the consensus cutover if dnsPass data is intact</li>
<li>After upgrade, verify <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">GET /api/consensus/status</code> shows <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">bootstrapComplete: true</code></li>
<li>Manifest gains <code className="bg-gray-800 dark:bg-gray-700 text-gray-100 dark:text-gray-200 px-1.5 py-0.5 rounded">consensusAutobaseKey</code> on first genesis sidecar bootstrap</li>
<li>Rollback: deploy the previous P2NS release; Autopass data is unchanged</li>
</ul>
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-6">When to reset storage</h2>
<p className="text-gray-600 dark:text-gray-300 mb-4">
After a Holepunch stack upgrade (Corestore, Autopass, HyperDB, etc.), existing on-disk P2P storage
@@ -148,6 +160,12 @@ export default function UpgradingPage() {
<li>
<a href={`${repoBase}/docs/RESTAPI.md`} target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:underline">REST API (full reference)</a>
</li>
<li>
<a href={`${repoBase}/docs/rfcs/0001-autobase-consensus.md`} target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:underline">RFC 0001: Autobase consensus sidecar</a>
</li>
<li>
<a href={`${repoBase}/docs/CONSENSUS.md`} target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:underline">Consensus mechanism (CONSENSUS.md)</a>
</li>
<li>
<a href={`${repoBase}/docs/plugins/HYPERDB.md`} target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 hover:underline">HyperDB recovery and version migration</a>
</li>