I’m happy to announce that this PR brings support for different EL clients to rbuilder.
The benefit of this effort is increasing client diversity in BuilderNet
The solution is quite simple; it assumes there is an external EL client to which rbuilder
connects via IPC (by external, I mean external to the rbuilder
process).
Implementation details
This solution leverages IPC-RPC calls to provide the state to rbuilder
, which is then used during transaction execution. Final state root calculation is currently not done by the rbuilder
but by the external node.
The benefits of this approach are that it’s quite generic, and any client implementation can now leverage rbuilder
for block building.
The biggest downside is the overhead the IPC brings, as every time EVM needs some state data, it makes an IPC call. And even though IPC by itself isn’t that expensive, when coupled with JSON serialization/deserialization and the sheer amount of requests, it adds up.
That being said, we are already investigating ways to improve performance. An example of this is our custom IPC library implementation, as the one provided by alloy-rs was not well suited for this solution.
Node requirements
There are a couple of custom RPC calls EL clients must implement in order for this solution to work.
These are:
rbuilder_calculateStateRoot
for state root calculationrbuilder_getCodeByHash
given Bytecode hash, returns Bytecoderbuilder_getBlockHash
gets the block hash given block number (similar toeth_getBlockByNumber
, but just returns block hash)rbuilder_getAccount
gets account info (similar toeth_getProof
, but w/o proof stuff)
Please follow this link to see the expected arguments and responses for each of the calls mentioned above.
I’m proud to say that the Nethermind client already supports all of the RPC methods defined above, and we have tested this solution heavily using the Nethermind client.
How to run rbuilder with Nethermind Client (NMC)
Nethermind config
- Build the latest
main
branch. Here is a guide on how to build from the source - Follow this guide on how to run NMC. Importantly pass the following flags when starting the NMC:
--jsonrpc-enabledmodules [rbuilder, Eth, Subscribe, TxPool, Rpc]
to enable all necessary JSON-RPC modules--jsonrpc-ipcunixdomainsocketpath ~/execution-data/nm.ipc
to enable IPC communcation--jsonrpc-websocketsport 8546
to enable Webscokets--JsonRpc.IpcProcessingConcurrency 16 --JsonRpc.WebSocketsProcessingConcurrency 2
For better IPC and WebSokcet perf.
Full command example:
./nethermind -c mainnet --data-dir ~/execution-data --jsonrpc-jwtsecretfile ~/jwt.hex --healthchecks-enabled true --jsonrpc-enabledmodules [Eth,Subscribe,Trace,TxPool,Web3,Personal,Proof,Net,Parity,Health,Rpc,rbuilder,admin] --JsonRpc.Host 0.0.0.0 --jsonrpc-ipcunixdomainsocketpath ~/execution-data/nm.ipc --sync-nonvalidatornode true --jsonrpc-websocketsport 8546 --Sync.DownloadReceiptsInFastSync false --JsonRpc.IpcProcessingConcurrency 16 --JsonRpc.WebSocketsProcessingConcurrency 2 --TxPool.BlobsSupport InMemory
rbuilder config
- Download latest rbuilder version (as of time of writing it’s
v1.0.0
) or build from the soruce - start rbuilder like you usually would, e.g.
rbuilder run config.toml
- Make sure
config.toml
has following
[ipc_provider]
ipc_path = "<path_to_ipc>"
mempool_server_url = "ws://localhost:8546"
request_timeout_ms = 100 # after how long IPC request will timeout in ms
Example of full config.toml
log_level = "info,rbuilder=info"
redacted_telemetry_server_port = 6061
redacted_telemetry_server_ip = "0.0.0.0"
full_telemetry_server_port = 6060
full_telemetry_server_ip = "0.0.0.0"
chain = "mainnet"
coinbase_secret_key = "<secret_key>"
relay_secret_key = "<secret_key>"
cl_node_url = "http://localhost:5052"
jsonrpc_server_port = 8645
jsonrpc_server_ip = "0.0.0.0"
ignore_cancellable_orders = true
watchdog_timeout_sec = 600
simulation_threads = 4
sbundle_mergeable_signers = []
live_builders = [ "mgp-ordering", "mp-ordering"]
[ipc_provider]
ipc_path = "/root/execution-data/nm.ipc"
mempool_server_url = "ws://localhost:8546"
request_timeout_ms = 100
[[relays]]
name = "flashbots"
url = "http://localhost:80"
priority = 0
[[builders]]
name = "mgp-ordering"
algo = "ordering-builder"
discard_txs = true
sorting = "mev-gas-price"
failed_order_retries = 1
drop_failed_orders = true
[[builders]]
name = "mp-ordering"
algo = "ordering-builder"
discard_txs = true
sorting = "max-profit"
failed_order_retries = 1
drop_failed_orders = true
Final thoughts
Feedback and comments are appreciated, please reach out!
Made possible with by the Nethermind and Flashbots teams.