mirror of
https://relay.ngit.dev/npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr/ngit-grasp.git
synced 2026-10-06 07:28:23 +00:00
fix(nostr): ignore vanish in disrespector mode
This commit is contained in:
@@ -31,8 +31,16 @@ relay policy code:
|
||||
- holding DB uses `process_nip09(false)` and `process_nip62(false)`
|
||||
(`src/nostr/holding.rs`)
|
||||
|
||||
This keeps deletion behavior auditable and consistent across cascade, holding,
|
||||
archive, and recovery flows.
|
||||
This keeps deletion behavior auditable and prevents the storage backends from
|
||||
silently applying deletion semantics outside ngit-grasp policy code.
|
||||
|
||||
The full cascade, holding, archive, and recovery flow currently applies to
|
||||
NIP-09 repository/content deletions and operator-driven blacklist/whitelist
|
||||
deletions. NIP-62 request-to-vanish handling is narrower: in normal mode a
|
||||
targeted vanish request records a vanish tombstone, removes that author's events
|
||||
from the main database, and evicts that author's purgatory entries. It does not
|
||||
currently move those events through the holding database or archive/recovery
|
||||
pipeline.
|
||||
|
||||
## The Left-Pad Problem
|
||||
|
||||
@@ -677,7 +685,7 @@ Deletion support is **conditionally advertised** in NIP-11 relay information
|
||||
(implemented in [`src/http/nip11.rs`](../../src/http/nip11.rs)):
|
||||
|
||||
- **When `deletion_request_disrespector = false`:** include `9` (`"deletion"`) and `62` (`"request to vanish"`) in the supported NIPs array
|
||||
- **When `deletion_request_disrespector = true`:** do NOT include `9` or `62` (archival mode doesn't honor deletions)
|
||||
- **When `deletion_request_disrespector = true`:** do NOT include `9` or `62` (archival mode stores but does not honor deletion or vanish requests)
|
||||
|
||||
This allows clients to discover whether a relay respects deletion requests.
|
||||
|
||||
|
||||
@@ -73,7 +73,8 @@ impl DeletionPolicy {
|
||||
/// main database) so clients see an OK and the request is preserved, but it
|
||||
/// is NOT acted upon — no purgatory eviction, no main-DB deletion, and no
|
||||
/// tombstone recording. The targeted events therefore remain fully
|
||||
/// accessible. This only affects NIP-09 user-initiated deletions.
|
||||
/// accessible. The same archival-mode contract is applied to NIP-62 vanish
|
||||
/// requests in [`DeletionService::handle_vanish`](super::service::DeletionService::handle_vanish).
|
||||
pub async fn handle(&self, event: &Event) -> WritePolicyResult {
|
||||
// Archival mode: store the deletion request but do not process it.
|
||||
if self.ctx.config.deletion_request_disrespector {
|
||||
|
||||
@@ -78,6 +78,16 @@ impl DeletionService {
|
||||
}
|
||||
|
||||
pub async fn handle_vanish(&self, event: &Event) -> WritePolicyResult {
|
||||
// Archival mode: store the vanish request but do not process it.
|
||||
if self.ctx.config.deletion_request_disrespector {
|
||||
tracing::info!(
|
||||
event_id = %event.id.to_hex(),
|
||||
author = %event.pubkey.to_hex(),
|
||||
"Disrespector mode: storing NIP-62 vanish request without acting on it"
|
||||
);
|
||||
return WritePolicyResult::Accept;
|
||||
}
|
||||
|
||||
// Only honour requests that target this relay (or all relays). We do not
|
||||
// configure a relay_url on the database, matching the historical
|
||||
// behaviour where only ALL_RELAYS requests were actioned; but we accept
|
||||
|
||||
@@ -9,15 +9,16 @@
|
||||
//! purgatory based, so the disrespector simply accepts the kind-5 request and
|
||||
//! does nothing with it. The two properties under test are:
|
||||
//!
|
||||
//! 1. **Disrespector accepts but ignores deletion** — a kind-5 request gets an
|
||||
//! `OK`, yet the targeted announcement remains queryable afterwards.
|
||||
//! 1. **Disrespector accepts but ignores deletion/vanish** — a kind-5 or
|
||||
//! kind-62 request gets an `OK`, yet the targeted/author events remain
|
||||
//! queryable afterwards and no vanish tombstone is laid down.
|
||||
//! 2. **NIP-11 advertisement** — a disrespector relay omits `9` and `62` from
|
||||
//! `supported_nips`; a normal relay advertises both.
|
||||
//!
|
||||
//! The normal-mode baseline ("a default relay honours the deletion") lives in
|
||||
//! `nip09_validation.rs` as `normal_mode_honours_deletion`. Shared helpers
|
||||
//! (`publish_served_repo`, `announcement_served_by_coordinate`,
|
||||
//! `announcement_coordinate`, `build_deletion`) live in
|
||||
//! `announcement_coordinate`, `build_deletion`, `build_vanish`) live in
|
||||
//! `tests/common/nip09_helpers.rs`.
|
||||
//!
|
||||
//! # Running
|
||||
@@ -30,7 +31,7 @@
|
||||
mod common;
|
||||
|
||||
use common::{
|
||||
announcement_coordinate, announcement_served_by_coordinate, build_deletion,
|
||||
announcement_coordinate, announcement_served_by_coordinate, build_deletion, build_vanish,
|
||||
publish_served_repo, TestRelay,
|
||||
};
|
||||
|
||||
@@ -98,6 +99,87 @@ async fn disrespector_accepts_but_ignores_deletion() {
|
||||
);
|
||||
}
|
||||
|
||||
/// Disrespector mode: the kind-62 vanish request is accepted (OK) but ignored —
|
||||
/// the author's events remain queryable and future writes are not blocked by a
|
||||
/// vanish tombstone.
|
||||
#[tokio::test]
|
||||
async fn disrespector_accepts_but_ignores_vanish() {
|
||||
let relay = TestRelay::start_with_deletion_disrespector().await;
|
||||
let client = AuditClient::new(relay.url(), AuditConfig::isolated())
|
||||
.await
|
||||
.expect("create audit client");
|
||||
|
||||
let (announcement, repo_id) = publish_served_repo(&client, "disrespector-vanish").await;
|
||||
let vanish = build_vanish(&client, None);
|
||||
let vanish_id = vanish.id;
|
||||
|
||||
// The relay MUST accept the vanish request (archival mode still stores/acks it).
|
||||
client
|
||||
.send_event(vanish)
|
||||
.await
|
||||
.expect("disrespector relay should OK the kind-62 vanish request");
|
||||
|
||||
tokio::time::sleep(std::time::Duration::from_millis(300)).await;
|
||||
|
||||
let vanish_served = client
|
||||
.is_event_on_relay(vanish_id)
|
||||
.await
|
||||
.expect("query kind-62 vanish after send");
|
||||
let target_served_by_id = client
|
||||
.is_event_on_relay(announcement.id)
|
||||
.await
|
||||
.expect("query announcement by id after vanish");
|
||||
let target_served_by_coordinate =
|
||||
announcement_served_by_coordinate(&client, &announcement, &repo_id).await;
|
||||
|
||||
let later_issue = client
|
||||
.create_issue(
|
||||
&announcement,
|
||||
"Post-ignored-vanish issue",
|
||||
"still allowed",
|
||||
vec![],
|
||||
)
|
||||
.expect("build post-vanish issue");
|
||||
let later_issue_id = later_issue.id;
|
||||
let later_issue_result = client.send_event(later_issue).await;
|
||||
|
||||
tokio::time::sleep(std::time::Duration::from_millis(300)).await;
|
||||
let later_issue_served = client
|
||||
.is_event_on_relay(later_issue_id)
|
||||
.await
|
||||
.expect("query post-ignored-vanish issue");
|
||||
|
||||
relay.stop().await;
|
||||
|
||||
assert!(
|
||||
vanish_served,
|
||||
"disrespector relay must store/serve the kind-62 vanish request itself (id {})",
|
||||
vanish_id
|
||||
);
|
||||
assert!(
|
||||
target_served_by_id,
|
||||
"disrespector relay must ignore vanish: announcement {} should still be \
|
||||
queryable by id",
|
||||
announcement.id
|
||||
);
|
||||
assert!(
|
||||
target_served_by_coordinate,
|
||||
"disrespector relay must ignore vanish: announcement {} should still be \
|
||||
served for an author+kind+identifier query",
|
||||
announcement.id
|
||||
);
|
||||
assert!(
|
||||
later_issue_result.is_ok(),
|
||||
"disrespector relay must not lay down a vanish tombstone; later write was {:?}",
|
||||
later_issue_result
|
||||
);
|
||||
assert!(
|
||||
later_issue_served,
|
||||
"later event {} must be served because disrespector mode ignored vanish",
|
||||
later_issue_id
|
||||
);
|
||||
}
|
||||
|
||||
/// Fetch the NIP-11 relay information document via HTTP and return the list of
|
||||
/// advertised `supported_nips`.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user