feat: Add separate message for conflict claim removalImplement removeConflictDomainClaim: message type to distinguish betweenfull domain cleanup and conflict claim removal, ensuring other peers'claims are preserved when removing conflicting claims.- Add sendConflictClaimRemoval() function for notification broadcasting- Add handler for removeConflictDomainClaim: messages that updates consensus but does NOT remove other peers' claims- Modify removal logic to conditionally broadcast based on claimant status: - Resolved claimants: broadcast remove_domain: (full cleanup) - Non-resolved claimants: broadcast removeConflictDomainClaim: (notification only)- Update admin routes and SDK to use conditional broadcastingPrevents cross-peer claim deletion when removing conflict claims whilemaintaining proper consensus updates and full cleanup functionality.
This commit is contained in:
@@ -205,17 +205,24 @@ async function handleDomainsRoutes(req, res) {
|
|||||||
// Full removal: user is the resolved claimant
|
// Full removal: user is the resolved claimant
|
||||||
logInfo('Admin', `User is resolved claimant for ${domain}, performing full cleanup`);
|
logInfo('Admin', `User is resolved claimant for ${domain}, performing full cleanup`);
|
||||||
await atomicDomainCleanup(domain);
|
await atomicDomainCleanup(domain);
|
||||||
|
|
||||||
|
// Broadcast full removal request (triggers other peers to clean up their claims)
|
||||||
|
if (state.sendRemovalRequest) {
|
||||||
|
state.sendRemovalRequest(domain);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Partial removal: user has claim but isn't the resolved claimant
|
// Partial removal: user has claim but isn't the resolved claimant (conflict scenario)
|
||||||
// This includes cases where:
|
// This includes cases where:
|
||||||
// - Consensus is not resolved
|
// - Consensus is not resolved
|
||||||
// - User is not the resolved claimant (conflict scenario)
|
// - User is not the resolved claimant (conflict scenario)
|
||||||
// - Resolved claimant is null/undefined
|
// - Resolved claimant is null/undefined
|
||||||
logInfo('Admin', `User is NOT resolved claimant for ${domain} (status=${consensusState.status}, resolvedClaimant=${consensusState.resolvedClaimant}), removing only own claim and votes`);
|
logInfo('Admin', `User is NOT resolved claimant for ${domain} (status=${consensusState.status}, resolvedClaimant=${consensusState.resolvedClaimant}), removing only own claim and votes`);
|
||||||
await removeOwnClaimAndVotes(domain, localWriter);
|
await removeOwnClaimAndVotes(domain, localWriter);
|
||||||
|
|
||||||
|
// Broadcast conflict claim removal notification (does NOT trigger other peers to remove)
|
||||||
|
if (state.sendConflictClaimRemoval) {
|
||||||
|
state.sendConflictClaimRemoval(domain);
|
||||||
}
|
}
|
||||||
if (state.sendRemovalRequest) {
|
|
||||||
state.sendRemovalRequest(domain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup hash preferences if domain was removed
|
// Cleanup hash preferences if domain was removed
|
||||||
|
|||||||
@@ -205,17 +205,24 @@ async function handleDomainsRoutes(req, res) {
|
|||||||
// Full removal: user is the resolved claimant
|
// Full removal: user is the resolved claimant
|
||||||
logInfo('Admin', `User is resolved claimant for ${domain}, performing full cleanup`);
|
logInfo('Admin', `User is resolved claimant for ${domain}, performing full cleanup`);
|
||||||
await atomicDomainCleanup(domain);
|
await atomicDomainCleanup(domain);
|
||||||
|
|
||||||
|
// Broadcast full removal request (triggers other peers to clean up their claims)
|
||||||
|
if (state.sendRemovalRequest) {
|
||||||
|
state.sendRemovalRequest(domain);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Partial removal: user has claim but isn't the resolved claimant
|
// Partial removal: user has claim but isn't the resolved claimant (conflict scenario)
|
||||||
// This includes cases where:
|
// This includes cases where:
|
||||||
// - Consensus is not resolved
|
// - Consensus is not resolved
|
||||||
// - User is not the resolved claimant (conflict scenario)
|
// - User is not the resolved claimant (conflict scenario)
|
||||||
// - Resolved claimant is null/undefined
|
// - Resolved claimant is null/undefined
|
||||||
logInfo('Admin', `User is NOT resolved claimant for ${domain} (status=${consensusState.status}, resolvedClaimant=${consensusState.resolvedClaimant}), removing only own claim and votes`);
|
logInfo('Admin', `User is NOT resolved claimant for ${domain} (status=${consensusState.status}, resolvedClaimant=${consensusState.resolvedClaimant}), removing only own claim and votes`);
|
||||||
await removeOwnClaimAndVotes(domain, localWriter);
|
await removeOwnClaimAndVotes(domain, localWriter);
|
||||||
|
|
||||||
|
// Broadcast conflict claim removal notification (does NOT trigger other peers to remove)
|
||||||
|
if (state.sendConflictClaimRemoval) {
|
||||||
|
state.sendConflictClaimRemoval(domain);
|
||||||
}
|
}
|
||||||
if (state.sendRemovalRequest) {
|
|
||||||
state.sendRemovalRequest(domain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup hash preferences if domain was removed
|
// Cleanup hash preferences if domain was removed
|
||||||
|
|||||||
+10
-5
@@ -669,15 +669,20 @@ const sdk = {
|
|||||||
if (isResolvedClaimant) {
|
if (isResolvedClaimant) {
|
||||||
// Full removal: user is the resolved claimant
|
// Full removal: user is the resolved claimant
|
||||||
await atomicDomainCleanup(domain);
|
await atomicDomainCleanup(domain);
|
||||||
} else {
|
|
||||||
// Partial removal: user has claim but isn't the resolved claimant
|
|
||||||
await removeOwnClaimAndVotes(domain, localWriter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Broadcast removal request to peers if available
|
// Broadcast full removal request (triggers other peers to clean up their claims)
|
||||||
if (state.sendRemovalRequest) {
|
if (state.sendRemovalRequest) {
|
||||||
state.sendRemovalRequest(domain);
|
state.sendRemovalRequest(domain);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Partial removal: user has claim but isn't the resolved claimant (conflict scenario)
|
||||||
|
await removeOwnClaimAndVotes(domain, localWriter);
|
||||||
|
|
||||||
|
// Broadcast conflict claim removal notification (does NOT trigger other peers to remove)
|
||||||
|
if (state.sendConflictClaimRemoval) {
|
||||||
|
state.sendConflictClaimRemoval(domain);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -520,6 +520,14 @@ async function main() {
|
|||||||
}
|
}
|
||||||
state.sendConsensusRequest = sendConsensusRequest;
|
state.sendConsensusRequest = sendConsensusRequest;
|
||||||
|
|
||||||
|
// Function to send conflict claim removal notification to all peers
|
||||||
|
function sendConflictClaimRemoval(domain) {
|
||||||
|
// Use channel-manager broadcast to send to all peers
|
||||||
|
const count = channelManager.broadcastToPeers(CORE_DOMAIN, 'request', `removeConflictDomainClaim:${domain}`);
|
||||||
|
logDebug('Main', `Sent conflict claim removal notification for ${domain} to ${count} peers`);
|
||||||
|
}
|
||||||
|
state.sendConflictClaimRemoval = sendConflictClaimRemoval;
|
||||||
|
|
||||||
// Register invite channel for sending/receiving invites
|
// Register invite channel for sending/receiving invites
|
||||||
channelManager.registerPluginChannel(CORE_DOMAIN, 'invite', {
|
channelManager.registerPluginChannel(CORE_DOMAIN, 'invite', {
|
||||||
encoding: 'string',
|
encoding: 'string',
|
||||||
@@ -959,6 +967,23 @@ async function main() {
|
|||||||
const allEntries = await getAllEntries();
|
const allEntries = await getAllEntries();
|
||||||
await autoVoteForDomain(domain, allEntries);
|
await autoVoteForDomain(domain, allEntries);
|
||||||
}
|
}
|
||||||
|
} else if (message.startsWith('removeConflictDomainClaim:')) {
|
||||||
|
const domain = message.slice(26); // Length of "removeConflictDomainClaim:"
|
||||||
|
logDebug('Swarm', `Received conflict claim removal notification for domain: ${domain}`);
|
||||||
|
|
||||||
|
// This is just a notification - don't remove anything
|
||||||
|
// The peer that sent this already removed their own conflict claim
|
||||||
|
// We should invalidate cache to refresh consensus state, but NOT remove our claims
|
||||||
|
const { invalidateEntriesCache } = require('./includes/core/core');
|
||||||
|
invalidateEntriesCache();
|
||||||
|
|
||||||
|
// Trigger consensus recalculation since a claim was removed
|
||||||
|
const { doAutoVotes } = require('./includes/core/core');
|
||||||
|
doAutoVotes().catch(err => {
|
||||||
|
logWarn('Swarm', `Error recalculating consensus after conflict claim removal: ${err.message}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
logInfo('Swarm', `Processed conflict claim removal notification for ${domain} - other claims preserved`);
|
||||||
} else {
|
} else {
|
||||||
logWarn('Swarm', `Unknown message from ${peerId}: ${message}`);
|
logWarn('Swarm', `Unknown message from ${peerId}: ${message}`);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user