-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
eed1587
commit 1c9cfce
Showing
2 changed files
with
201 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,108 @@ | ||
Electric Eel (`eleel`) | ||
==== | ||
|
||
This is a multiplexer for Ethereum execution clients. It allows multiple consensus | ||
clients to connect to a single execution client endpoint. | ||
Eleel is a multiplexer for Ethereum execution clients. It allows multiple consensus | ||
clients to connect to a single execution client. | ||
|
||
There are several limitations: | ||
It is suitable for monitoring and analytics but **should not** be used to run | ||
validators and **will** cause you to miss block proposals if you attempt this. | ||
|
||
- Implementation is WIP. | ||
- One consensus node must be nominated as the controlling node. | ||
- No payload building -- `eleel` will never send payload attributes to the EL: use a builder. | ||
Eleel is written in Rust and makes use of components from [Lighthouse][]. | ||
|
||
`eleel` is API-compatible with [`openexecution`][openexecution], rewritten in | ||
Rust to take advantage of the stronger type-system and to reuse components from | ||
[Lighthouse][]. | ||
## Build from source | ||
|
||
[openexecution]: https://github.com/TennisBowling/openexecution | ||
[Lighthouse]: https://github.com/sigp/lighthouse | ||
``` | ||
cargo install --release --locked | ||
``` | ||
|
||
A binary will be installed to `~/.cargo/bin/eleel`. | ||
|
||
## Getting started | ||
|
||
Eleel needs to connect to a _real_ execution node, e.g. Geth/Nethermind/Besu. You | ||
should set up an execution node and take note of the JWT secret it uses. We'll provide it to | ||
Eleel's `--ee-jwt-secret` flag. | ||
|
||
Eleel also needs a _controlling consensus node_ (e.g. Lighthouse) which is responsible for driving | ||
the execution node. The controlling node is _in charge_, and its messages will be sent | ||
directly to the execution node. The controller connects to Eleel using the `/canonical` path. There | ||
is a second JWT secret for authenticating the controller to Eleel, which is set using the | ||
`--controller-jwt-secret` flag. | ||
|
||
You can generate a new JWT secret using this command: | ||
|
||
``` | ||
openssl rand -hex 32 | tr -d "\n" | ||
``` | ||
|
||
In addition to the single controller node, Eleel also supports _multiple_ consensus clients, | ||
which can be authenticated using any of a collection of JWT secrets specified in a TOML config | ||
file. There are a lot of JWT secrets! An example TOML file can be seen below: | ||
|
||
```toml | ||
[secrets] | ||
node1 = "c259fb249f7fa1882b1d4150ace73c1023aba4f6267b29a871ad5c9adc7a543a" | ||
node2 = "fb6073f77160f9a7ce11190d3612e841daea2e7319a59e1d82a8804e9fa193ee" | ||
``` | ||
|
||
The identifiers `node1` and `node2` are _key IDs_ which are used by Eleel to decide which secret | ||
to use when authenticating a request. It does this by examining the `key` field of the claim | ||
(distinct from the standard JWT key-id). If the `key` is not set by the client then Eleel | ||
tries all of the keys in a random order looking for a match (slow). | ||
|
||
Putting this all together, here's an example of Eleel sharing a Geth node between two Lighthouse | ||
nodes: | ||
|
||
Eleel, connected to Geth on port 8551 and serving the consensus nodes on port 8552: | ||
|
||
``` | ||
eleel \ | ||
--ee-jwt-secret /tmp/execution.jwt \ | ||
--ee-url "http://localhost:8551" \ | ||
--controller-jwt-secret /tmp/controller.jwt \ | ||
--client-jwt-secrets /tmp/client-secrets.toml \ | ||
--listen-port 8552 | ||
``` | ||
|
||
Geth, using the same JWT secret that Eleel uses to connect to it: | ||
|
||
``` | ||
geth --authrpc.jwtsecret /tmp/execution.jwt --authrpc.port 8551 | ||
``` | ||
|
||
Lighthouse running as the controller and connected to Eleel's `/canonical` endpoint: | ||
|
||
``` | ||
lighthouse bn \ | ||
--execution-endpoint "http://localhost:8552/canonical" \ | ||
--execution-jwt "/tmp/controller.jwt" | ||
``` | ||
|
||
Lighthouse running as a client connected to Eleel's `/` endpoint: | ||
|
||
``` | ||
lighthouse bn \ | ||
--execution-endpoint "http://localhost:8552" \ | ||
--execution-jwt "/tmp/node1.jwt" \ | ||
--execution-jwt-id "node1" | ||
``` | ||
|
||
### CLI reference | ||
|
||
For full CLI options see [`./docs/cli-reference.md`](./docs/cli-reference.md), or run | ||
`eleel --help`. | ||
|
||
## Block Building | ||
|
||
Eleel does not build valid execution blocks, but will build _invalid_ dummy execution | ||
payloads. This is designed for use with [blockdreamer][blockdreamer] only and | ||
**will cause you to propose invalid blocks** if used by a validator client. | ||
|
||
## License | ||
|
||
Copyright Sigma Prime 2023 and contributors. | ||
|
||
Licensed under the terms of the Apache 2.0 license. | ||
|
||
[Lighthouse]: https://github.com/sigp/lighthouse | ||
[blockdreamer]: https://github.com/blockprint-collective/blockdreamer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
``` | ||
Ethereum execution engine multiplexer | ||
Usage: eleel [OPTIONS] --ee-jwt-secret <PATH> --controller-jwt-secret <PATH> --client-jwt-secrets <PATH> | ||
Options: | ||
--listen-address <IP> | ||
Listening address for the HTTP server | ||
[default: 127.0.0.1] | ||
--listen-port <PORT> | ||
Listening port for the HTTP server | ||
[default: 8552] | ||
--ee-url <URL> | ||
Primary execution engine to be shared by connected consensus nodes | ||
[default: http://localhost:8551] | ||
--ee-jwt-secret <PATH> | ||
Path to the JWT secret for the primary execution engine | ||
--controller-jwt-secret <PATH> | ||
Path to the JWT secret for the controlling consensus client | ||
--client-jwt-secrets <PATH> | ||
Path to TOML file of JWT secrets for the non-controlling consensus clients. | ||
See docs for TOML file format. | ||
--new-payload-cache-size <N> | ||
Number of recent newPayload messages to cache in memory | ||
[default: 64] | ||
--fcu-cache-size <N> | ||
Number of recent forkchoiceUpdated messages to cache in memory | ||
[default: 64] | ||
--payload-builder-cache-size <N> | ||
Number of payload attributes and past payloads to cache in memory | ||
[default: 8] | ||
--payload-builder-extra-data <STRING> | ||
Extra data to include in produced blocks | ||
[default: Eleel] | ||
--justified-block-cache-size <N> | ||
Number of justified block hashes to cache in memory | ||
[default: 4] | ||
--finalized-block-cache-size <N> | ||
Number of finalized block hashes to cache in memory | ||
[default: 4] | ||
--fcu-matching <NAME> | ||
Choose the type of matching to use before returning a VALID fcU message to a client | ||
[default: loose] | ||
Possible values: | ||
- exact: match head/safe/finalized from controller exactly | ||
- loose: match head and sanity check safe/finalized | ||
- head-only: match head and ignore safe/finalized (dangerous) | ||
--network <NAME> | ||
Network that the consensus and execution nodes are operating on | ||
[default: mainnet] | ||
--new-payload-wait-millis <MILLIS> | ||
Maximum time that a consensus node should wait for a newPayload response from the cache. | ||
We expect that the controlling consensus node and primary execution node will take some time to process requests, and that requests from consensus nodes could arrive while this processing is on-going. Using a timeout of 0 will often result in a SYNCING response, which will put the consensus node into optimistic sync. Using a longer timeout will allow the definitive (VALID) response from the execution engine to be returned, more closely matching the behaviour of a full execution engine. | ||
[default: 2000] | ||
--new-payload-wait-cutoff <NUM_BLOCKS> | ||
Maximum age of a payload that will trigger a wait on `newPayload` | ||
Payloads older than this age receive an instant SYNCING response. See docs for `--new-payload-wait-millis` for the purpose of this wait. | ||
[default: 64] | ||
--fcu-wait-millis <MILLIS> | ||
Maximum time that a consensus node should wait for a forkchoiceUpdated response from the cache. | ||
See the docs for `--new-payload-wait-millis` for the purpose of this timeout. | ||
[default: 1000] | ||
--body-limit-mb <MEGABYTES> | ||
Maximum size of JSON-RPC message to accept from any connected consensus node | ||
[default: 128] | ||
-h, --help | ||
Print help (see a summary with '-h') | ||
``` |