nips icon indicating copy to clipboard operation
nips copied to clipboard

NIP-11 without WebSocket isn't stupid simple enough

Open alopatindev opened this issue 1 year ago • 6 comments

Before publishing some events from browser client I'd like to check whether certain features are available on the relays (to save some bandwidth by not spamming servers with useless requests).

When NIP-11 isn't implemented I want to assume that all capabilities are available for such relays.

Ideally I'd like to fetch relays capabilities on relays pool initialization step, without creating extra connections. Can any browser client library do that right now?

Properly doing the https GET to fetch the JSON and then upgrading to WebSocket doesn't look simple to me.

Also it requires correct server CORS configuration (currently it's not always the case).

Could we have (instead or additionally) a WebSocket request for the same JSON document?

alopatindev avatar Jun 19 '24 21:06 alopatindev

I'm used to people coming here asking us to replace the WebSocket for a bunch of HTTP APIs. This is the first time I've seen someone asking for the opposite.

I sympathize with you, you're probably right that using a WebSocket would have been better, but I think the hurdle and the damage that would be caused by trying to push this change would be much bigger than the benefits we would gain from it.

fiatjaf avatar Jun 19 '24 23:06 fiatjaf

Why is that? This seems like a nice idea to me, if nothing came back you could fall back to http or go without.

staab avatar Jun 20 '24 03:06 staab

I forgot to mention another scenario: I'd like to ignore some relays for reading before I subscribed to messages from them (because language_tags turned out to be irrelevant on this part of multilingual website).

For now due to some CORS issue client is damned to violate rules of some relays: client will still connect to such relay without knowing it doesn't support this language. Client might receive, react to or even publish their own messages in irrelevant language on this relay.

And at the same time the same misconfigured relay might be useful to this client, on a different page of the same (multilingual) website even. Until user will ironically receive ban for violating the rules.

If it's not CORS issue than it's (inevitable? or just hard to solve properly?) performance drop for this client:

  • either due to waiting for JSON and only then reopening a connection for new messages
  • or because of connecting to too many irrelevant relays first, receiving messages from them and possibly receiving JSON concurrently using other connections
    • this is even worse, because now we'll either
      • need to wait until JSON is (not) received and only then we can show messages
      • or we'd need to show messages and then suddenly hide/remove some of the messages (this will appear buggy to user and complicate client logic).

If adding a new (additional) WebSocket request makes protocol too complicated and removing HTTPS version will cause too much damage, another approach would be just make a new NIP that provides the WebSocket interface for NIP-11's JSON.

This will make it possible to leave both implementations or choose which one one wants to implement or maybe potentially deprecate entire NIP-11 later if it will receive too little interest in proper implementation (and server configuration).

alopatindev avatar Jun 20 '24 17:06 alopatindev

@alopatindev Many NIP-11 details are included in NIP-66 events for discovery and meta events, as well as sometimes the entire NIP-11 as stringified JSON in the event content

Sidenote: One hurdle to transposing NIP-11 as-is to events tags, is that the JSON scheme for NIP-11 does not transpose well to tags due to it's depth and an array of objects for fees

dskvr avatar Jun 26 '24 21:06 dskvr

I'm used to people coming here asking us to replace the WebSocket for a bunch of HTTP APIs

@fiatjaf interesting, you mean a bunch of HTTP requests without bidirectional streaming at all?

I actually think that HTTP/2 in particular would be a better choice than WebSocket today for entire Nostr protocol, specifically because

  • it defines multiplexing
  • supports bidirectional streaming without all this upgrade-to-WebSocket-complications
  • perhaps flow control requirement is useful as well.

Maybe we should do the opposite? How about gradually migrating everything to specifically HTTP/2 (and then probably to HTTP/3 with a fallback to HTTP/2 for older clients) starting with

  • recommending NIP-11 (and whatever that mentions connection over HTTP to relays) to be implemented specifically with HTTP/2
  • and later adding HTTP/2-based bidirectional communication and deprecating < HTTP/2 + WebSocket?
    • I guess it's easier to migrate to something like this from WebSocket, rather than to a bunch of new HTTP requests.

Also, even though HTTP/3 is still unreleased and requires manual enabling in browser, it looks like it's already possible to use it.

HTTP/3 is based on UDP/QUIC which gives improved congestion control than in TCP (however requires doing things in user space rather than in kernel space like TCP used to, very different protocol).

Is that right that the lack of proper congestion control is the reason why we currently publish messages sequentially (even though I personally find it annoyingly slow) rather than concurrently?

alopatindev avatar Jul 07 '24 10:07 alopatindev

First off, if we are going to make a breaking change to nostr such as moving to HTTP/2, then we should make a bunch of other breaking changes at the same time in order to fix longstanding problems, such as binary events, subkey handling, etc. And we could incorporate NIP-11 data into the main protocol too (the point of this issue).

But I'm not at all convinced that HTTP/2 is a good idea even having read that entire linked stackoverflow discussion. That top answer is a weird and hacky way to use HTTP/2 which would probably encounter many implementation edge cases of breakage because HTTP/2 is still fundamentally a request-response model.

Also, multiplexing doesn't improve performance. The data is still serialized through packets. It just handles framing and reassembly to "organize" your data for you. It will still be just as "annoyingly slow" if it was changed.

Lastly, the performance gained by avoiding head-of-line-blocking is primarily a means of latency reduction, with no effect on bandwith. Latency issues aren't very signficant for nostr. They are for voice communication, for real-time gaming, for video streaming. But for nostr it's not really a big deal. Not motivating enough.

mikedilger avatar Jul 08 '24 21:07 mikedilger

FYI https://github.com/nostr-protocol/nips/pull/1434

bezysoftware avatar Aug 20 '24 07:08 bezysoftware