feat: allow partial domain removal and add conflict status

- Add partial domain removal functionality allowing users to remove their own claims and votes even when they're not the resolved claimant
- Add conflict status detection for domains where local peer has claim but another claimant won consensus
- Update UI to display conflict status with red badge
- Enhance API responses with detailed consensus information
- Update all documentation with new features

Changes:
- core/core.js: Add removeOwnClaimAndVotes() function for partial removal
- admin/routes/domains.js: Implement partial/full removal logic in /api/remove-domain
- admin/admin-backend/routes/domains.js: Same partial removal logic for backend routes
- plugins/sdk.js: Update removeDomain() to support partial removal
- admin/ui/config.js: Add conflict status badge and update postFetch
- admin/admin-frontend/ui/config.js: Add conflict status badge and fix status rendering
- admin/utils.js: Add conflict status to utility functions
- admin/admin-frontend/utils.js: Add conflict status to utility functions
- docs/CONSENSUS.md: Add conflict status to resolution states
- docs/README_LONGFORM.md: Add conflict status to consensus states
- docs/RESTAPI.md: Update /api/resolved-domains with new fields and examples
- docs/ARCHITECTURE.md: Document full vs partial removal modes
- docs/OPENAPI.yaml: Update Domain schema and add ConsensusState schema
This commit is contained in:
Raven Scott
2025-12-26 15:32:41 -05:00
parent ea1bcb569a
commit 480f99ae28
13 changed files with 234 additions and 61 deletions
+5 -1
View File
@@ -35,11 +35,15 @@ Domain management including:
### `core/domain_cleanup.js`
Comprehensive domain removal including:
- P2P network claim removal
- P2P network claim removal (full removal for resolved claimants, partial removal for competing claims)
- Holesail client cleanup
- Virtual interface removal
- DNS preference cleanup
Supports two removal modes:
- **Full removal**: When user is the resolved claimant, removes all claims, votes, and infrastructure
- **Partial removal**: When user has a competing claim, removes only their claim and votes they cast
## Infrastructure Modules
### `infrastructure/logger.js`
+1
View File
@@ -108,6 +108,7 @@ Where:
| Status | Description |
|--------|-------------|
| `resolved` | Single winner determined by vote count or tie-breaker |
| `conflict` | Domain resolved to another claimant, but local peer has a competing claim |
| `insufficient_quorum` | Not enough votes to reach consensus |
| `tie` | Multiple claimants tied; resolved via tie-breaker |
| `no_claims` | No claims exist for this domain |
+45
View File
@@ -822,9 +822,19 @@ components:
type: string
hash:
type: string
isLocal:
type: boolean
description: Whether the local writer has a claim for this domain
isOwner:
type: boolean
description: Whether the local writer is the resolved claimant (owner) of this domain
consensusState:
$ref: '#/components/schemas/ConsensusState'
description: Detailed consensus information for this domain
consensusStatus:
type: string
enum: [resolved, conflict, insufficient_quorum, tie, no_claims, error, internal]
description: Simplified consensus status, may include 'conflict' for domains where local peer has claim but another claimant won
services:
type: array
items:
@@ -1227,6 +1237,41 @@ components:
type: string
description: Error message if status is error
ConsensusState:
type: object
description: Detailed consensus state for a specific domain
properties:
status:
type: string
enum: [resolved, conflict, insufficient_quorum, tie, no_claims, error]
description: Current consensus status
hash:
type: string
description: Resolved hash for the domain (null if not resolved)
resolvedClaimant:
type: string
description: Public key of the resolved claimant (null if not resolved)
voteCounts:
type: object
additionalProperties:
type: integer
description: Vote counts per claimant (claimant -> vote count)
activePeers:
type: integer
description: Number of active peers in the network
quorumMet:
type: boolean
description: Whether quorum requirements were met
minVotes:
type: integer
description: Minimum votes required for quorum
totalVotes:
type: integer
description: Total votes cast for this domain
lastResolution:
type: integer
description: Timestamp of last resolution attempt
ConsensusMetrics:
type: object
description: Overall consensus metrics
+2 -1
View File
@@ -332,11 +332,12 @@ When multiple claimants have the same number of votes, a tie-breaking strategy i
A domain can be in one of several consensus states:
- **`resolved`**: The domain has been successfully resolved with a clear winner and quorum met.
- **`conflict`**: Domain resolved to another claimant, but local peer has a competing claim.
- **`insufficient_quorum`**: There are claims but not enough votes to meet the quorum threshold.
- **`tie`**: Multiple claimants have the same number of votes (tie-breaker applied).
- **`no_claims`**: No claims exist for this domain.
Only domains in the `resolved` state will return a hash for DNS resolution. Other states indicate that consensus has not yet been reached.
Only domains in the `resolved` state will return a hash for DNS resolution. Other states indicate that consensus has not yet been reached. The `conflict` state indicates that while the domain is resolved to another claimant, the local peer still maintains a competing claim.
### Consensus Configuration
+49 -7
View File
@@ -72,11 +72,14 @@ The P2NS (Peer-to-Peer Name System) admin backend API, hosted at `https://p2ns.a
```
### 4. GET /api/resolved-domains
- **Description**: Retrieves a list of resolved domains with their hashes, local status, ownership, and available services.
- **Description**: Retrieves a list of resolved domains with their hashes, local status, ownership, consensus information, and available services.
- **Response**: JSON array of objects with:
- `domain` (string): Domain name
- `hash` (string): Holesail hash or `"internal"` for internal domains
- `isLocal` (boolean): Whether the local writer has a claim for this domain
- `isOwner` (boolean): Whether the local writer is the resolved claimant (owner) of this domain
- `consensusState` (object): Detailed consensus information including status, vote counts, quorum status, etc.
- `consensusStatus` (string): Simplified status that may include `"conflict"` for domains where local peer has a claim but another claimant won
- `services` (array): Array of service objects with `serviceName`, `key`, `port`, and `protocol` fields
- **Status Codes**:
- `200`: Success.
@@ -88,10 +91,25 @@ The P2NS (Peer-to-Peer Name System) admin backend API, hosted at `https://p2ns.a
```
```json
[
{
"domain": "example.tld",
"hash": "hs://s00084bf...",
{
"domain": "example.tld",
"hash": "hs://s00084bf...",
"isLocal": true,
"isOwner": true,
"consensusState": {
"status": "resolved",
"hash": "hs://s00084bf...",
"resolvedClaimant": "a6a6d7ebcc1df8f33410067bf96ad2cc30d5276516f758bb0f34195e914c451f",
"voteCounts": {
"a6a6d7ebcc1df8f33410067bf96ad2cc30d5276516f758bb0f34195e914c451f": 8
},
"activePeers": 5,
"quorumMet": true,
"minVotes": 2,
"totalVotes": 8,
"lastResolution": 1766780982538
},
"consensusStatus": "resolved",
"services": [
{
"serviceName": "web",
@@ -101,10 +119,34 @@ The P2NS (Peer-to-Peer Name System) admin backend API, hosted at `https://p2ns.a
}
]
},
{
"domain": "peer.directory",
"hash": "internal",
{
"domain": "bm.git",
"hash": "hs://s000f44fb5cfe3fa7f37e9070ea14975a8dbf1e2156689638bc92458118df7a4987b",
"isLocal": true,
"isOwner": false,
"consensusState": {
"status": "resolved",
"hash": "hs://s000f44fb5cfe3fa7f37e9070ea14975a8dbf1e2156689638bc92458118df7a4987b",
"resolvedClaimant": "acbb3b69ee810f4fbe54927a5742530e4cf76b7b462a4c37ddfe27ba5c3060b6",
"voteCounts": {
"a6a6d7ebcc1df8f33410067bf96ad2cc30d5276516f758bb0f34195e914c451f": 1,
"acbb3b69ee810f4fbe54927a5742530e4cf76b7b462a4c37ddfe27ba5c3060b6": 7
},
"activePeers": 5,
"quorumMet": true,
"minVotes": 2,
"totalVotes": 8,
"lastResolution": 1766780982538
},
"consensusStatus": "conflict",
"services": []
},
{
"domain": "peer.directory",
"hash": "internal",
"isLocal": true,
"isOwner": true,
"consensusStatus": "internal",
"services": []
}
]