Skip to content

Conversation

faheelsattar
Copy link
Collaborator

@faheelsattar faheelsattar commented Oct 7, 2025

📝 Summary

Allows sending multiple getHeader requests within a slot and returns the freshest successful header. This helps improving bid while respecting deadlines. It maximizes chance of a higher bid since later requests can return improved headers. It achieves this via YAML config file which can be passed via --relay-config , allowing delayed first requests via TargetFirstRequestMs and multiple subsequent requests at intervals via FrequencyGetHeaderMs. This feature is only activated if EnableTimingGames is set to true in the config file for a particular relay.

This PR also allows setting relays via YAML file where timing games parameters can be set. This is also backwards compatible if someone doesnt want to set relays via YAML file and want to use the default method of setting relays via --relay flag

example config

# timeout settings for get_header requests 
timeout_get_header_ms: 900  # timeout for get_header request in milliseconds
late_in_slot_time_ms: 1000  # threshold that defines when in a slot is considered "too late"

relays:
  # relay with timing games enabled
  - url: "https://0x9000009807ed12c1f08bf4e81c6da3ba8e3fc3d953898ce0102433094e5f22f21102ec057841fcb81978ed1ea0fa8246@relay.relayer1.net"
    enable_timing_games: true
    # time in ms from slot start for the first getHeader request
    target_first_request_ms: 200
    # time in ms between subsequent getHeader requests
    frequency_getheader_ms: 100

  # relay with timing games disabled (standard behavior)
  - url: "https://0x9000009807ed12c1f08bf4e81c6da3ba8e3fc3d953898ce0102433094e5f22f21102ec057841fcb81978ed1ea0fa8246@relay.relayer2.com"
    enable_timing_games: false
    target_first_request_ms: 0
    frequency_getheader_ms: 0

Closes #830

⛱ Motivation and Context

📚 References


✅ I have run these commands

  • make lint
  • make test-race
  • go mod tidy

Comment on lines 11 to 15
# relay with timing games disabled (standard behavior)
- url: "https://0x9000009807ed12c1f08bf4e81c6da3ba8e3fc3d953898ce0102433094e5f22f21102ec057841fcb81978ed1ea0fa8246@relay.relayer2.com"
enable_timing_games: false
target_first_request_ms: 0
frequency_getheader_ms: 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would also work without the bottom three lines right? For example:

relays:
  - url: https://...
  - url: https://...
  - url: https://...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah it would, missing fields will get default values

@metachris metachris requested a review from Copilot October 9, 2025 07:24
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a timing games feature for bid optimization that allows sending multiple getHeader requests within a slot to maximize the chance of receiving higher bids. The feature is configurable via YAML configuration files and remains backwards compatible with existing relay configuration methods.

Key changes:

  • Introduces RelayConfig struct to wrap RelayEntry with timing games parameters
  • Implements timing games logic with configurable delays and request frequencies
  • Adds YAML configuration support for relay timing settings

Reviewed Changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
server/types/relay_entry.go Adds RelayConfig struct with timing games parameters
server/service.go Updates BoostService to use RelayConfig instead of RelayEntry
server/get_header.go Implements timing games logic with multiple timed requests
cli/main.go Adds relay config file loading and merging functionality
cli/flags.go Adds --relay-config flag for YAML configuration
cli/config.go Implements YAML config parsing and relay merging logic
examples/relay_config.yml Provides example configuration file
go.mod Promotes yaml.v3 from indirect to direct dependency

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@potuz
Copy link

potuz commented Oct 9, 2025

Doesn't this feature require CL client implementation changes to not timeout on the request on the CL side?

@faheelsattar
Copy link
Collaborator Author

Doesn't this feature require CL client implementation changes to not timeout on the request on the CL side?

I think the CL clients sends an optional X-Timeout-Ms header which this feature respects.
https://github.com/ethereum/builder-specs/blob/db7c5ee0363c6449997e2a1d5bc9481ed87ba223/apis/builder/header.yaml#L46-#L57

@potuz
Copy link

potuz commented Oct 9, 2025

CLs have a hardcoded timeout for the return of the header from the call to MeV-Boost, I do not see how this works without modifying the CL

@faheelsattar
Copy link
Collaborator Author

CLs have a hardcoded timeout for the return of the header from the call to MeV-Boost, I do not see how this works without modifying the CL

That is okay too since we also have TimeoutGetHeaderMs which will be configurable when setting up mev-boost.
https://github.com/faheelsattar/mev-boost/blob/feat/timing-games/server/get_header.go#L30
https://github.com/faheelsattar/mev-boost/blob/feat/timing-games/server/get_header.go#L85-#L99

@potuz
Copy link

potuz commented Oct 9, 2025

What I mean is that the CL has a hardcoded timeout that is not configurable.

@faheelsattar
Copy link
Collaborator Author

faheelsattar commented Oct 9, 2025

What I mean is that the CL has a hardcoded timeout that is not configurable.

Yeah i understand what you are saying "the CL clients have hardcoded timeouts (e.g: 1000ms) that isnt configurable".
This feature is meant to work within that constraint.
How? cuz we have a configurable value in our mev-boost config file called 'timeout_get_header_ms' (e.g: 900ms) which has to be configured less then the "hardcoded value" in the CL. The operators must configure the values when running mev-boost accordingly. Hope that makes sense.

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

Successfully merging this pull request may close these issues.

Add support for timing games features

3 participants