775d222299
## Proposed Changes With proposer boosting implemented (#2822) we have an opportunity to re-org out late blocks. This PR adds three flags to the BN to control this behaviour: * `--disable-proposer-reorgs`: turn aggressive re-orging off (it's on by default). * `--proposer-reorg-threshold N`: attempt to orphan blocks with less than N% of the committee vote. If this parameter isn't set then N defaults to 20% when the feature is enabled. * `--proposer-reorg-epochs-since-finalization N`: only attempt to re-org late blocks when the number of epochs since finalization is less than or equal to N. The default is 2 epochs, meaning re-orgs will only be attempted when the chain is finalizing optimally. For safety Lighthouse will only attempt a re-org under very specific conditions: 1. The block being proposed is 1 slot after the canonical head, and the canonical head is 1 slot after its parent. i.e. at slot `n + 1` rather than building on the block from slot `n` we build on the block from slot `n - 1`. 2. The current canonical head received less than N% of the committee vote. N should be set depending on the proposer boost fraction itself, the fraction of the network that is believed to be applying it, and the size of the largest entity that could be hoarding votes. 3. The current canonical head arrived after the attestation deadline from our perspective. This condition was only added to support suppression of forkchoiceUpdated messages, but makes intuitive sense. 4. The block is being proposed in the first 2 seconds of the slot. This gives it time to propagate and receive the proposer boost. ## Additional Info For the initial idea and background, see: https://github.com/ethereum/consensus-specs/pull/2353#issuecomment-950238004 There is also a specification for this feature here: https://github.com/ethereum/consensus-specs/pull/3034 Co-authored-by: Michael Sproul <micsproul@gmail.com> Co-authored-by: pawan <pawandhananjay@gmail.com>
232 lines
11 KiB
Markdown
232 lines
11 KiB
Markdown
# MEV and Lighthouse
|
|
|
|
Lighthouse is able to interact with servers that implement the [builder
|
|
API](https://github.com/ethereum/builder-specs), allowing it to produce blocks without having
|
|
knowledge of the transactions included in the block. This enables Lighthouse to outsource the job of
|
|
transaction gathering/ordering within a block to parties specialized in this particular task. For
|
|
economic reasons, these parties will refuse to reveal the list of transactions to the validator
|
|
before the validator has committed to (i.e. signed) the block. A primer on MEV can be found
|
|
[here](https://ethereum.org/en/developers/docs/mev).
|
|
|
|
Using the builder API is not known to introduce additional slashing risks, however a live-ness risk
|
|
(i.e. the ability for the chain to produce valid blocks) is introduced because your node will be
|
|
signing blocks without executing the transactions within the block. Therefore, it won't know whether
|
|
the transactions are valid, and it may sign a block that the network will reject. This would lead to
|
|
a missed proposal and the opportunity cost of lost block rewards.
|
|
|
|
## How to connect to a builder
|
|
|
|
The beacon node and validator client each require a new flag for lighthouse to be fully compatible with builder API servers.
|
|
|
|
```
|
|
lighthouse bn --builder https://mainnet-builder.test
|
|
```
|
|
The `--builder` flag will cause the beacon node to query the provided URL during block production for a block
|
|
payload with stubbed-out transactions. If this request fails, Lighthouse will fall back to the local
|
|
execution engine and produce a block using transactions gathered and verified locally.
|
|
|
|
The beacon node will *only* query for this type of block (a "blinded" block) when a validator specifically requests it.
|
|
Otherwise, it will continue to serve full blocks as normal. In order to configure the validator client to query for
|
|
blinded blocks, you should use the following flag:
|
|
|
|
```
|
|
lighthouse vc --builder-proposals
|
|
```
|
|
With the `--builder-proposals` flag, the validator client will ask for blinded blocks for all validators it manages.
|
|
In order to configure whether a validator queries for blinded blocks check out [this section.](#validator-client-configuration)
|
|
|
|
## Multiple builders
|
|
|
|
Lighthouse currently only supports a connection to a single builder. If you'd like to connect to multiple builders or
|
|
relays, run one of the following services and configure lighthouse to use it with the `--builder` flag.
|
|
|
|
* [`mev-boost`][mev-boost]
|
|
* [`mev-rs`][mev-rs]
|
|
|
|
## Validator Client Configuration
|
|
|
|
In the validator client you can configure gas limit and fee recipient on a per-validator basis. If no gas limit is
|
|
configured, Lighthouse will use a default gas limit of 30,000,000, which is the current default value used in execution
|
|
engines. You can also enable or disable use of external builders on a per-validator basis rather than using
|
|
`--builder-proposals`, which enables external builders for all validators. In order to manage these configurations
|
|
per-validator, you can either make updates to the `validator_definitions.yml` file or you can use the HTTP requests
|
|
described below.
|
|
|
|
Both the gas limit and fee recipient will be passed along as suggestions to connected builders. If there is a discrepancy
|
|
in either, it will *not* keep you from proposing a block with the builder. This is because the bounds on gas limit are
|
|
calculated based on prior execution blocks, so an honest external builder will make sure that even if your
|
|
requested gas limit value is out of the specified range, a valid gas limit in the direction of your request will be
|
|
used in constructing the block. Depending on the connected relay, payment to the proposer might be in the form of a
|
|
transaction within the block to the fee recipient, so a discrepancy in fee recipient might not indicate that there
|
|
is something afoot.
|
|
|
|
> Note: The gas limit configured here is effectively a vote on block size, so the configuration should not be taken lightly.
|
|
> 30,000,000 is currently seen as a value balancing block size with how expensive it is for
|
|
> the network to validate blocks. So if you don't feel comfortable making an informed "vote", using the default value is
|
|
> encouraged. We will update the default value if the community reaches a rough consensus on a new value.
|
|
|
|
### Set Gas Limit via HTTP
|
|
|
|
To update gas limit per-validator you can use the [standard key manager API][gas-limit-api].
|
|
|
|
Alternatively, you can use the [lighthouse API](api-vc-endpoints.md). See below for an example.
|
|
|
|
### Enable/Disable builder proposals via HTTP
|
|
|
|
Use the [lighthouse API](api-vc-endpoints.md) to enable/disable use of the builder API on a per-validator basis.
|
|
You can also update the configured gas limit with these requests.
|
|
|
|
#### `PATCH /lighthouse/validators/:voting_pubkey`
|
|
|
|
|
|
#### HTTP Specification
|
|
|
|
| Property | Specification |
|
|
|-------------------|--------------------------------------------|
|
|
| Path | `/lighthouse/validators/:voting_pubkey` |
|
|
| Method | PATCH |
|
|
| Required Headers | [`Authorization`](./api-vc-auth-header.md) |
|
|
| Typical Responses | 200, 400 |
|
|
|
|
#### Example Path
|
|
|
|
```
|
|
localhost:5062/lighthouse/validators/0xb0148e6348264131bf47bcd1829590e870c836dc893050fd0dadc7a28949f9d0a72f2805d027521b45441101f0cc1cde
|
|
```
|
|
|
|
#### Example Request Body
|
|
Each field is optional.
|
|
```json
|
|
{
|
|
"builder_proposals": true,
|
|
"gas_limit": 30000001
|
|
}
|
|
```
|
|
|
|
#### Example Response Body
|
|
|
|
```json
|
|
null
|
|
```
|
|
### Fee Recipient
|
|
|
|
Refer to [suggested fee recipient](suggested-fee-recipient.md) documentation.
|
|
|
|
### Validator definitions example
|
|
|
|
You can also directly configure these fields in the `validator_definitions.yml` file.
|
|
|
|
```
|
|
---
|
|
- enabled: true
|
|
voting_public_key: "0x87a580d31d7bc69069b55f5a01995a610dd391a26dc9e36e81057a17211983a79266800ab8531f21f1083d7d84085007"
|
|
type: local_keystore
|
|
voting_keystore_path: /home/paul/.lighthouse/validators/0x87a580d31d7bc69069b55f5a01995a610dd391a26dc9e36e81057a17211983a79266800ab8531f21f1083d7d84085007/voting-keystore.json
|
|
voting_keystore_password_path: /home/paul/.lighthouse/secrets/0x87a580d31d7bc69069b55f5a01995a610dd391a26dc9e36e81057a17211983a79266800ab8531f21f1083d7d84085007
|
|
suggested_fee_recipient: "0x6cc8dcbca744a6e4ffedb98e1d0df903b10abd21"
|
|
gas_limit: 30000001
|
|
builder_proposals: true
|
|
- enabled: false
|
|
voting_public_key: "0xa5566f9ec3c6e1fdf362634ebec9ef7aceb0e460e5079714808388e5d48f4ae1e12897fed1bea951c17fa389d511e477"
|
|
type: local_keystore voting_keystore_path: /home/paul/.lighthouse/validators/0xa5566f9ec3c6e1fdf362634ebec9ef7aceb0e460e5079714808388e5d48f4ae1e12897fed1bea951c17fa389d511e477/voting-keystore.json
|
|
voting_keystore_password: myStrongpa55word123&$
|
|
suggested_fee_recipient: "0xa2e334e71511686bcfe38bb3ee1ad8f6babcc03d"
|
|
gas_limit: 33333333
|
|
builder_proposals: true
|
|
```
|
|
|
|
## Circuit breaker conditions
|
|
|
|
By outsourcing payload construction and signing blocks without verifying transactions, we are creating a new risk to
|
|
live-ness. If most of the network is using a small set of relays and one is bugged, a string of missed proposals could
|
|
happen quickly. This is not only generally bad for the network, but if you have a proposal coming up, you might not
|
|
realize that your next proposal is likely to be missed until it's too late. So we've implemented some "chain health"
|
|
checks to try and avoid scenarios like this.
|
|
|
|
By default, Lighthouse is strict with these conditions, but we encourage users to learn about and adjust them.
|
|
|
|
- `--builder-fallback-skips` - If we've seen this number of skip slots on the canonical chain in a row prior to proposing, we will NOT query
|
|
any connected builders, and will use the local execution engine for payload construction.
|
|
- `--builder-fallback-skips-per-epoch` - If we've seen this number of skip slots on the canonical chain in the past `SLOTS_PER_EPOCH`, we will NOT
|
|
query any connected builders, and will use the local execution engine for payload construction.
|
|
- `--builder-fallback-epochs-since-finalization` - If we're proposing and the chain has not finalized within
|
|
this number of epochs, we will NOT query any connected builders, and will use the local execution engine for payload
|
|
construction. Setting this value to anything less than 2 will cause the node to NEVER query connected builders. Setting
|
|
it to 2 will cause this condition to be hit if there are skips slots at the start of an epoch, right before this node
|
|
is set to propose.
|
|
- `--builder-fallback-disable-checks` - This flag disables all checks related to chain health. This means the builder
|
|
API will always be used for payload construction, regardless of recent chain conditions.
|
|
|
|
## Builder Profit Threshold
|
|
|
|
If you are generally uneasy with the risks associated with outsourced payload production (liveness/censorship) but would
|
|
consider using it for the chance of out-sized rewards, this flag may be useful:
|
|
|
|
`--builder-profit-threshold <WEI_VALUE>`
|
|
|
|
The number provided indicates the minimum reward that an external payload must provide the proposer for it to be considered
|
|
for inclusion in a proposal. For example, if you'd only like to use an external payload for a reward of >= 0.25 ETH, you
|
|
would provide your beacon node with `--builder-profit-threshold 250000000000000000`. If it's your turn to propose and the
|
|
most valuable payload offered by builders is only 0.1 ETH, the local execution engine's payload will be used. Currently,
|
|
this threshold just looks at the value of the external payload. No comparison to the local payload is made, although
|
|
this feature will likely be added in the future.
|
|
|
|
## Checking your builder config
|
|
|
|
You can check that your builder is configured correctly by looking for these log messages.
|
|
|
|
On start-up, the beacon node will log if a builder is configured:
|
|
|
|
```
|
|
INFO Connected to external block builder
|
|
```
|
|
|
|
At regular intervals the validator client will log that it successfully registered its validators
|
|
with the builder network:
|
|
|
|
```
|
|
INFO Published validator registrations to the builder network
|
|
```
|
|
|
|
When you successfully propose a block using a builder, you will see this log on the beacon node:
|
|
|
|
```
|
|
INFO Successfully published a block to the builder network
|
|
```
|
|
|
|
If you don't see that message around the time of your proposals, check your beacon node logs
|
|
for `INFO` and `WARN` messages indicating why the builder was not used.
|
|
|
|
Examples of messages indicating fallback to a locally produced block are:
|
|
|
|
```
|
|
INFO Builder did not return a payload
|
|
```
|
|
|
|
```
|
|
WARN Builder error when requesting payload
|
|
```
|
|
|
|
```
|
|
WARN Builder returned invalid payload
|
|
```
|
|
|
|
```
|
|
INFO Builder payload ignored
|
|
```
|
|
|
|
```
|
|
INFO Chain is unhealthy, using local payload
|
|
```
|
|
|
|
In case of fallback you should see a log indicating that the locally produced payload was
|
|
used in place of one from the builder:
|
|
|
|
```
|
|
INFO Reconstructing a full block using a local payload
|
|
```
|
|
|
|
[mev-rs]: https://github.com/ralexstokes/mev-rs
|
|
[mev-boost]: https://github.com/flashbots/mev-boost
|
|
[gas-limit-api]: https://ethereum.github.io/keymanager-APIs/#/Gas%20Limit
|