Replying to Avatar dpc

I was thinking about nostr, a bit from a similiar perspective, especially that a lot of things are very much like in https://github.com/crev-dev/cargo-crev (exchanging documents signed by self-generated identities). The purpose was different, but most things are analogous.

Agreed on everything, but with a note that ease of building client is a huge benefit, especially for a protocol that lives or dies based on network effect. The idea would probably not catch on if building things would require too much work. If it is to be more complex, it needs to come with good off-the-shelf libraries to use.

End user software delivery is the biggest constrain on boostraping. Being able to handle everything from a web-client (primarily) is a must have. And it must work well.

The transport layer is a secondary thing. Self-signed document can be delivered in various ways - through web sockets, raw tcp, bittorrent, with e2e encryption or without it. In carg-crev github repositories are used free and public transport. Relays could support combination of all and it can be iterated on. So I would leave websocket with TLS as is to start with.

Using faster and more compact encoding and crypto, detaching the signature (witness) would be the biggest wins, and can't be easily iterated on after the fact, so getting it right is important. Good engineering suggest using some "one byte-prefix for version", to allow ecosystem rotate to something else in the future.

Identities/crypto should be modular (just add a "type" prefix). Clients that don't support certain ID type, can just ignore the message. That gives an ability to rotate to something else in the future, without changing too much elsewhere. I'm not a fan of GPG/SSH (even though I use them all the time, every day). Being able to support it for clients that need it for something - great. Forcing on everyone - meh. Something that is fast and easy to support would be a preferable default.

Also, IMO, nostr needs to come with a portable, reference WoT handling library. Coming up with a well working WoT is quite complex. Different clients could come up with their own approach, but having something off the shelf that clients can use to get a reasonable and consistent WoT behavior would be a big plus.

In cargo-crev there's a `crev-wot` https://github.com/crev-dev/cargo-crev/tree/master/crev-wot that implements a basic Wot based on "trust levels", "distance from root" with support for bans and overrides, but I always wanted to (and never had time) to implement "maximum flow" algorithm to deal with sybil attacks and bot farms.

BTW. The websocket thing is something I wonder about often. In a use-case with reasonably frequent updates, is it better to have clients hold an active but mostly idle tcp connection (like websocket), or make them do polling, or some long polling?

A proper async IO runtime can probably handle tons of connections at once anyway. 10k, 100k, maybe 1M.

Also with a gossip-like note fetching, it should be feasible to have lots moderately sized relays, without a loss to usability, so maybe worrying too much about scaling vertically a single relay is unnecessary.

Otherwise some client&application level load balancing might fix the problem. Eg when connecting to a relay it answers with a list of keyspace "shards" (possibly overlapping for redundancy), and then connects/queries to the actually node that holds the data. That would allow reasonably simple and flexible scaling of the relays without complex server side load balancing.

Reply to this note

Please Login to reply.

Discussion

Just one note: none of the async runtimes can handle 100k due to POSIX limit on connection number which is 16 bit (number of ports per the underlying physical network card).

Async is a myth. It is nothing more than the threads, with semi-automatic allocation of procedures (“tasks”) over threads. And threads are limited and heavy - just a dozens per async runtime.

The problem is that I see an attack vector on nostr relays with which I can lay down the most of the network. And that means something is wrong in the core protocol design. That “something” is the same thing as in “javascript” - making threshold for devs low. “Low” means also low robustness against attacks.

Any public network exposed infrastructure can be DoSed given enough resources. Bigger and more scalable infra can just sustain higher load, making a successful attack harder / more costly. That's why even medium-size commercial businesses hide behind something like Cloudflare.

So the way I think about it - the more efficient the underlying protocol, the more robust it is in face of a heavy load (legitimate or malicious), but ultimately if you're running a relay on puny VPS, it will fail relatively easily. The goal is to squeeze as much as possible from what's available.

Low barrier to entry doesn't not have to mean low robustness. Often does, but ideally something robust could be easy to build on.

I find the websockets make development more difficult. I send an event and then have to listen for a matching OK event? With a http request I send and get a response.

That isn't to say one couldn't make a relay with a HTTP api, however. At least primal.net dev is trying.

I am working on a protocol which will combine both RPC and PubSub model (in mutexed way). It will work either as a binary TCP protocol - or can be bridged via combination of HTTP and WebSocket connection.