Skip to content

Commit

Permalink
Add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelsproul committed Sep 27, 2023
1 parent eed1587 commit 1c9cfce
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 11 deletions.
106 changes: 95 additions & 11 deletions README.md
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
106 changes: 106 additions & 0 deletions docs/cli-reference.md
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')
```

0 comments on commit 1c9cfce

Please sign in to comment.