Alex Stokes
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    2
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # relay monitor design doc thanks to @metachris, @bertcmiller and @thegostep for helpful discussions on this design # intro this document assumes knowledge of the general `mev-boost` architecture. you will want to be familar with the `builder-specs`: https://github.com/ethereum/builder-specs and here are some diagrams that are relevant, both from the `flashbots/mev-boost` repo on github: ## high-level architecture ![](https://i.imgur.com/sf6gsKJ.png) ## builder API flow ![](https://i.imgur.com/TFkDvSR.png) # what in the initial version of `mev-boost` (https://boost.flashbots.net) there is a trusted actor that connects proposers to builders called the **relay**. the relay has a series of duties including verifying that builders supply good blocks that respect the proposers' preferences (e.g. gas limit of the block) and facilitating an auction so that proposers can efficiently allocate blockspace. while this role is trusted, it is permissionless so that anyone is able to run a relay and it is on proposers to configure "relay mux" software (e.g. https://github.com/flashbots/mev-boost) with relays of their choosing to connect to the builders they are interested in working with during each auction. to mitigate potential abuses of this role by byzantine relays, flashbots has suggested a "relay monitor": https://github.com/flashbots/mev-boost/issues/142 this document refines the ideas in that issue towards a concrete specification. # design the relay monitor (RM) uses publicly available data to form a view on the **behavior** and **performance** of the set of relays it is monitoring. this includes an "opt-in" setting of the relay mux that forwards each proposer's view of the network to the RM. doing so greatly improves the relay monitor's ability to understand what the relay (and also proposer) did for each proposal. by **behavior**, we refer to the set of responsibilites relays have to ensure safety and liveness of the ethereum protocol. users of the mev-boost ecosystem take on risk that relays and/or builders fail to fulfill these responsibilities and an important role of the RM is to ensure relays carry out their portion of requirements. by **performance**, we refer to metrics like latency and throughput relating to how well the relay works in a system context. ## types of faults ### behavior faults first, we describe the types of faults the RM watches for and the corresponding data the RM consumes for each relay and receives from each proposer. the high-level structure of the `mev-boost` flow is a commit-reveal scheme where first a set of bids are provided that commit to a given payload (`getHeader` in the API sequence diagram) and then a proposer selects one bid in a binding way by signing over a block containing the data committed to in the bid. the relay should then release the corresponding payload (`getPayload` in the sequence diagram). note that there is nothing stopping a relay from offering a bid during one call of the API and a different (likely more valuable) bid on a subsequent call. this complicates the monitoring process as the RM will not know what view the proposer had unless the proposer shares it. this fault -- "auction integrity" -- is listed for completeness but should be considered an "advanced" class of faults to detect and fault should only be assigned assuming best intentions of the relay if there is doubt. we can now look at the possible faults for each phase of the commit-reveal scheme: #### bid faults * malformed bid * relay produces some bid that is syntatically invalid (e.g. incomplete execution payload header) or has an invalid signature * **requires**: bid from relay * consensus-invalid bid * relay produces a bid that is invalid with respect to the consensus logic, e.g. the block `number` in the execution payload is wrong (note: RM should be tolerant to bids on non-canonical forks) * **requires**: bid from relay * payment-invalid bid * the payment claimed in the bid does not match the ultimate value delivered to the proposer if the payload for this bid was included on-chain * **requires**: bid from relay *AND* full payload in next step * valid bid, but nonconforming * the bid is valid wrt the prior conditions but does not reflect the latest validator preferences for the given proposer * **requires**: bid from relay, latest preferences from proposer * auction integrity: non-discriminatory * relay does not discriminate between bidders * **requires**: bid(s) from relay, bid(s) seen by proposer * auction integrity: market competition * this one came from @thegostep * relay does not deviate from its peers over a given period of time * **requires**: bid(s) from relays across a period of time #### payload faults * malformed payload * relay returns an execution payload that is syntactically invalid (e.g. missing block number) or does not match the execution payload header from the accepted bid * **requires**: payload from relay, signed blinded beacon block from proposer * consensus-invalid payload * assuming the prior conditions hold, this failure occurs if the execution payload contains invalid transactions wrt the consensus logic * **requires**: payload from relay, signed blinded beacon block from proposer * unavailable payload * relay committed to making available some payload via producing the bid in the prior step and could not make this payload available * note: if the corresponding block *eventually* ends up in the canonical chain (or even orphaned) it should not count against the relay, or perhaps as a distinct sub-fault, "published but failed to provide payload" * **requires**: payload from relay, signed blinded beacon block from proposer ### performance faults / metrics Given its central role to network security, I recommend the behavior monitoring is implemented ahead of any performance monitoring. **TODO**: flesh these out more some metrics to watch: - relay latency - relay error rate (including uptime, HTTP error rate) - not as interested in getting raw requests/sec but open to hearing otherwise ## relay monitor feature set ### goal: an indexed collection of relay faults we can start simply by tabulating the above number of faults observed for each relay. a downstream consumer can use the fault data to make their own assessment of relay risk, or form a "reputation" score, etc. this means a relay monitor keeps a mapping of fault type ordered by "chain coordinate" and indexed by relay (pubkey). for example: ```json { "0xdeadbeefcafe": { // relay pubkey "malformed-bid": [ (slot, parent-hash, proposer-pubkey) , (slot1, parent-hash1, proposer-pubkey1) ], // list of faults and 'when' they occurred, organized by fault type ..., // other faults here "unavailable-payload": [], // no availability faults observed for this relay } } ``` note: this schema is just a strawman to illustrate and is very likely to change #### aside on auditability a relay monitor will also want to persist all events ingested so that any given assessment of relay performance can be re-derived as desired. note that the input data is authenticated with the author's signature (e.g. `signature` on `BuilderBid`) and this along with the canonical chain would be able to verify the authenticity of any RM output. if some service existed to capture all block data (even off the canonical chain), you could independently verify any claims made by any relay monitor. ### how to process faults the requirements for each type of fault induce a dependency graph which suggests the following high-level functionality for the RM organized as a series of concurrent, long-running "tasks": 0. proposer preference aggregation any relay mux software should send a copy of the `SignedValidatorRegistration` to any connected relay monitors when they perform the routine calls to any connected relays. the RM stores these preferences by pubkey (and will want a validator index mapping). :::success **requires**: change `mev-boost` software to upstream validator preferences to configured relay monitors, along with relays and see note below about this being user-configurable ::: 1. bid inspection for each slot of the consensus chain and each head of the execution chain, the relay monitor fetches the offered bid from each relay for the scheduled proposer on that chain. the RM can verify the bid does not have the following faults: - malformed bid - consensus-invalid bid - valid bid, but nonconforming bids should be stored, indexed by relay pubkey and execution block hash for later analysis 2. payload inspection there is an option here depending on how much data the proposer wants to share with the relay monitor: they can send the `SignedBlindedBeaconBlock` and the `SignedBuilderBid` (let's call this the "bid acceptance data") in a call to the relay monitor alongside the `getPayload` call to the relay(s). note proposers may wish to skip this step for either privacy reasons or to avoid the resource overhead of sending the data to an additional endpoint. in the event the RM never receives the bid acceptance data from the proposer, they can still watch the canonical chain for whatever block arrives and see if they have *some* matching bid (using the execution block hash in the block on-chain), using the `value` to break ties if required. this gives less accuracy to the RM overall but supports smaller stakers (compared to say well-resourced pools) so I'd argue is a use case worth supporting. if the RM does recieve the bid acceptance data, it can finish the remaining validations after calling the appropriate relay(s) to get the corresponding execution payload: - payment-invalid bid - malformed payload - consensus-invalid payload - unavailable payload bonus: the RM can gossip the complete `SignedBeaconBlock` if they are well-peered with the rest of the Ethereum network. :::success **requires**: allow relay monitor data collection to be configurable (downstream convo if it by default and to who or not) **requires**: `mev-boost` software sends bid and signed block to RM along with the call to get the execution payload from the relay(s). ::: 3. auction inspection this section will be left opaque for now and detection of this type of fault will be considered part of the scope of some future work. it would boil down to making sure that for the set of observed data there were no inconsistencies in what proposers see and what the relays provide. ## rating API while running the data collection and fault processing described above, the RM continually computes a "scorecard" per relay like the example given above. this "rating" API can provide the current snapshot of this "scorecard" at any point a caller requests it via this API. the primary consumer of this data is the relay mux software that can use it to make policy decisions about which relays to use. :::success **requires**: `mev-boost` software should be able to call the "rating" API for a set of relay monitors and process the resulting data Q: how to handle multiple relay monitors -- just merge them all together (?) Q: points out how we want to handle "relay monitor" fraud -- to start, let's just assume RMs are trusted, even moreso than relays ::: i'd suggest there is a "default profile" baked into any relay mux software that encodes a given policy that protects against the most harmful faults. but this could become a configurable part of the `mev-boost` software. ### default profile the default fault detection algorithm is: :::info if there are `M` faults of any type by a relay across the last `N` slots, then the relay mux should stop using that relay for the next `2**N` slots ::: note: the exact profile is up for debate so if you see something you like better, please let me know! :::success **requires**: `mev-boost` software should call the rating API every epoch and process the fault data into a policy decision for any attached relays **requires**: `mev-boost` software needs to know when epochs are, or at least how long an epoch is (and can just query at some point in an epoch if not at the start) Q: we can refine to call ahead of any proposal, but then `mev-boost` needs a lot more context about the chain than it currently has -- what do we think about this? ::: ### aside on soundness there are fallback pathways in client software such that we can safely scope these policy decisions to the relay mux software and the upstream client software will work in terms of network safety and liveness. for example, the relay mux software could temporarily identify no relays for a given proposal based on recent faults and in that case the proposer software would use a local pathway to construct a block in lieu of the remote pathway enabled by the mev-boost ecosystem. ## additional notes / open questions - how to ensure everyone has the same configuration for relays? - e.g. if i have same `pubkey` but different relay endpoints and they serve different data? ## rationale / discussion ### can proposers abuse the monitoring system? - proposer can make an invalid beacon block for an honest bid - this can likely be detected and published as well also want proposer's view, and can make reputation for bad proposers, if we wanted, but this is definitely outside the scope for now ### why a "simple scorecard" to communicate reputation? easier to start with something simple, and push some work to the consumer. exposing aggregate metrics is more neutral than aggregation *and then* taking a view on relay reputation ### privacy concerns this design of the relay monitor, esp the parts where `mev-boost` software upstreams information about validators to the RM, does not respect validator privacy very well. i think this trade-off is mitigated by the opt-in nature of sending data to the RM and is appropriate given the severity of the risks it addresses. future iterations of this functionality can start incorporating constructions that obscure information flow to support better privacy.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully