bug: silent rejection of certain replaceable events
Summary: Sometimes replacables are silently rejected, if an event of the same author and kind exists which a d tag which is prefixed by the d tag of the event being submitted.
to reproduce:
- stand up a relay:
db := badger.BadgerBackend{Path: *relay_data_path}
db.Init()
relay.StoreEvent = append(relay.StoreEvent, db.SaveEvent)
relay.QueryEvents = append(relay.QueryEvents, db.QueryEvents)
relay.CountEvents = append(relay.CountEvents, db.CountEvents)
relay.DeleteEvent = append(relay.DeleteEvent, db.DeleteEvent)
relay.ReplaceEvent = append(relay.ReplaceEvent, db.ReplaceEvent)
http.ListenAndServe(":3334", relay)
- publish a replaceable event 'a-b' with a
dtag of<alphanumeric-string-1><non-alphanumeric-seperator><alphanumeric-string-2>. - then publish a replaceable event 'a' with a
dtag of<alphanumeric-string-1>. both events are accepted without adverse notices. - request events and see whether both are returned.
- delete the relay data and retry. ~1 in every 4 times event 'a' will not be returned.
- once you have found a troublesome event - keep a note of it.
- delete the relay data again and try, this time submitting the trouble event. It will consistantly be silently rejected if submited after ther 'a-b' event but otherwise accepted.
If event 'a' is published before 'a-b' it is always successful.
If event a-b is of a different replaceable kind it is succesful.
if both events are kind 1's it successful.
Recreating the event (so it has a different timestamp and id) and resubmitting it will often work.
Here are the nak commands and outputs:
nak event -k 30618 -t d=a-b ws://localhost:3334 && nak event -k 30618 -t d=a ws://localhost:3334 && nak req -k 30618 -t d=a ws://localhost:3334
connecting to ws://localhost:3334... ok.
{"kind":30618,"id":"75797277c5a00c80c764ad70d1173d243c06d7b0c73f8f212b40e5061f431fe3","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1749114315,"tags":[["d","a-b"]],"content":"","sig":"1e7c15b0e282ce356a11a63824a0df5886e9f5d76ccd06326da4f6ee5b4c1bb8cba25ec9adfa8d17f41ea7efb9795af5732eef61c3e23ce238e6fbead09eecd1"}
publishing to ws://localhost:3334... success.
connecting to ws://localhost:3334... ok.
{"kind":30618,"id":"c58030ed126a4a641ad25b5044153ba877f8c674389c005613c68bb0093c7374","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1749114315,"tags":[["d","a"]],"content":"","sig":"cd75d0819405d7a471fd9ba464cd701d4df1937cf356ad3b42e00e4cbd7f4597fab9552c885db21f0b28bdaa04d2ad49a919abaa2ccac73f7b3416df35fa501d"}
publishing to ws://localhost:3334... success.
connecting to ws://localhost:3334... ok.
[go-nostr][info] 2025/06/05 10:05:15 {ws://localhost:3334} filter does not match: [{"kinds":[30618],"#d":["a"]}] ~ {"kind":30618,"id":"75797277c5a00c80c764ad70d1173d243c06d7b0c73f8f212b40e5061f431fe3","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1749114315,"tags":[["d","a-b"]],"content":"","sig":"1e7c15b0e282ce356a11a63824a0df5886e9f5d76ccd06326da4f6ee5b4c1bb8cba25ec9adfa8d17f41ea7efb9795af5732eef61c3e23ce238e6fbead09eecd1"}
Now you have found a troublesome event which you can use for consistant results, even if you clear the relay data:
nak event -k 30618 -t d=a-b ws://localhost:3334 && echo '{"kind":30618,"id":"c58030ed126a4a641ad25b5044153ba877f8c674389c005613c68bb0093c7374","pubkey":"79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","created_at":1749114315,"tags":[["d","a"]],"content":"","sig":"cd75d0819405d7a471fd9ba464cd701d4df1937cf356ad3b42e00e4cbd7f4597fab9552c885db21f0b28bdaa04d2ad49a919abaa2ccac73f7b3416df35fa501d"}' | nak event ws://localhost:3334 && nak req -k 30618 -t d=a ws://localhost:3334
The issue also happens, but much less frequently, with an alphanumeric seperator eg abc:
nak event -k 30618 -t d=abc ws://localhost:3334 && nak event -k 30618 -t d=a ws://localhost:3334 && nak req -k 30618 -t d=a ws://localhost:3334
I couldn't replicate it when there was no seperator (ab).
I have no idea of how to reproduce this. What you describe doesn't happen at all.
What actually happens is that the second event always replaces the first, every single time, and even when there is no separator or anything like that, because the database querying logic is broken as it only does a prefix matching, so that's an definitely an issue that I should be ashamed of, but it doesn't seem to be the issue you're reporting at all.