nips
nips copied to clipboard
Better deletions / Tombstones
There are a few problems with deletions on Nostr. I think it will be a serious problem for adoption if not fixed.
Other decentralized protocols have similar problems, but they make a better attempt to solve them. It will never be perfect, but it can "just work" most of the time on most apps. In my experience, that matters a lot to users. Furthermore, I believe Nostr is actually better equipped to deal with these problems.
First problem, deleted events may be found on other relays:
- I submit an event to Relay A.
- Someone reposts my event to Relay B, causing the event to be copied to Relay B, which I don't know about.
- I delete my event (kind 5) on Relay A. I don't know about Relay B, so I don't send my deletion there.
- Someone else's client queries for my event using a relay pool library, connected to Relay A and Relay B. The event is found on Relay B, while Relay A gives an EOSE. So the event is shown.
How could we solve this? Make Relay A return the deletion event (kind 5) for the query. Now the client can know that the event was deleted.
Another thing to consider is what happens when my deletion actually does work? Consider this case:
- I submit a post on Relay A, and then someone replies to it.
- I delete my post.
- The reply to my post still exists. Someone clicks it, and the client attempts to load my post.
- My post is not found because I deleted it.
- The client connects to additional relays trying very hard to find my post. It might eventually be found (bad) or the client might just waste its time trying (also bad).
Solution: return the deletion event (kind 5) from Relay A in the query for the deleted object.
I am thinking that maybe as a general rule, relays could return deletion events in place of a deleted event that would otherwise match the filter. This is called a Tombstone.
It violates a principle of filters, which is that events returned by relays should match the filter. But I don't think it would break clients, which should already be validating the results from filters.
So, is it worth it? Honestly, I believe yes. Unless there's evidence this would break a lot of clients. The problem is important, and it's not uncommon for deletions to need special handling. Thoughts?
Oof: https://pkteerium.xyz/notice/AY3iwdeNYxPGFIYQzY
I do agree it will need to be addressed. Until it is available, some people will just not understand or want to use Nostr. Perhaps that is ok but I do believe that Nostr will be better with a more diverse user base and supporting deletions or edits isn't sinking to the lowest common denominator. I believe it would be valualeble for everyone.
I agree with your thoughts, and think they are better than these other ideas I present as well but I did want to share some more options.
Expiration Option on Notes It could perhaps be possible to have an option of notes having an expiration time. This wouldn’t necessarily allow for deletion but if someone is generally more interested in removing their discourse history than preserving it they could choose to post a note for only 1 Month etc. All relays would know upfront of when it will be deleted or it just wouldn’t have it.
In the future, it could be implemented that you could remove the expiration of a note if you found it was important to keep up. The downside is perhaps a relay wouldn’t get the memo to not delete but at least most relays would.
In this scenario, there is nothing stopping someone from setting up a bot to scrape and save all notes with an expiration time so they can effectively nullify the expiration in the public’s view but this issue is also possible on any other social media platform with public profiles.
Un-Post a Note The issue I see with this is it is ultimately up to the relay and/or operator to respect the request to delete or tombstone. An operator could always modify the relay to not follow protocol. I have this other idea, which may be flawed but perhaps viable. What if nostr didn't actually purge the data and instead returned the event along with the additional tombstone classification? A user could “un-post” a note (not delete). This would then be interpreted by clients and presented to the user as something like “Un-posted note is struck from record at request of poster. For posterity, click to reveal original note.”
Maybe instead of sending
["REQ","_",{"ids":["a9b46e23598efdceca2046eee94ceba4f0ccde28af6f05a2b8b550abd48f3e71"]}]
clients could send
["REQ","_",{"ids":["a9b46e23598efdceca2046eee94ceba4f0ccde28af6f05a2b8b550abd48f3e71"]},{"kinds":[5],"e":["a9b46e23598efdceca2046eee94ceba4f0ccde28af6f05a2b8b550abd48f3e71"]}]
whenever they are querying for an event.
It's cumbersome, but at least it's opt-in and doesn't require changes to relays. Clients would have to have extra logic for handling deletion events returned automatically from relays anyway.
@fiatjaf That is actually a great point. That would solve both problems in some cases, and clients should absolutely do this. You can just add 5
to your existing filters.
Eg when getting a profile feed, add kind 5 to your query, and then process it in the background:
["REQ", "_", {"kinds": [1,6,5], "authors": ["000..."]}]
The home feed query is similar:
["REQ", "_", {"kinds": [1,6,5], "authors": ["000...", "1111....", "2222...."]}]
But, are there other queries where you can't do that so easily? I can't remember what I was thinking before.
This is a great start.
I think this wouldn't be very helpful in an author or homefeed query, only when fetching a specific note by id.
I'm glad someone mentioned this, I also had the unfortunate incident, or rather attack, today regarding the "Event Deletion". Nostr's client has a lot of Permission when it has a private key, and it's only through the client that users can interact with relay, including the deletion event (NIP-09), where the client's prompts are the only way for users to determine the desired outcome.
Today I was trying out a new Nostr client and was misled by the "Delete Account Data" in the software settings, at first I thought it was just deleting the account from the software (similar to logging out), but in fact it sends a deletion event to all configured relays! And there's no secondary confirmation. All account notes are instantly flagged by the delete event, and cannot be revoked (NIP-09 makes this clear). I quickly realized the problem and force-stopped the software to avoid further damage, but the problem had already occurred: some deletions had been delivered to the relay, but some had not. If there is a data inconsistency, how do users ensure that their data remains intact after a deletion event? Even if the incident I experienced today was an accident, it was not an intentional act by the client developer. Obviously, NIP-09 not only exacerbates the data incompleteness, but also gives rise to more serious phishing and malicious attacks, any client can get the private key and then empty your data, this may be due to a misunderstanding, or phishing attacks.
What client did that?
What client did that?
Nostrmo v1.8.0: https://github.com/haorendashu/nostrmo
which should already be validating the results from filters.
It would break things if they're validating that the objects they get back match the filters they specified.
I like the suggestions above -- clients can already fetch deletion events if they want.
To increase the likelihood that a deletion will be fetched with an event that it deletes, when creating a deletion event, clients could prefer using a created_at that matches (or maybe is 1 second after?) the created_at of the event that it deletes.
There is no way to query for "all kind 1's of author P, plus any deletion events of kind 1's by author P". Unless deletion events always had a 'k' tag in which case you could (but they don't).
But you could query for a broader range of deletion events, and that's not too bad:
["kinds": [1], "authors": "<P>", "since": yesterday],
["kinds": [5], "authors": "<P>", "since": yesterday]
So things are OK now, but I'd be in favor of adding a 'k' tag to deletion events.
I'd be in favor of adding a 'k' tag to deletion events.
I just added the k
to Amethyst's deletions.
Just added k tags to deletions from coracle
Added k
tags to deletions from NDK