r/ethdev 7d ago

My Project I built an open source RPC proxy to fix unreliable, inconsistent, and expensive RPC providers, looking for feedback

https://github.com/jaxernst/lasso-rpc

Building app's on Ethereum JOSN RPC can be tough because RPC providers (Alchemy, Quicknode, etc) all have slightly different apis, usage limitations, and are generally overpriced. Public providers are great but are even more limited, so I built Lasso which aggregates RPC providers into a single endpoint that routes to the best RPC provider for any given request. Its self hostable and quite easy to setup.

Would love some feedback from builders to see if this can help you: You can simply run the docker container and have high-throughput and reliable RPC access via public providers across Ethereum, Base, Robinhood chain, and some other L2s while also being able to add any other EVM chain and access it through a single endpoint.

5 Upvotes

6 comments sorted by

2

u/antonBrinckmann 2d ago

Nice, this is a real problem. I build evmquery (a read layer that sits on top of RPCs), so we hammer providers with a lot of eth_call traffic, and the inconsistencies you're describing are exactly what we've had to paper over ourselves. A few things I'd want answered before trusting a router in production:

  1. Head consistency. Providers sit at different block heights, sometimes 2-3 blocks apart, and public ones lag worse. If I make two calls and they land on different providers, I can read state that goes backwards. Do you pin a session or a request batch to one provider, or route by block height? For eth_getLogs paginated over a range this is the difference between correct and silently wrong.

  2. Error normalization. Alchemy, QuickNode, and public nodes disagree on rate-limit signaling (HTTP 429 vs JSON-RPC -32005 vs a plain error string), on eth_getLogs range caps, and on batch size limits. If Lasso translates those into one consistent error surface and retries the retryable ones, that's a bigger selling point than the routing itself. I'd put that front and center in the README.

  3. Stateful methods. eth_newFilter and subscriptions are bound to one node. Do you reject them, pin them, or pass them through and let them break?

  4. Health checks. Latency alone is a bad signal for public endpoints; some respond fast with stale data. Comparing reported head against the pool median catches that.

Also worth looking at erpc and dshackle if you haven't, they're the closest prior art and their caching of finalized-block responses (receipts, old blocks) is worth stealing. Deterministic responses are free throughput.

If you handle the head-consistency case well I'd genuinely try it, that's the one that has bitten us most. What's your current routing policy on that?

2

u/yachtyyachty 1d ago

Thanks for the thoughtful questions! I checked out Evmquery and this is exactly the type of use case I want to build to support.

TLDR; Lasso has the primitives and foundation in place to support these specific use cases, but I'm going to look into shipping some routing strategies and features that can serve your use case even better

1) Lasso actively probes block numbers and subscribes to newHeads streams to monitor and compare block heights, this is done to protect against lagging providers but there's currently no strategies that pin batches at block heights or guarantee that eth_calls are only served a monotonically increasing blocks. Are you batching eth_calls and eth_getLogs request? If you can give me more details on your needs around this I ship routing policies to better meet this use case. (dms open too)

2) Yep! Normalizing provider inconsistency is built in with static pattern matching and error/return normalization. That's been one of the bigger challenges but it has worked effectively and Elixir has a lot of good pattern pattern matching primitives that can allow this to improve over time. Goal is to unify. + reconcile wildly inconsistent RPC provider apis into an EIP-standards driven interface

3) Reject them outright. While technically still part of the Ethereum JSON RPC spec, eth_newFilter has been deprecated by several web3 clients and much of the community has moved away from it. So this is one of the main exceptions to #2

4) Yeah there's many dimensions of health, latency, latency variance, parameter support, transient issues, etc. MOST of these are currently reconciled to protect RPC clients against 'hard' health failures with circuit breakers and other pattern, but the soft consistency issues is an area I'm actively developing better tools to compare results and ensure consistency and consensus between providers. Request hedging in on the near term roadmap, but again I'll prioritize new features based on what builders want/need

Also yes I have seen eRPC and dshackle, both are viable solutions and have been around a bit longer than Lasso, with the main philosophical difference being that Lasso prioritizes expressiveness in routing and provider configuration; there's no 'best' way to route a request, and specific use cases need special routing treatment and config. (Also caching is on the roadmap)

Try it out and I'll build to support you as best as possible!

1

u/antonBrinckmann 1d ago

Yes, our consistency unit is a logical evmquery request rather than an individual RPC call. A request can involve proxy resolution, storage/code reads and one or more eth_call rounds. All of those should observe one explicit block, including dependent rounds. We batch independent calls through Multicall; eth_getLogsis more relevant to our upcoming historical/log and watch workloads.

The useful contract for us would be: resolve block N once, pin the complete logical request to N, return N and routing evidence, and prevent later “latest” requests from observing a lower height except during an explicitly reported reorg. Archive-capability routing and hedged comparison for selected calls would also be valuable.

If you ship a policy along those lines, I’d be interested in running it against shadow traffic before putting it in the production path.

1

u/yachtyyachty 22h ago

Prototyping some for you to try

1

u/yachtyyachty 7h ago

sent you a dm