When we created EtherCattle and subsequently Cardinal, the goal was to make Ethereum infrastructure easier to manage from an operational perspective. We’ve got to admit, the merge kind of threw a wrench in the works.
Operationally manageable infrastructure should have no single-point-of-failure
- No single service that, if it crashed, would take down the whole system. With our Cardinal stack, we can have multiple Ethereum nodes feeding data into a redundant Kafka cluster to be consumed by multiple Cardinal Replicas and Flume indexes. Any single service can fail with no impact to availability.
But beacon nodes complicate things. Beacon nodes have a many-to-one relationship with execution clients (like Geth); you can have multiple beacon nodes served by a single Geth node, but not the other way around. This is a problem from a single-point-of-failure perspective - If your Geth node dies, your beacon nodes can no longer validate blocks. And if your goal is to run many Geth nodes (perhaps for RPC capacity), you have to run just as many beacon nodes.
This left us with two apparent options at Rivet:
Option one was to run Beacon nodes and Geth nodes together on the same server. We didn’t love this idea because it would force them to share resources, and potentially push them onto larger servers
Option two was to write a muxing utility: aggregate updates from the beacon chain through a message broker (like Kafka), then apply updates as needed to the Geth clients. This lets us have beacon clients on their own servers (potentially even running different beacon clients on different servers) while running an independent collection of execution clients on their own servers (again, potentially even running different execution clients on different servers).
If you need multiple execution nodes to handle RPC requests, you can run one beacon nodes to support as many execution clients as you need for your level of throughput (we’d recommend running two for high availability, but if one cuts out for a bit you can survive on one).
On the other hand, if you’re staking your own validator nodes, you can run two execution clients to support all of your validators rather than having a singular execution client looming as a single point of failure.
Checkout Cardinal Beacon Mux on Github, and stop by our Discord Server if you have any questions.