seraphis-migration / wallet3

Info and discussions about a hypothetical full 'wallet2' rewrite from scratch
MIT License
14 stars 0 forks source link

Concurrent network requests #58

Open j-berman opened 1 year ago

j-berman commented 1 year ago

Context

If the wallet was able to make concurrent network requests to a daemon, then it could make requests for chunks of blocks in parallel and immediately start scanning whichever chunks get to the client first. This is how @UkoeHB's async scanner was designed. When implemented, I observed a download speed-up of ~40% on my machine pointing to a remote daemon, which translated to a ~40% speed-up in scanning compared to wallet2, since download speed is my bottleneck (source).

The epee http client wallet2 uses does not support concurrent network requests over a single connection. In order for a client to make concurrent network requests to a daemon with epee's http client, it must initiate multiple connections to the daemon, which has perf overhead. This is how I implemented the mock async scanner mentioned above (source).

libcurl's http client offers the ability to make concurrent network requests over a single connection, however, this is only supported when the server supports http/2 multiplexing or http/3. Both of which seem to require significant changes to the Monero server connection code to support.

Immediate path forward

I think the optimal immediate path forward is to move forward with a hardened client-side connection pool that wraps N http connections to a daemon and is particularly useful for scanning. I already implemented a mock connection pool in my scanner impl linked above, and I think that can easily be improved and hardened.

This shouldn't require any changes to the daemon and should be easily doable in days since it's pretty much already implemented.

Future considerations

Both of these would be nice to have but I think networking dev resources are probably better allocated elsewhere at the moment (e.g. p2p encryption), since we can realize a major scanning speed-up without major server-side code that would require a fair amount of dev effort and review.

rbrunner7 commented 1 year ago

Agree.

client-side connection pool that wraps N http connections to a daemon

About how many connections do we speak here? I wonder whether we run a danger that public nodes will get pushed to their performance limits much faster if future wallets overwhelm them with connections.

j-berman commented 1 year ago

I'll check resource impact with connections soon. I planned to cap the connection pool at 20. It can also easily be implemented to only open >1 connections if the client has many blocks to scan and disconnect any lingering connections when scanning is done.

j-berman commented 1 year ago

One clarifying note: when using libcurl's multi interface, if the server does not support multiplexing and the client tries to make concurrent requests, then libcurl initiates new connections to the server and handles requests concurrently under the hood. Thus, switching to libcurl today and using the multi interface for concurrent requests would in fact negate the usefulness of a new client-side connection pool since it abstracts the "pooling" away. However, the client-side connection pool is simple enough code that I'm still of the view it makes sense to move forward with it.