update readme after our refactor

This commit is contained in:
Bryan Stitt 2022-05-12 05:54:27 +00:00
parent 10cd52f19a
commit 53e7d99d47
2 changed files with 36 additions and 14 deletions

@ -1,34 +1,48 @@
# web3-proxy
quick and dirty proxy for ethereum rpcs (or similar)
Signed transactions are sent to the configured private RPC (eden, flashbots, etc.). All other requests are sent to an RPC server on the latest block (alchemy, moralis, rivet, your own node, or one of many other providers).
Web3-proxy is a fast caching and load balancing proxy for web3 (Ethereum or similar) JsonRPC servers.
Signed transactions (eth_sendRawTransaction) are sent in parallel to the configured private RPCs (eden, ethermine, flashbots, etc.).
All other requests are sent to an RPC server on the latest block (alchemy, moralis, rivet, your own node, or one of many other providers). If multiple servers are in sync, they are prioritized by `active_requests/soft_limit`. Note that this means that the fastest server is most likely to serve requests and slow servers are unlikely to ever get any requests.
Each servers has different limits to configure. The `soft_limit` is the number of parallel active requests where a server starts to slow down. The `hard_limit` is where a server starts giving rate limits or other errors.
```
cargo run --release -- --help
```
```
Finished release [optimized] target(s) in 0.13s
Compiling web3-proxy v0.1.0 (/home/bryan/src/web3-proxy/web3-proxy)
Finished release [optimized] target(s) in 9.45s
Running `target/release/web3-proxy --help`
Usage: web3-proxy [--listen-port <listen-port>] [--rpc-config-path <rpc-config-path>]
Reach new heights.
Web3-proxy is a fast caching and load balancing proxy for web3 (Ethereum or similar) JsonRPC servers.
Options:
--listen-port what port the proxy should listen on
--rpc-config-path what port the proxy should listen on
--rpc-config-path path to a toml of rpc servers
--help display usage information
```
Start the server with the defaults (listen on `http://localhost:8544` and use `./config/example.toml` which proxies to a local websocket on 8546 and ankr's public ETH node):
```
cargo run --release
```
Check that the proxy is working:
```
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":67}' 127.0.0.1:8544/eth
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"web3_clientVersion","id":1}' 127.0.0.1:8544/eth
```
You can copy `config/example.toml` to `config/production-$CHAINNAME.toml` and then run `docker-compose up --build -d` start a proxies for many chains.
## Flame Graphs
Flame graphs make finding slow code painless:
$ cat /proc/sys/kernel/kptr_restrict
1
$ echo 0 |sudo tee /proc/sys/kernel/kptr_restrict
@ -54,17 +68,24 @@ Test erigon:
wrk -s ./data/wrk/getLatestBlockByNumber.lua -t12 -c400 -d30s --latency http://127.0.0.1:8945
Note: Testing with `getLatestBlockByNumber.lua` is not great because the latest block changes and so one run is likely to be very different than another.
## Todo
- [ ] after connecting to a server, check that it gives the expected chainId
- [ ] if the fastest server has hit rate limits, we won't be able to serve any traffic until another server is synced.
- [ ] proper logging with useful instrumentation
- [ ] think more about how multiple rpc tiers should work
- [ ] if a request gets a socket timeout, try on another server
- maybe always try at least two servers in parallel? and then return the first? or only if the first one doesn't respond very quickly?
- [ ] incoming rate limiting (by ip or by api key or what?)
- [ ] measure latency to nodes?
- [ ] one proxy for mulitple chains?
- [x] simple proxy
- [x] better locking. when lots of requests come in, we seem to be in the way of block updates
- [ ] proper logging
- [x] load balance between multiple RPC servers
- [x] support more than just ETH
- [x] option to disable private rpc and send everything to primary
- [x] health check nodes by block height
- [ ] measure latency to nodes
- [x] Dockerfile
- [ ] testing getLatestBlockByNumber is not great because the latest block changes and so one run is likely to be different than another
- [ ] if a request gets a socket timeout, try on another server
- maybe always try at least two servers in parallel? and then return the first? or only if the first one doesn't respond very quickly?
- [x] docker-compose.yml

@ -8,14 +8,13 @@ use crate::connection::Web3Connection;
use crate::Web3ProxyApp;
#[derive(FromArgs)]
/// Reach new heights.
/// Web3-proxy is a fast caching and load balancing proxy for web3 (Ethereum or similar) JsonRPC servers.
pub struct CliConfig {
/// what port the proxy should listen on
#[argh(option, default = "8544")]
pub listen_port: u16,
/// what port the proxy should listen on
// TODO: use flags for the config path "./data/config/example.toml"
/// path to a toml of rpc servers
#[argh(option, default = "\"./config/example.toml\".to_string()")]
pub rpc_config_path: String,
}
@ -35,6 +34,7 @@ pub struct Web3ConnectionConfig {
}
impl RpcConfig {
/// Create a Web3ProxyApp from config
pub async fn try_build(self) -> anyhow::Result<Web3ProxyApp> {
let balanced_rpc_tiers = self
.balanced_rpc_tiers
@ -53,6 +53,7 @@ impl RpcConfig {
}
impl Web3ConnectionConfig {
/// Create a Web3Connection from config
pub async fn try_build(
self,
clock: &QuantaClock,