mev-boost icon indicating copy to clipboard operation
mev-boost copied to clipboard

Support validator account level relay choice

Open beetrootkid opened this issue 3 years ago • 24 comments

As a node operator, different customers want to select different sources of MEV. To enable efficient distribution of validator keys across regions and consensus client types, our validator clients hold keys from different customers.

Teku and Lighthouse support specification of fee_recipient at the validator key level.

It would be great if mev-boost / builder-api could utilize the same file but with an added parameter per validator key to select the appropriate relay when that particular key is chosen to propose a block.

This would also enable solo stakers who have more than one validator to explore different sources of MEV without having to run multiple nodes.

beetrootkid avatar Jun 17 '22 09:06 beetrootkid

Could you provide a specific example?

An issue is that mev-boost and the relay needs to conform to the builder spec: https://ethereum.github.io/builder-specs/

This API spec only allows setting fee_recipient and gas_limit for a specific validator, and mev-boost is just proxying that data to the relays which prepare it for the builders. There is no way for mev-boost to select additional preferences at the builders.

metachris avatar Jun 20 '22 08:06 metachris

Ah - so, should I raise this at the builder-spec repo?

A specific example:

  • One customer "trusts" relays 3,4,5 as sources of MEV
  • Another customer "trusts" relays 1,2,3

Right now, the only way to handle this is to have different consensus clients for the two customers with differently associated MEV boost sidecars...

beetrootkid avatar Jun 20 '22 12:06 beetrootkid

hmmm i see, i think this would indeed be easiest handled in mev-boost. and it seems related to #155, file based relay list, where you could set this relation. we'll discuss internally and report back in a little bit.

metachris avatar Jun 20 '22 13:06 metachris

For reference, the Teku/Lighthouse config file format looks like this:

{
  "proposer_config": {
    "0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a": {
      "fee_recipient": "0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3",
      "validator_registration": {
        "enabled": true,
        "gas_limit": "12345654321"
      }
    }
  },
  "default_config": {
    "fee_recipient": "0x6e35733c5af9B61374A128e6F85f553aF09ff89A",
    "validator_registration": {
      "enabled": false
    }
  }
}

metachris avatar Jun 21 '22 08:06 metachris

The most simple config for mev-boost could look like this (and allow per-proposer overrides):

{
  "default_config": {
      "relays": [
          "https://0xb5246e299aeb782fbc7c91b41b3284245b1ed5206134b0028b81dfb974e5900616c67847c2354479934fc4bb75519ee1@builder-relay-kiln.flashbots.net"
      ]
  }
}

metachris avatar Jun 21 '22 08:06 metachris

The most simple config for mev-boost could look like this (and allow per-proposer overrides):

{
  "default_config": {
      "relays": [
          "https://0xb5246e299aeb782fbc7c91b41b3284245b1ed5206134b0028b81dfb974e5900616c67847c2354479934fc4bb75519ee1@builder-relay-kiln.flashbots.net"
      ]
  }
}

wouldn't make sense to add these relay entry inside validator registration? as "https://0xb5246e299aeb782fbc7c91b41b3284245b1ed5206134b0028b81dfb974e5900616c67847c2354479934fc4bb75519ee1@builder-relay-kiln.flashbots.net" refers to a particular public key.

jmcruz1983 avatar Jun 21 '22 08:06 jmcruz1983

my take:

{
  "builder_relays_groups": {
     "groupA": ["https://[email protected]", "http://..."],
     "groupB": ["https://[email protected]", "http://...."]
  },
  "proposer_config": {
    "0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a": {
      "fee_recipient": "0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3",
      "validator_registration": {
        "enabled": true,
        "builder_relays_group": "groupB",
        "gas_limit": "12345654321"
      }
    }
  },
  "default_config": {
    "fee_recipient": "0x6e35733c5af9B61374A128e6F85f553aF09ff89A",
    "validator_registration": {
      "enabled": false,
      "builder_relays_group": "groupA"
    }
  }
}

tbenr avatar Jun 21 '22 08:06 tbenr

For simplicity, I would propose following:

{
  "proposer_config": {
    "0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a": {
      "fee_recipient": "0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3",
      "validator_registration": {
        "enabled": true,
        "relay": "https://other-builder-relay-kiln.flashbots.net"
        "gas_limit": "12345654321"
      }
    }
  },
  "default_config": {
    "fee_recipient": "0x6e35733c5af9B61374A128e6F85f553aF09ff89A",
    "validator_registration": {
      "relay": "https://default-builder-relay-kiln.flashbots.net"
      "enabled": false
    }
  }
}

jmcruz1983 avatar Jun 21 '22 08:06 jmcruz1983

  • relays needs to be an array
  • i prefer to allow setting relays directly, not requiring groups
  • i'd prefer the prop be named only relays instead of builder_relays, but if we want to reuse the same config i see the argument for giving it the longer name for sake of clarity
  • how about allowing both URL and group reference?
{
    "builder_relays_groups": {
        "groupB": [
            "https://[email protected]",
            "http://...."
        ]
    },
    "proposer_config": {
        "0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a": {
            "fee_recipient": "0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3",
            "validator_registration": {
                "enabled": true,
                "builder_relays": ["https://[email protected]"],
                "gas_limit": "12345654321"
            }
        }
    },
    "default_config": {
        "fee_recipient": "0x6e35733c5af9B61374A128e6F85f553aF09ff89A",
        "validator_registration": {
            "enabled": false,
            "builder_relays": ["groupB"]
        }
    }
}

metachris avatar Jun 21 '22 08:06 metachris

  • relays needs to be an array
  • i prefer to allow setting relays directly, not requiring groups
  • i'd prefer the prop be named only relays instead of builder_relays, but if we want to reuse the same config i see the argument for giving it the longer name for sake of clarity
  • how about allowing both URL and group reference?
{
    "builder_relays_groups": {
        "groupB": [
            "https://[email protected]",
            "http://...."
        ]
    },
    "proposer_config": {
        "0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a": {
            "fee_recipient": "0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3",
            "validator_registration": {
                "enabled": true,
                "builder_relays": ["https://[email protected]"],
                "gas_limit": "12345654321"
            }
        }
    },
    "default_config": {
        "fee_recipient": "0x6e35733c5af9B61374A128e6F85f553aF09ff89A",
        "validator_registration": {
            "enabled": false,
            "builder_relays": ["groupB"]
        }
    }
}

looks good to me.

Once we find an agreement we should formalize with a schema definition so we can be clear on formats and what is required and what is optional. (ie, in teku we require default_config to be present, and other things too to minimize chances of misconfigurations)

tbenr avatar Jun 21 '22 12:06 tbenr

I'm thinking about changing from validator_registration to builder_registration.

{
  "proposer_config": {
    "0x...": {
      "fee_recipient": "0x..",
      "builder_registration": {
          "enabled": true,
          "builder_relays": ["https://[email protected]"],
          "gas_limit": "12345654321"
      }
  }
}

From a validator configuration perspective seems clearer. If that section is being translated in a validator_registration from the perspective of a builder, it's just a technicality.

tbenr avatar Jul 06 '22 10:07 tbenr

Looks good too. In this case we could consider changing builder_relays to relays because it's already in the builder context 🤔

metachris avatar Jul 06 '22 17:07 metachris

For reference: see also the Prysm PR https://github.com/prysmaticlabs/prysm/pull/10992

metachris avatar Jul 06 '22 19:07 metachris

Just to clarify things : builder_relays, either if it is in the proposer_config or the default_config, is an array of either:

  • group references
  • relay url

And can also be a combination of both ?

0xpanoramix avatar Jul 06 '22 21:07 0xpanoramix

I think it is even better to have builder instead of builder_registration. So we remove the "clash" with the internal validator_registation object.

   "builder": {
          "enabled": true,
          "relays": ["https://[email protected]"],
          "gas_limit": "12345654321"
      }

tbenr avatar Jul 07 '22 08:07 tbenr

Just to clarify things : builder_relays, either if it is in the proposer_config or the default_config, is an array of either:

  • group references
  • relay url

yes

And can also be a combination of both ?

I vote for maximum flexibility: combination

tbenr avatar Jul 07 '22 08:07 tbenr

Hey @james-prysm, in teku we are doing our final review\changes to officially release builder-related params and config. Doing that I came up with some ideas to improve UX in the proposer config file. I saw you at prysm just merged PRs for supporting this. The change that affects CL clients is just a rename of validator_registration into builder

{
    "builder_relays_groups": {
        "groupB": [
            "https://[email protected]",
            "http://...."
        ]
    },
    "proposer_config": {
        "0xa057816155ad77931185101128655c0191bd0214c201ca48ed887f6c4c6adf334070efcd75140eada5ac83a92506dd7a": {
            "fee_recipient": "0x50155530FCE8a85ec7055A5F8b2bE214B3DaeFd3",
            "builder": {
                "enabled": true,
                "relays": ["https://[email protected]"],
                "gas_limit": "12345654321"
            }
        }
    },
    "default_config": {
        "fee_recipient": "0x6e35733c5af9B61374A128e6F85f553aF09ff89A",
        "builder": {
            "enabled": false,
            "relays": ["groupB"]
        }
    }
}

tbenr avatar Jul 07 '22 08:07 tbenr

Do you think it should replace the -relays flag ? Imo yes, cause it collides with the default_config, unless we provide explicit flags for other default fields (fee_recipient, enabled)

0xpanoramix avatar Jul 12 '22 09:07 0xpanoramix

It should not replace the -relays flag, but i think if someone specifies the config and -relays, it should fail with a log message

metachris avatar Jul 12 '22 17:07 metachris

@tbenr just seeing this now... thanks for letting me know, I'll go update this.

james-prysm avatar Jul 14 '22 20:07 james-prysm

Just catching up with this from the Lighthouse side and I have a few questions

  1. It seems strange to mix concerns by combining mev-boost config with CL config. IMO the fee recipient and gas limit are fundamentally CL parameters, while the relay assignments are mev-boost's domain. My question is: does mev-boost make use of the fee-recipient/gas limit, and do the CLs that already support this format (Teku+Prysm) make use of the relay assignments? Lighthouse currently only supports a single builder, so we'd have no use for the relay assignments if we were to support this config.
  2. Should CLs support the mev-boost config even when they aren't using a builder (i.e. for a local EL)?
  3. Is the config intended to be reloaded on-demand, and if so how often? I notice that Teku don't reload it by default and will reload it at most once per epoch if --validators-proposer-config-refresh-enabled is set. This seems like it could be an issue for VCs managing thousands of keys, as there may be frequent updates which users want actioned faster than once-per-epoch, but reading/loading the file too often could add significant latency.

Given my current understanding of the design space my preference would be for a separate push-based API for the gas limit to be added alongside the push-based Fee recipient API, and a separate relay assignment config file for mev-boost. IMO this re-separates concerns addressing points (1) and (2), while also mitigating the performance-latency trade-off of (3).

michaelsproul avatar Jul 19 '22 23:07 michaelsproul

the way Prysm works right now is we have an enable-builder flag that will turn on validator registration. if a user has their prysm validator client started with enable-builder then the fee recipient API will also be updated on the mev-boost side, if it's not on then it'll just continue with the prepare beacon proposer call.

james-prysm avatar Jul 21 '22 13:07 james-prysm

@michaelsproul mev-boost only uses the relays config from this file, gasLimit and feeRecipient need to be sent as a validator registration that's signed with the validator key, so mev-boost wouldn't even be able to use that.

metachris avatar Jul 22 '22 08:07 metachris

Thanks everyone for all the input so far (and @0xpanoramix for his work on implementing this in #186). Let's continue the spec-specific conversations in https://github.com/ethereum/builder-specs/pull/41/files 🙏

metachris avatar Jul 22 '22 08:07 metachris

Succeeded by #455

metachris avatar May 13 '23 09:05 metachris