Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a reth-based relay #129

Open
ralexstokes opened this issue Sep 13, 2023 · 10 comments
Open

Implement a reth-based relay #129

ralexstokes opened this issue Sep 13, 2023 · 10 comments

Comments

@ralexstokes
Copy link
Owner

Following the successful integration of reth in the builder (see #112), I'd like to scope out what it would look like to build a relay using reth.

The relay would follow a similar design built as an extension around reth and have access to a local CL node.

The relevant relay API requiring the execution node is the block submission endpoint where builders submit bids for the mev-boost auction.

Requirements

At a high-level, this endpoint:

  1. identifies the chain tip for the submission (slot and parent_hash, and implicitly checking proposer via the preferences validation done next)
  2. get the validator preferences for this chain tip and verify they match what is in the bid (proposer_fee_recipient and gas_limit)
  3. verify the builder signature
  4. verify the execution of the payload is valid
  5. payment verification

Steps (4) and (5) require EL support. To address (4), we would like some API to hand a payload off to reth and have it verify the execution. Moreover, it should support execution on any chain tip it knows about, not just the canonical chain. To address (5), we need to know which payment scheme(s) the relay supports. Two common schemes are "end-of-block (EOB)" ETH transfers and COINBASE payments. The following just focuses on EOB payments and leaves the COINBASE route to future work.

Implementing (4)

I have already sketched out a high-level API here to handle block validation. This sketch suggests one route: just extend reth with this endpoint w/ a custom RPC call. I would prefer a more direct route that skips what is ultimately an unnecessary API call as we can find a tighter integration w/ the reth software.

If we just do the ad-hoc thing, it would be exposing some kind of BlockValidator as an extension to the CLI that exposes the client's implementation of this trait BlockExecutor. I have traced a call to this here: https://github.com/paradigmxyz/reth/blob/main/crates/storage/provider/src/traits/executor.rs#L22 which is used in the debug_cmd binary.

One possible implementation for the relay under this design is that the relay has a BlockValidator component that implements the required CLI extension trait to be called during reth startup. This component could e.g. launch an async (blocking) task that just waits for block validation requests on some channel (coming from the rest of the relay infra), call the BlockExecutor::execute_and_verify_receipt method and then return the result as desired.

Implementing (5)

To handle EOB payments, we actually just need to know the last payment in the block was successful (and the rest of the block was valid). The rest of the verifications are just static checks we can perform outside reth proper, even just using something like ethers. Assuming we knew the full block was valid from the prior step, we can simply take advantage of the execute_and_verify_receipt API and grab the receipts from the PostState returned from that method. We can then see if the payment transaction was successfully executed and then check everything else about the syntax of the transaction.

To implement COINBASE payments, we could likely also look at the PostState object but I'll leave this alone for now.

if someone wants to make a pass at this, here's the PR for the relevant functionality we would want to support: flashbots/builder#93

Other notes

Can we just use BlockExecutor::execute? Upon closer inspection, it looks like execute_and_verify_receipt just supports an older behavior from many execution forks ago, which I don't feel the need to support here.

I think the "just add a block validator CLI ext" method would work and work well, although it is a bit ad-hoc. Hoping some reth devs can chime in if they see a better solution.

@PatStiles
Copy link

PatStiles commented Sep 13, 2023

Interested in working on this as expressed in #113 3 for my EPF. For now I’ll finish up the validation checks I laid out in this pr and open a separate WIP one for (4). Will then reach out for your guys feedback @ralexstokes @jacobkaufmann

@ralexstokes
Copy link
Owner Author

@PatStiles great! we are working through the right way to integrate reth and given that this decision will have pretty far-reaching consequences for the structure of the relay we want to sort this out first before doing much more on the other parts of the relay

I intend to open a "dev roadmap" to a relay MVP soon once we have this (big) question figured out

@ralexstokes
Copy link
Owner Author

I have some notes on a design here:

https://hackmd.io/@ralexstokes/mev-relay-rs-design-doc

@PatStiles
Copy link

I have some notes on a design here:

https://hackmd.io/@ralexstokes/mev-relay-rs-design-doc

It’s not visible on my end due to permissions.

@ralexstokes
Copy link
Owner Author

I have some notes on a design here:
https://hackmd.io/@ralexstokes/mev-relay-rs-design-doc

It’s not visible on my end due to permissions.

@PatStiles I believe you just need to be logged in (you can authenticate w/ GitHub)

@ralexstokes ralexstokes pinned this issue Sep 20, 2023
@PatStiles
Copy link

PatStiles commented Sep 24, 2023

@ralexstokes Was debating starting the Proposer Auction as @chirag-bgh has started implementing the Builder Auction per your comments in the design doc. Was wondering if I should hold off?

@ralexstokes
Copy link
Owner Author

there will be explicit issues in this repo once we have left the design phase, if you move ahead of that process you may be doing some work that will be thrown away

@chirag-bgh
Copy link
Contributor

chirag-bgh commented Sep 26, 2023

Implementing (4)

I have already sketched out a high-level API here to handle block validation. This sketch suggests one route: just extend reth with this endpoint w/ a custom RPC call. I would prefer a more direct route that skips what is ultimately an unnecessary API call as we can find a tighter integration w/ the reth software.

If we just do the ad-hoc thing, it would be exposing some kind of BlockValidator as an extension to the CLI that exposes the client's implementation of this trait BlockExecutor. I have traced a call to this here: https://github.com/paradigmxyz/reth/blob/main/crates/storage/provider/src/traits/executor.rs#L22 which is used in the debug_cmd binary.

One possible implementation for the relay under this design is that the relay has a BlockValidator component that implements the required CLI extension trait to be called during reth startup. This component could e.g. launch an async (blocking) task that just waits for block validation requests on some channel (coming from the rest of the relay infra), call the BlockExecutor::execute_and_verify_receipt method and then return the result as desired.

I think we can take inspiration from this: ultrasoundmoney/reth#5
This would be more of what we need exactly: ultrasoundmoney/reth-payload-validator#1

@ckoopmann
Copy link

Implementing (4)

I have already sketched out a high-level API here to handle block validation. This sketch suggests one route: just extend reth with this endpoint w/ a custom RPC call. I would prefer a more direct route that skips what is ultimately an unnecessary API call as we can find a tighter integration w/ the reth software.
If we just do the ad-hoc thing, it would be exposing some kind of BlockValidator as an extension to the CLI that exposes the client's implementation of this trait BlockExecutor. I have traced a call to this here: https://github.com/paradigmxyz/reth/blob/main/crates/storage/provider/src/traits/executor.rs#L22 which is used in the debug_cmd binary.
One possible implementation for the relay under this design is that the relay has a BlockValidator component that implements the required CLI extension trait to be called during reth startup. This component could e.g. launch an async (blocking) task that just waits for block validation requests on some channel (coming from the rest of the relay infra), call the BlockExecutor::execute_and_verify_receipt method and then return the result as desired.

I think we can take inspiration from this: ultrasoundmoney/reth#5 This would be more of what we need exactly: ultrasoundmoney/reth-payload-validator#1

Would love to support / colab on this.
Btw: The most performant way might be trying to implement the reth communication using direct db access instead of going via rpc. But will probably be more complex. (if possible at all to implement all required features).

See:
https://github.com/paradigmxyz/reth/blob/main/examples/db-access.rs

@chirag-bgh
Copy link
Contributor

Would love to support / colab on this. Btw: The most performant way might be trying to implement the reth communication using direct db access instead of going via rpc. But will probably be more complex. (if possible at all to implement all required features).

See: https://github.com/paradigmxyz/reth/blob/main/examples/db-access.rs

Sure!
This could be helpful for direct db access bypassing the rpc: https://github.com/SorellaLabs/ethers-reth

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants