Skip to content

Commit e622a5e

Browse files
authored
ws get_header bids stream draft (#483)
1 parent fc9704a commit e622a5e

22 files changed

Lines changed: 1402 additions & 75 deletions

Cargo.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ subtle = "2.5"
7979
tempfile = "3.20.0"
8080
thiserror = "2.0.12"
8181
tokio = { version = "1.37.0", features = ["full"] }
82+
tokio-tungstenite = { version = "0.28.0", default-features = false, features = ["connect", "rustls-tls-webpki-roots"] }
8283
toml = "0.8.13"
8384
tonic = { version = "0.12.3", features = ["channel", "prost", "tls"] }
8485
tonic-build = "0.12.3"
@@ -93,6 +94,7 @@ typenum = "1.17.0"
9394
unicode-normalization = "0.1.24"
9495
url = { version = "2.5.0", features = ["serde"] }
9596
uuid = { version = "1.8.0", features = ["fast-rng", "serde", "v4"] }
97+
webpki-roots = "1.0"
9698

9799
[patch.crates-io]
98100
blstrs_plus = { git = "https://github.com/Commit-Boost/blstrs" }

benches/microbench/src/get_header.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use cb_common::{pbs::GetHeaderParams, signer::random_secret, types::Chain};
4444
use cb_pbs::{PbsState, get_header};
4545
use cb_tests::{
4646
mock_relay::{MockRelayState, start_mock_relay_service},
47-
utils::{generate_mock_relay, get_pbs_static_config, to_pbs_config},
47+
utils::{generate_mock_relay, get_pbs_config, to_pbs_config},
4848
};
4949
use criterion::{Criterion, black_box, criterion_group, criterion_main};
5050

@@ -103,8 +103,7 @@ fn bench_get_header(c: &mut Criterion) {
103103
let states: Vec<PbsState> = RELAY_COUNTS
104104
.iter()
105105
.map(|&n| {
106-
let config =
107-
to_pbs_config(CHAIN, get_pbs_static_config(0), relay_clients[..n].to_vec());
106+
let config = to_pbs_config(CHAIN, get_pbs_config(0), relay_clients[..n].to_vec());
108107
PbsState::new(config, PathBuf::new())
109108
})
110109
.collect();

benches/pbs/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::time::{Duration, Instant};
22

33
use alloy::primitives::B256;
44
use cb_common::{
5-
config::RelayConfig,
5+
config::{GetHeaderTransport, RelayConfig},
66
pbs::{GetHeaderResponse, RelayClient, RelayEntry},
77
types::{BlsPublicKey, BlsSecretKey, Chain},
88
utils::TestRandomSeed,
@@ -157,6 +157,7 @@ fn get_mock_validator(bench: BenchConfig) -> RelayClient {
157157
id: None,
158158
headers: None,
159159
get_params: None,
160+
get_header: GetHeaderTransport::Http,
160161
enable_timing_games: false,
161162
target_first_request_ms: None,
162163
frequency_get_header_ms: None,

config.example.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,15 @@ headers = { X-MyCustomHeader = "MyCustomValue" }
9292
# GET parameters to add to each request URL for this relay
9393
# OPTIONAL
9494
get_params = { param1 = "value1", param2 = "value2" }
95+
# How to fetch headers from this relay.
96+
# "http" -> one request per get_header, at the relay url above
97+
# "stream" -> websocket stream of bid updates, only for relays that support it. Connects to
98+
# ws(s)://<relay url>/eth/v1/builder/header_stream/{slot}/{parent_hash}/{pubkey}.
99+
# Requires a UUID api key, set it in `headers` field above under the `X-Api-Key`
100+
# name; it is sent on the websocket handshake. Can use
101+
# https://www.uuidgenerator.net/version4 to generate one.
102+
# OPTIONAL, DEFAULT: "http"
103+
get_header = "http"
95104
# Whether to enable timing games, as tuned by `target_first_request_ms` and `frequency_get_header_ms`.
96105
# NOTE: if neither `target_first_request_ms` nor `frequency_get_header_ms` is set, this flag has no effect.
97106
#

crates/common/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ tree_hash.workspace = true
5555
tree_hash_derive.workspace = true
5656
unicode-normalization.workspace = true
5757
url.workspace = true
58+
uuid.workspace = true
5859
reqwest-eventsource.workspace = true
5960

6061
[dev-dependencies]

crates/common/src/config/pbs.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ use crate::{
3838
},
3939
};
4040

41+
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize, Serialize)]
42+
#[serde(rename_all = "snake_case")]
43+
pub enum GetHeaderTransport {
44+
#[default]
45+
Http,
46+
Stream,
47+
}
48+
4149
#[derive(Debug, Clone, Deserialize, Serialize)]
4250
#[serde(deny_unknown_fields)]
4351
pub struct RelayConfig {
@@ -50,6 +58,9 @@ pub struct RelayConfig {
5058
pub headers: Option<HashMap<String, String>>,
5159
/// Optional GET parameters to add to each request
5260
pub get_params: Option<HashMap<String, String>>,
61+
/// How to fetch headers from this relay
62+
#[serde(default)]
63+
pub get_header: GetHeaderTransport,
5364
/// Whether to enable timing games
5465
#[serde(default = "default_bool::<false>")]
5566
pub enable_timing_games: bool,

crates/common/src/pbs/constants.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ pub const BUILDER_V1_API_PATH: &str = "/eth/v1/builder";
44
pub const BUILDER_V2_API_PATH: &str = "/eth/v2/builder";
55

66
pub const GET_HEADER_PATH: &str = "/header/{slot}/{parent_hash}/{pubkey}";
7+
8+
pub const GET_HEADER_STREAM_PATH: &str = "/header_stream";
79
pub const GET_STATUS_PATH: &str = "/status";
810
pub const REGISTER_VALIDATOR_PATH: &str = "/validators";
911
pub const SUBMIT_BLOCK_PATH: &str = "/blinded_blocks";
@@ -17,6 +19,7 @@ pub const HEADER_VERSION_KEY: &str = "X-CommitBoost-Version";
1719
pub const HEADER_VERSION_VALUE: &str = COMMIT_BOOST_VERSION;
1820
pub const HEADER_START_TIME_UNIX_MS: &str = "Date-Milliseconds";
1921
pub const HEADER_TIMEOUT_MS: &str = "X-Timeout-Ms";
22+
pub const HEADER_API_KEY: &str = "X-Api-Key";
2023
pub const HEADER_CONSENSUS_VERSION: &str = "Eth-Consensus-Version";
2124

2225
pub const DEFAULT_PBS_JWT_KEY: &str = "DEFAULT_PBS";

crates/common/src/pbs/error.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,24 @@ pub enum PbsError {
3838

3939
#[error("SSZ error: {0}")]
4040
SszError(#[from] SszValueError),
41+
42+
#[error("websocket error: {0}")]
43+
WebSocket(String),
44+
45+
#[error("websocket connect failed: {0}")]
46+
WebSocketConnect(String),
47+
48+
#[error("websocket timed out")]
49+
WebSocketTimeout,
4150
}
4251

4352
impl PbsError {
4453
pub fn is_timeout(&self) -> bool {
45-
matches!(self, PbsError::Reqwest(err) if err.is_timeout())
54+
match self {
55+
PbsError::Reqwest(err) => err.is_timeout(),
56+
PbsError::WebSocketTimeout => true,
57+
_ => false,
58+
}
4659
}
4760

4861
/// Extract the HTTP status code from relay-originated errors.

0 commit comments

Comments
 (0)