Oddbean new post about | logout
 The relays in the 'p' tags are hints.  I'm not sure they are useful in kind-3 events as we use NIP-65 now to specify what relays the people you follow use.  Gossip may or may not write them (I can't remember).

The contents however are YOUR relays, if you choose to store them there, as some clients have done in the past.  This is very old stuff, Damus and Astral stored them in there to auto-configure when you went to a different client.  Gossip reads and uses them if it can't find a NIP-65 event. 
 Thanks for the response man. I was trying to figure that out and I don't know the NIPs like the back of my hand quite yet. I've been following Nostr and dabbling with it since there were like 17 NIPs and the protocol was much simpler and keeping up with this stuff can be hard as it's happening fast, I need an RSS feed (or a Nostr bot?) to help me keep track of all the changes.

So there are 3 ways you can get relays to fetch from, the NIP-02 way, the way I'm talking about where they're in the content (and they're the recipient's relays, not a dump of all follows relays if I understand that correctly?) and the NIP-65 way? I ask because I'm working on something and I want to make sure to cover all my bases and implement everything I need to implement to satisfy users.

An aside, I quite like the NIP-02 way of storing them with one caveat: I think the field for a relay in the p tag should be a list of relays as this would help with censorship resistance. I really like a simpler protocol, and I like the idea of client side storage of feeds, I've actually got a client I'm in the very beginning stages of building that is focused largely on user definable client side feeds, but it is on the backburner in favor of a CLI utility that uses bittorrent and nostr to enable media sharing. 
 I argued for multiple relay hints a long long time ago but it didn't get any traction, got pushback on being too much overhead instead, and pushback on the fact that these things rot over time.

The NIP-02 relay hints are 3rd party.  Somebody's follow list claims somebody else uses that relay, but do they really?  That is why I don't use them for authorative data.

The authorative data is NIP-65 kind 10002 (and new 10050 for DMs).  That is meant to be the real deal.

But in case somebody didn't publish what relays they use, there are fallbacks:
1) The contents of kind-3 (although not documented in NIP-02), since some clients put them in there for self-configuration
2) relay hints in other people's kind-3 (NIP-02), but these are 3rd party
3) NIP-05 nostr.json may have relays, but nostr.json is unsigned!
4) Maybe you saw their events on a relay before, so you might remember that as a possibility
5) Any 'p' tag can have a relay hint (again 3rd party, plus they rot, but if you have nothing else....)

Gossip keeps all these relationships and scores them, and it has been a long road of tweaks to that system to get where it is today.  If all the other clients did the outbox model, I could throw all that stuff away and just use NIP-65 and be done. 
 So if I'm following, I should prioritize kind 10002 events, then content of kind 3, then p tags in kind 3. I won't be doing any complex scoring I don't think.

So on the hypothetical side of this, I think, if the relays in p tags were lists, and they were only used to fetch a user's kind 0 event and it contained a list of relays that were updated every time a client added or removed a relay, that should prevent rot while keeping all the extra complexity out of this, no? 
 I'm not sure I follow 
 So, suppose the p tags on *my* kind 3 could each have multiple relays like you said you tried for that I quite like. And suppose your kind 0 event had a list of relays that was updated by your client every time you added or removed a relay, just like if you changed your avatar or something. Could be kind 10002 as well, but I'm trying to simplify the protocol in my mind, rolling the contents of kind 10002 onto kind 0. If the relays in your p tag in my kind 3 were updated by my client when they don't match your kind 0 (or 10002), then we don't really have a rot problem or a bootstrapping problem, right? The likelihood that your followers' p tag for you in their kind 3 are out of date is very low, the likelihood that nobody can find your list of relays from just a couple of your followers' kind 3 events is extremely low, and if clients MUST update their kind 3 p tags from your 10002 or 0 in my hypothetical idea, then it looks like those two problems are practically solved, though I know not perfectly solved since there is a small chance that none of your followers have a single relay for you that you still broadcast to and therefore that will have an up to date kind 0 or 10002 event for you. To me this seems much more robust and less dirty than the brute force hack you just told me about. 
 Well you are just copying from my kind 0 when my kind 0 updates. And that is a lot of copying and republishing overhead. And yet you still have to find my kind 0 to do that, which was the original problem.  So I don't think you've solved anything.  Unless you are saying that you would look into a bunch of other people's kind 3 lists to see if any of them know where I have moved to.  So what you are doing is creating a bunch of redundancy of my kind 0 information distributed all around the place.  We could achieve the same thing more simply by just having relays copy/push people's kind 0 (or 10002) information to all the other relays they know about once they first discover a new version... a kind of relay-to-relay propagation... or even have clients blastr the thing in the same way. 
 >Well you are just copying from my kind 0 when my kind 0 updates. And that is a lot of copying and republishing overhead.

Yes, but its not really more overhead than the original NIP-02 spec had (besides p tag relays being more than one), if you don't want the relays in kind 3 p tags to rot you have to update them frequently, it solves the bootstrapping as well.

> And yet you still have to find my kind 0 to do that, which was the original problem.

Yes, but it's much less likely I will fail to be able to now that I know that your p tag in my kind 3 will very likely have at least one valid relay.

> Unless you are saying that you would look into a bunch of other people's kind 3 lists to see if any of them know where I have moved to.  

Yes, if you can't find a valid relay that has my kind 0 or 10002 from my p tag in your kind 3, then try from one of my followers' kind 3, move on to the next one and check relays you didn't see before and so on, that is of course in the event that your list of my relays has rotted into oblivion, it's a last resort. If you *never* find a valid relay that has my kind 0 or 10002 then the network is almost certainly completely split somehow.

> So what you are doing is creating a bunch of redundancy of my kind 0 information distributed all around the place.  We could achieve the same thing more simply by just having relays copy/push people's kind 0 (or 10002) information to all the other relays they know about once they first discover a new version... a kind of relay-to-relay propagation... or even have clients blastr the thing in the same way.

But there's no method to that, you just hope the network is not fragmented, that approach is less robust, and youre burdening relays that have nothing to do with the people involved, hoping they won't just drop these events. It seems to me that this is way more duplication overhead because even relays that don't care otherwise still have to be trusted to participate in storing and relaying kind 10002 events for (I don't know how much) less robustness. This way, you only publish your kind 0 or 10002 to your relays, no blastring required. Just changing the kind 3 p tags to have multiple relays would make this work, everything else is just client behavior, if you use kind 10002 instead of changing kind 0 to have that information inside, although that seems maybe like a slightly better idea.

Anyway I just like chewing on ideas, it seems like a good idea to me and seems more robust and "correct". I don't expect it to be implemented and I'm not picking fights in the nostr world shouting about how everything should be done my way, but it's fun to think about different ways to solve different problems and ponder on how a protocol could work differently and how those differences might make things better and/or worse on different ways. Maybe you're right, maybe blasting your 10002 is practically always sufficient, isn't that much of a bother to relays who already are tasked with relaying messages from every direction, maybe it's highly improbable that the network will fragment enough to make it a concern that needs to be addressed more elegantly, maybe the bootstrapping issue isn't really much of a centralizing force at all. 
 Also, where do you bootstrap fetching relays from? So you've got to ask some relays for kind 10002 notes, is it standard to ask your relays from content of kind 3 for them for your follows? What happens if you find none, doesn't that fracture the network? 
 The bootstrapping issue was kinda solved with a brute force hack.  Broastcast your 10002 event everywhere.  You won't actually get it everywhere, but you will get it to enough places that maybe it can be found.

I don't know how to solve the bootstrap problem truly.  This hack seems good enough.  As long as there are a group of very popular relays, if you use all of those and look things up on all of those, people will find each other.

People have suggested a DHT in the past, but I think this also has the bootstrapping issue, which doesn't really seem solvable to me, at least not perfectly.  You can always have a set of relays distinct from all the others which can never find your event.  Say there were 10 relays on mars.  How can they get your event from Earth if Mars and Earth aren't connected?  Not possible.  So without centralization, it is strictly provably impossible to do it perfectly. 
 nip66 draft 
 broadcast*

there i fixed it