nips
nips copied to clipboard
Make kind 7 act as parameterized repleaceable event
Considering NIP-25 is marked as a draft, thought of a way of fixing some problems with the reactions while not breaking current clients. Although the possible values of the d tag may look unusual, it is just specific to kind 7.
This should make it possible to:
- react to all kinds of events (but ephemeral) or to a pubkey (profile)
- react once to save relay disk space
- allow edits to content
- re-use relays existing parameterized repleaceable event handling logic to do edits
- request just the reactions to an event (using
{ "kinds": [7], "#d": ["note id"] }filter), instead of including all thread reactions
I think it would be better to also suggest to include just 2 tags, the d tag (required) and only one p so that the owner of the reacted to post/profile can be notified, instead of everybody in the thread, while also saving space. But i didn't add it to not make current clients mad.
Smart. Starts to get a bit heavy though if every reaction needs d, p, e tags, with probably one repetition (since the value of the d will probably match the value of one of the e, p). What do you think about this?
Also the reaction needs to include all the p, e, a tags from the event being reacted to? Seems a bit overkill, but I guess you agree with me on this point but don't want to make current clients mad.
Smart. Starts to get a bit heavy though if every reaction needs
d,p,etags, with probably one repetition (since the value of thedwill probably match the value of one of thee,p). What do you think about this?Also the reaction needs to include all the
p,e,atags from the event being reacted to? Seems a bit overkill, but I guess you agree with me on this point but don't want to make current clients mad.
@barkyq I've pushed changes in this direction. I do think adding all those p, e, a tags are a waste of disk space (bigger event size) and also of bandwidth because one asks for direct reactions but receives "all" (the relay most likely will limit it anyway) thread reactions. It is also strange to put many p tags which would mess with notifications (why would someone want to be notified of a reaction to the reply to a reply to a reply to his post? =o)
:+1: Nice that it blocks users from reacting multiple times on the same pubkey without requiring new relay logic. Also consistent with #236
I think I would want to keep the e tag for reactions to replaceable events, or at least some reference to the id of the event originally reacted to. Without such a reference, the event may be replaced in a way that changes the context and meaning of the reaction, without any indication that the reaction was to an earlier event.
@shafemtol it totally makes sense. However, if the created_at of the reaction is older than the created_at of the current version of a replaceable event, it is enough to know you liked a regular note before it changed into a pr0n ad. Per NIP-16 an event can only be replaced if it has newer timestamp. Is it enough or would you still require the original event id for your use case?
I thought of the created_at timestamps, but in my mind relying on those would not be enough. The changed note could have a timestamp one second later than the original note and thus most likely have an earlier timestamp than any reactions.
yes in order for the timestamp thing to work, relays need to not allow posting of events with old created_at
yes in order for the timestamp thing to work, relays need to not allow posting of events with old
created_at
That would just not be viable. That would mean that if you went out of sync with one of your relays for too long and then came back, some of your events on that relay would remain permanently unavailable or stale. At least until NIP-03 is widely deployed and actively used, relays have to take old timestamps at face value.
The changed note could have a timestamp one second later than the original note
There is NIP-22 (Event created_at Limits) that could prevent it. But as it is optional, you are right, or else we would need to add it as a dependency to this NIP, which doesn't seem right. Also, the extra e tag allows a client to just fetch reactions to the current version of the replaceable event if it wished to hide stale reactions, instead of filtering client side. This would encourage just typo edits near the publish time instead of full edits.
Isn't this a relay policy choice?
Isn't this a relay policy choice?
Yes NIP-22 range is custom relay config indeed. One more reason to need the event id of the replaceable event.
@fiatjaf do you think I should add something like "Because the previous version of this NIP relied on e tag instead of d tag, for a transition period the reaction event MAY include an e tag with the reacted to event id even if such event isn't replaceable."?
Is there anything else I can do to help this land?
Yes. Change the NIP to say that relays must deduplicate reactions to the same event. Do not change anything else in the event format. Instead relays can be smart enough to do
if event.kind == 7:
if current = get(kind = 7, #e = event.tags.e):
replace(current, event)
else:
add(event)
@fiatjaf What about this? It is very similar to contact lists that can leverage relays replaceable events logic by just doing:
function isReplaceableEvent (event) {
return event.kind === eventKinds.CONTACT_LIST ||
(event.kind >= 10000 && event.kind < 20000)
}
Relays would need to just update the isParameterizedReplaceableEvent function to also check for event.kind === eventKinds.REACTION. So no special logic just for a kind as in your example.
Relays that have implemented parameterized replaceable events will automatically treat today's reaction as having d = '' as per NIP-33 specs. The relays which haven't implemented it will work just like today, storing duplicates. Clients rely on external relays, so relays are kings. In the end of the day, relays dictate nostr protocol, not the clients. Even Damus would have to change eventually.
I just don't see why add this extra d tag when we already have the e tag that can be used for replacement. And then require all clients to change when it's much easier for relays to change their behavior. Relays should probably do this for other kinds too.
I just don't see why add this extra d tag when we already have the e tag that can be used for replacement
The previous version was a Frankestein because I tried to keep old text intact by not removing this: Including the e tags enables clients to pull all the reactions associated with individual posts or all the posts in a thread. Very unlikely to need all reactions to all posts in a thread. It would be massive amount of data. Please see updated version.
At first, there wasn't an official way to categorize an event as replaceable. Replaceable Events came as NIP-16 and Parameterized Replaceable Events followed at NIP-33.
"Set Metadata", ~"Channel Metadata"~ and "Contact List" are in essence Replaceable Events, but as they were created before NIP-16, they just aren't in NIP-16 kind range.
But the logic to update them is the same as any replaceable event: find by kind and pubkey > check if new created_at is greater > replace it
My point is that reactions are in essence a parameterized replaceable events, though it is missing the d tag, cause it was created before NIP-33 even existed.
With the d tag we can do: find by kind, pubkey and d tag > check if new created_at is greater > replace it.
Just like future event kinds that wish to be replaceable shouldn't expect special logic from relays. Just use the right kind range and, if needed, the d tag.
My only problem with all your suggestions is that even though they are good you completely disregard the problematic effects to breaking things. Open https://nostr.net/ and see how many implementations of relays and clients exist today. It is really not worth making breaking changes to spec when all these codebases exist and are doing things in one way. It will just create massive confusion.
I did pondered over the breaking change aspect. In this specific case of reactions, that aren't main functionality kind of events, on a NIP marked as draft, by applying changes that wouldn't break feed nor thread loading and would eventually be noticed by client authors when they see unexpected reaction counts, I thought it was a good idea. Yet I get you and others don't think the same way. Thanks for replying.
Sorry, I feel bad rejecting all your suggestions given that you really seem to care.
We are early on in the protocol and if reactions need fixing, we should fix them now.
Event deletion is a mess in a decentralized protocol and the only way of removing reactions right now. The deletion event has to be kept around in case the deleted event is still around, too ...
With a parametrized replaceable event, changing a reaction would work and we could even define that reaction "" is the implicit deletion.
As clients would have to be aware of this new way of doing reactions, I'm against touching kind-7 behaviour. We have nip33 for a reason and relays that implemented it would not need further changes to support these reactions on kind-30007 for example.
e- and p-tags would not be needed as clients requesting reactions to profiles/events would ask for respective d-tags. We might add an "e" or "p" somewhere though so that clients could find e/p if the reaction is all they know. Following Alice I might only find she liked something and want to know what it was. Maybe tag ["d",$eventId,"e"].
First clients to implement kind-30007 could author both kinds of reactions and de-dupe reactions accordingly and we retire kind-7 once the new way catches on.
I think this ship has sailed, adding a MUST here is a little too strong for an event type of which we have millions. I think @fiatjaf is right that this is a relay policy issue, and should probably be added to NIP 07 as an additional requirement for relays. Closing for that reason and for inactivity.