From 10efd2dabb71dd64ad32e10d0c42576bfe85821f Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Fri, 7 Feb 2025 09:33:41 +0000 Subject: [PATCH 01/23] Initial for fb --- Cargo.lock | 100 ++++++++++++++++++++++++++---------- Cargo.toml | 2 + src/error.rs | 2 + src/flashblocks.rs | 124 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 23 +++++++++ src/server.rs | 23 ++++++++- 6 files changed, 244 insertions(+), 30 deletions(-) create mode 100644 src/flashblocks.rs diff --git a/Cargo.lock b/Cargo.lock index 34822f4c..131afb7c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1025,9 +1025,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" dependencies = [ "serde", ] @@ -1364,6 +1364,12 @@ dependencies = [ "parking_lot_core", ] +[[package]] +name = "data-encoding" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f" + [[package]] name = "der" version = "0.7.9" @@ -3079,7 +3085,7 @@ dependencies = [ "arbitrary", "derive_more", "serde", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -3094,7 +3100,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_repr", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -3116,7 +3122,7 @@ dependencies = [ "op-alloy-consensus", "op-alloy-genesis", "serde", - "thiserror 2.0.4", + "thiserror 2.0.11", "tracing", "unsigned-varint", ] @@ -3156,7 +3162,7 @@ dependencies = [ "op-alloy-protocol", "serde", "snap", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -3903,7 +3909,7 @@ dependencies = [ "reth-execution-errors", "reth-primitives", "reth-storage-errors", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -4037,7 +4043,7 @@ dependencies = [ "serde", "strum", "sysinfo", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -4096,7 +4102,7 @@ dependencies = [ "reth-primitives-traits", "reth-trie", "serde", - "thiserror 2.0.4", + "thiserror 2.0.11", "tokio", ] @@ -4110,7 +4116,7 @@ dependencies = [ "reth-execution-errors", "reth-fs-util", "reth-storage-errors", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -4131,7 +4137,7 @@ dependencies = [ "reth-primitives", "reth-primitives-traits", "serde", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -4168,7 +4174,7 @@ dependencies = [ "once_cell", "rustc-hash 2.0.0", "serde", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -4210,7 +4216,7 @@ dependencies = [ "reth-prune-types", "reth-storage-errors", "revm-primitives", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -4238,7 +4244,7 @@ source = "git+https://github.com/paradigmxyz/reth.git?rev=e022b6fd92a33cd44e3ae5 dependencies = [ "serde", "serde_json", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -4254,7 +4260,7 @@ dependencies = [ "parking_lot", "reth-mdbx-sys", "smallvec", - "thiserror 2.0.4", + "thiserror 2.0.11", "tracing", ] @@ -4316,7 +4322,7 @@ dependencies = [ "enr", "secp256k1", "serde_with", - "thiserror 2.0.4", + "thiserror 2.0.11", "url", ] @@ -4344,7 +4350,7 @@ dependencies = [ "memmap2", "reth-fs-util", "serde", - "thiserror 2.0.4", + "thiserror 2.0.11", "tracing", "zstd", ] @@ -4475,7 +4481,7 @@ dependencies = [ "reth-transaction-pool", "revm", "sha2", - "thiserror 2.0.4", + "thiserror 2.0.11", "tracing", ] @@ -4548,7 +4554,7 @@ dependencies = [ "reth-primitives", "revm-primitives", "serde", - "thiserror 2.0.4", + "thiserror 2.0.11", "tokio", ] @@ -4681,7 +4687,7 @@ dependencies = [ "modular-bitfield", "reth-codecs", "serde", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -4804,7 +4810,7 @@ dependencies = [ "futures-util", "metrics", "reth-metrics", - "thiserror 2.0.4", + "thiserror 2.0.11", "tokio", "tracing", "tracing-futures", @@ -4857,7 +4863,7 @@ dependencies = [ "schnellru", "serde", "smallvec", - "thiserror 2.0.4", + "thiserror 2.0.11", "tokio", "tokio-stream", "tracing", @@ -4940,7 +4946,7 @@ dependencies = [ "reth-tracing", "reth-trie-common", "smallvec", - "thiserror 2.0.4", + "thiserror 2.0.11", ] [[package]] @@ -5122,10 +5128,12 @@ dependencies = [ "thiserror 1.0.65", "time", "tokio", + "tokio-tungstenite", "tower 0.4.13", "tracing", "tracing-opentelemetry", "tracing-subscriber", + "url", ] [[package]] @@ -5878,11 +5886,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.4" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f49a1853cf82743e3b7950f77e0f4d622ca36cf4317cba00c767838bac8d490" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ - "thiserror-impl 2.0.4", + "thiserror-impl 2.0.11", ] [[package]] @@ -5898,9 +5906,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.4" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8381894bb3efe0c4acac3ded651301ceee58a15d47c2e34885ed1908ad667061" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", @@ -6043,6 +6051,18 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "tokio-tungstenite" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4bf6fecd69fcdede0ec680aaf474cdab988f9de6bc73d3758f0160e3b7025a" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.12" @@ -6325,6 +6345,24 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tungstenite" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413083a99c579593656008130e29255e54dcaae495be556cc26888f211648c24" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.1.0", + "httparse", + "log", + "rand", + "sha1", + "thiserror 2.0.11", + "utf-8", +] + [[package]] name = "typenum" version = "1.17.0" @@ -6417,6 +6455,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf8parse" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index cb17b788..8efd2416 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,8 @@ metrics = "0.24.0" metrics-exporter-prometheus = "0.16.0" metrics-process = "2.3.1" metrics-util = "0.18.0" +tokio-tungstenite = "0.26.1" +url = "2.5" # dev dependencies for integration tests time = { version = "0.3.36", features = ["macros", "formatting", "parsing"] } diff --git a/src/error.rs b/src/error.rs index 734dd7c4..9a6ae90d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -10,4 +10,6 @@ pub enum Error { InitRPCServer(String), #[error("Error Initializing Prometheus Metrics: {0}")] InitMetrics(String), + #[error("Error Initializing Flashblocks Client: {0}")] + InitFlashblocks(String), } diff --git a/src/flashblocks.rs b/src/flashblocks.rs new file mode 100644 index 00000000..6cbe0be9 --- /dev/null +++ b/src/flashblocks.rs @@ -0,0 +1,124 @@ +use futures_util::StreamExt; +use op_alloy_rpc_types_engine::OpExecutionPayloadEnvelopeV3; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; +use tokio::sync::{mpsc, RwLock}; +use tokio_tungstenite::{connect_async, tungstenite::Message}; +use tracing::{debug, error, info}; +use url::Url; + +#[derive(Debug, Deserialize, Serialize)] +struct FlashbotsMessage { + method: String, + params: serde_json::Value, + #[serde(default)] + id: Option, +} + +// Simplify actor messages to just handle shutdown +#[derive(Debug)] +enum ActorMessage { + BestPayload { + response: OpExecutionPayloadEnvelopeV3, + }, +} + +pub struct FlashbotsClient { + sender: mpsc::Sender, + best_payload: Arc>>, + mailbox: mpsc::Receiver, +} + +impl FlashbotsClient { + pub fn new() -> Self { + let (sender, mailbox) = mpsc::channel(100); + + Self { + sender, + mailbox, + best_payload: Arc::new(RwLock::new(None)), + } + } + + pub async fn get_best_payload(&self) -> Option { + self.best_payload.read().await.clone() + } + + pub fn init(&mut self, ws_url: String) -> Result<(), Box> { + let url = Url::parse(&ws_url)?; + let sender = self.sender.clone(); + + // Spawn WebSocket handler + tokio::spawn(async move { + loop { + match connect_websocket(&url, sender.clone()).await { + Ok(()) => break, + Err(e) => { + error!( + message = "Flashbots WebSocket connection error, retrying in 5 seconds", + error = %e + ); + tokio::time::sleep(std::time::Duration::from_secs(5)).await; + } + } + } + }); + + // Take ownership of mailbox and state for the actor loop + let mut mailbox = std::mem::replace(&mut self.mailbox, mpsc::channel(1).1); + let best_payload = self.best_payload.clone(); + + // Spawn actor's event loop + tokio::spawn(async move { + while let Some(message) = mailbox.recv().await { + match message { + ActorMessage::BestPayload { response } => { + *best_payload.write().await = Some(response); + } + } + } + }); + + Ok(()) + } +} + +async fn connect_websocket( + url: &Url, + sender: mpsc::Sender, +) -> Result<(), Box> { + let (ws_stream, _) = connect_async(url.as_str()).await?; + let (_write, mut read) = ws_stream.split(); + + info!(message = "Flashbots WebSocket connected", url = %url); + + while let Some(msg) = read.next().await { + match msg { + Ok(Message::Text(text)) => { + match serde_json::from_str::(&text) { + Ok(payload) => { + debug!(message = "Received new payload from Flashbots"); + let _ = sender + .send(ActorMessage::BestPayload { response: payload }) + .await; + } + Err(e) => { + println!("{}", text); + error!(message = "Failed to parse payload", error = %e); + } + } + } + Ok(Message::Close(_)) => { + info!(message = "Received close frame"); + break; + } + Err(e) => { + error!(message = "WebSocket error", error = %e); + return Err(e.into()); + } + _ => {} // Ignore other message types + } + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index fa51f954..1b26878e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,10 @@ use tokio::signal::unix::{signal as unix_signal, SignalKind}; use tracing::{error, info, Level}; use tracing_subscriber::EnvFilter; +use crate::flashblocks::FlashbotsClient; + mod error; +mod flashblocks; #[cfg(all(feature = "integration", test))] mod integration; mod metrics; @@ -109,6 +112,13 @@ struct Args { /// Timeout for the l2 client calls in milliseconds #[arg(long, env, default_value = "2000")] l2_timeout: u64, + + #[arg(long, env, default_value = "false")] + flashblocks: bool, + + /// Flashblocks WebSocket URL + #[arg(long, env, default_value = "ws://localhost:1111")] + flashblocks_url: String, } type Result = core::result::Result; @@ -199,13 +209,26 @@ async fn main() -> Result<()> { let builder_client = create_client(&args.builder_url, builder_jwt_secret, args.builder_timeout)?; + let flashblocks_client = if args.flashblocks { + let mut flashblocks_client = FlashbotsClient::new(); + flashblocks_client + .init(args.flashblocks_url) + .map_err(|e| Error::InitFlashblocks(e.to_string()))?; + + Some(flashblocks_client) + } else { + None + }; + // Construct the RPC module let eth_engine_api = EthEngineApi::new( Arc::new(l2_client), Arc::new(builder_client), args.boost_sync, metrics, + flashblocks_client, ); + let mut module: RpcModule<()> = RpcModule::new(()); module .merge(eth_engine_api.into_rpc()) diff --git a/src/server.rs b/src/server.rs index 5ebe8de1..01d7762f 100644 --- a/src/server.rs +++ b/src/server.rs @@ -23,6 +23,7 @@ use reth_rpc_layer::AuthClientService; use tokio::sync::Mutex; use tracing::{debug, error, info}; +use crate::flashblocks::FlashbotsClient; use crate::metrics::ServerMetrics; const CACHE_SIZE: usize = 100; @@ -149,6 +150,7 @@ pub struct EthEngineApi { boost_sync: bool, metrics: Option>, payload_trace_context: Arc, + flashblocks_client: Option, } impl EthEngineApi { @@ -157,6 +159,7 @@ impl EthEngineApi { builder_client: Arc, boost_sync: bool, metrics: Option>, + flashblocks_client: Option, ) -> Self { Self { l2_client, @@ -164,6 +167,7 @@ impl EthEngineApi { boost_sync, metrics, payload_trace_context: Arc::new(PayloadTraceContext::new()), + flashblocks_client, } } } @@ -381,11 +385,25 @@ where .await .unwrap_or(payload_id); + // Use the flashblocks payload if available + let payload = if let Some(flashblocks_client) = &self.flashblocks_client { + flashblocks_client.get_best_payload().await + } else { + None + }; + let builder = self.builder_client.clone(); - let payload = builder.client.get_payload_v3(external_payload_id).await.map_err(|e| { + + // Fallback to the get_payload_v3 from the builder if no flashblocks payload is available + let payload = if let Some(payload) = payload { + info!(message = "using flashblocks payload"); + payload + } else { + builder.client.get_payload_v3(external_payload_id).await.map_err(|e| { error!(message = "error calling get_payload_v3 from builder", "url" = builder.url, "error" = %e, "local_payload_id" = %payload_id, "external_payload_id" = %external_payload_id); e - })?; + })? + }; let block_hash = ExecutionPayload::from(payload.clone().execution_payload).block_hash(); info!(message = "received payload from builder", "local_payload_id" = %payload_id, "external_payload_id" = %external_payload_id, "block_hash" = %block_hash); @@ -623,6 +641,7 @@ mod tests { )), boost_sync, None, + None, ); let mut module: RpcModule<()> = RpcModule::new(()); module From e7673c1f020ddba759dd77993867b9ad3545c909 Mon Sep 17 00:00:00 2001 From: Ferran Date: Wed, 12 Feb 2025 12:21:34 +0100 Subject: [PATCH 02/23] Rebase main --- src/error.rs | 15 --------------- src/main.rs | 48 +++++++++--------------------------------------- src/server.rs | 12 +++++++----- 3 files changed, 16 insertions(+), 59 deletions(-) delete mode 100644 src/error.rs diff --git a/src/error.rs b/src/error.rs deleted file mode 100644 index 9a6ae90d..00000000 --- a/src/error.rs +++ /dev/null @@ -1,15 +0,0 @@ -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum Error { - #[error("Invalid arguments: {0}")] - InvalidArgs(String), - #[error("Error Initializing RPC Client: {0}")] - InitRPCClient(String), - #[error("Error Initializing RPC Server: {0}")] - InitRPCServer(String), - #[error("Error Initializing Prometheus Metrics: {0}")] - InitMetrics(String), - #[error("Error Initializing Flashblocks Client: {0}")] - InitFlashblocks(String), -} diff --git a/src/main.rs b/src/main.rs index 4e2827c7..a6a961b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,19 +21,14 @@ use proxy::ProxyLayer; use reth_rpc_layer::JwtSecret; use server::RollupBoostServer; +use crate::flashblocks::FlashbotsClient; use tokio::net::TcpListener; use tokio::signal::unix::{signal as unix_signal, SignalKind}; use tracing::{error, info, Level}; use tracing_subscriber::EnvFilter; -<<<<<<< HEAD -use crate::flashblocks::FlashbotsClient; - -mod error; -mod flashblocks; -======= mod client; ->>>>>>> main +mod flashblocks; #[cfg(all(feature = "integration", test))] mod integration; mod metrics; @@ -88,15 +83,6 @@ struct Args { /// Log format #[arg(long, env, default_value = "text")] log_format: String, -<<<<<<< HEAD - - /// Timeout for the builder client calls in milliseconds - #[arg(long, env, default_value = "200")] - builder_timeout: u64, - - /// Timeout for the l2 client calls in milliseconds - #[arg(long, env, default_value = "2000")] - l2_timeout: u64, #[arg(long, env, default_value = "false")] flashblocks: bool, @@ -104,8 +90,6 @@ struct Args { /// Flashblocks WebSocket URL #[arg(long, env, default_value = "ws://localhost:1111")] flashblocks_url: String, -======= ->>>>>>> main } #[tokio::main] @@ -192,37 +176,23 @@ async fn main() -> eyre::Result<()> { info!("Boost sync enabled"); } -<<<<<<< HEAD let flashblocks_client = if args.flashblocks { - let mut flashblocks_client = FlashbotsClient::new(); - flashblocks_client - .init(args.flashblocks_url) - .map_err(|e| Error::InitFlashblocks(e.to_string()))?; - - Some(flashblocks_client) + let mut client = FlashbotsClient::new(); + client.init(args.flashblocks_url).unwrap(); + Some(client) } else { None }; - // Construct the RPC module - let eth_engine_api = EthEngineApi::new( - Arc::new(l2_client), - Arc::new(builder_client), - args.boost_sync, + let rollup_boost = RollupBoostServer::new( + l2_client, + builder_client, + boost_sync_enabled, metrics, flashblocks_client, ); - let mut module: RpcModule<()> = RpcModule::new(()); - module - .merge(eth_engine_api.into_rpc()) - .map_err(|e| Error::InitRPCServer(e.to_string()))?; -======= - let rollup_boost = - RollupBoostServer::new(l2_client, builder_client, boost_sync_enabled, metrics); - let module: RpcModule<()> = rollup_boost.try_into()?; ->>>>>>> main // Build and start the server info!("Starting server on :{}", args.rpc_port); diff --git a/src/server.rs b/src/server.rs index 6b9d66fa..692d72ea 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,4 +1,5 @@ use crate::client::ExecutionClient; +use crate::flashblocks::FlashbotsClient; use crate::metrics::ServerMetrics; use alloy_primitives::B256; use std::num::NonZero; @@ -10,6 +11,7 @@ use alloy_rpc_types_engine::{ PayloadStatus, }; use jsonrpsee::core::{async_trait, ClientError, RegisterMethodError, RpcResult}; +use jsonrpsee::proc_macros::rpc; use jsonrpsee::types::error::INVALID_REQUEST_CODE; use jsonrpsee::types::{ErrorCode, ErrorObject}; use jsonrpsee::RpcModule; @@ -20,11 +22,8 @@ use opentelemetry::trace::{Span, TraceContextExt, Tracer}; use opentelemetry::{Context, KeyValue}; use reth_optimism_payload_builder::{OpPayloadAttributes, OpPayloadBuilderAttributes}; use reth_payload_primitives::PayloadBuilderAttributes; -use crate::flashblocks::FlashbotsClient; -use crate::metrics::ServerMetrics; use tokio::sync::Mutex; use tracing::{error, info}; -use jsonrpsee::proc_macros::rpc; const CACHE_SIZE: usize = 100; @@ -110,6 +109,7 @@ pub struct RollupBoostServer { pub boost_sync: bool, pub metrics: Option>, pub payload_trace_context: Arc, + pub flashblocks_client: Option>, } impl RollupBoostServer { @@ -118,6 +118,7 @@ impl RollupBoostServer { builder_client: ExecutionClient, boost_sync: bool, metrics: Option>, + flashblocks_client: Option, ) -> Self { Self { l2_client, @@ -125,6 +126,7 @@ impl RollupBoostServer { boost_sync, metrics, payload_trace_context: Arc::new(PayloadTraceContext::new()), + flashblocks_client: flashblocks_client.map(Arc::new), } } } @@ -424,7 +426,7 @@ impl RollupBoostServer { info!(message = "using flashblocks payload"); payload } else { - builder.client.get_payload_v3(external_payload_id).await.map_err(|e| { + builder.auth_client.get_payload_v3(external_payload_id).await.map_err(|e| { error!(message = "error calling get_payload_v3 from builder", "url" = ?builder.auth_rpc, "error" = %e, "local_payload_id" = %payload_id, "external_payload_id" = %external_payload_id); e })? @@ -685,7 +687,7 @@ mod tests { let builder_client = ExecutionClient::new(builder_auth_rpc, jwt_secret, 2000).unwrap(); let rollup_boost_client = - RollupBoostServer::new(l2_client, builder_client, boost_sync, None); + RollupBoostServer::new(l2_client, builder_client, boost_sync, None, None); let module: RpcModule<()> = rollup_boost_client.try_into().unwrap(); From 99958e11d0f84eb91e5645a98fadb3a4840805d8 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 17 Feb 2025 16:35:01 +0000 Subject: [PATCH 03/23] Use separated crate --- src/{flashblocks.rs => flashblocks/client.rs} | 0 src/flashblocks/mod.rs | 3 +++ 2 files changed, 3 insertions(+) rename src/{flashblocks.rs => flashblocks/client.rs} (100%) create mode 100644 src/flashblocks/mod.rs diff --git a/src/flashblocks.rs b/src/flashblocks/client.rs similarity index 100% rename from src/flashblocks.rs rename to src/flashblocks/client.rs diff --git a/src/flashblocks/mod.rs b/src/flashblocks/mod.rs new file mode 100644 index 00000000..163196ac --- /dev/null +++ b/src/flashblocks/mod.rs @@ -0,0 +1,3 @@ +mod client; + +pub use client::FlashbotsClient; From 44390bacfb0e9a66dcb851f793b4d8467edc2544 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Mon, 17 Feb 2025 19:19:58 +0000 Subject: [PATCH 04/23] Some moves --- src/flashblocks/client.rs | 8 ++++++++ src/flashblocks/mod.rs | 1 + src/flashblocks/primitives.rs | 1 + 3 files changed, 10 insertions(+) create mode 100644 src/flashblocks/primitives.rs diff --git a/src/flashblocks/client.rs b/src/flashblocks/client.rs index 6cbe0be9..7b0ef612 100644 --- a/src/flashblocks/client.rs +++ b/src/flashblocks/client.rs @@ -122,3 +122,11 @@ async fn connect_websocket( Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn test_flashbots_client() {} +} diff --git a/src/flashblocks/mod.rs b/src/flashblocks/mod.rs index 163196ac..9cbe94cf 100644 --- a/src/flashblocks/mod.rs +++ b/src/flashblocks/mod.rs @@ -1,3 +1,4 @@ mod client; +mod primitives; pub use client::FlashbotsClient; diff --git a/src/flashblocks/primitives.rs b/src/flashblocks/primitives.rs new file mode 100644 index 00000000..3c686d3c --- /dev/null +++ b/src/flashblocks/primitives.rs @@ -0,0 +1 @@ +pub struct FlashbotsPayloadV1 {} From 32ab82844c78f3e8aae79ebc4eb2e6e368912d7b Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 18 Feb 2025 10:56:03 +0000 Subject: [PATCH 05/23] Add diff --- Cargo.lock | 1 + Cargo.toml | 1 + src/flashblocks/client.rs | 132 ---------------------- src/flashblocks/mod.rs | 4 +- src/flashblocks/primitives.rs | 74 ++++++++++++- src/flashblocks/service.rs | 199 ++++++++++++++++++++++++++++++++++ src/main.rs | 9 +- src/server.rs | 6 +- 8 files changed, 285 insertions(+), 141 deletions(-) delete mode 100644 src/flashblocks/client.rs create mode 100644 src/flashblocks/service.rs diff --git a/Cargo.lock b/Cargo.lock index 89a9607c..41b01a3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5234,6 +5234,7 @@ dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", "alloy-rpc-types-eth", + "alloy-serde 0.7.3", "anyhow", "assert_cmd", "clap", diff --git a/Cargo.toml b/Cargo.toml index 97c01790..659f1114 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ op-alloy-rpc-types = "0.7.3" op-alloy-rpc-jsonrpsee = { version = "0.9.6", features = ["client"] } alloy-rpc-types-engine = "0.7.3" alloy-rpc-types-eth = "0.7.3" +alloy-serde = "0.7" alloy-primitives = "0.8.10" alloy-eips = { version = "0.9.2", features = ["serde"] } tokio = { version = "1", features = ["full"] } diff --git a/src/flashblocks/client.rs b/src/flashblocks/client.rs deleted file mode 100644 index 7b0ef612..00000000 --- a/src/flashblocks/client.rs +++ /dev/null @@ -1,132 +0,0 @@ -use futures_util::StreamExt; -use op_alloy_rpc_types_engine::OpExecutionPayloadEnvelopeV3; -use serde::{Deserialize, Serialize}; -use std::sync::Arc; -use tokio::sync::{mpsc, RwLock}; -use tokio_tungstenite::{connect_async, tungstenite::Message}; -use tracing::{debug, error, info}; -use url::Url; - -#[derive(Debug, Deserialize, Serialize)] -struct FlashbotsMessage { - method: String, - params: serde_json::Value, - #[serde(default)] - id: Option, -} - -// Simplify actor messages to just handle shutdown -#[derive(Debug)] -enum ActorMessage { - BestPayload { - response: OpExecutionPayloadEnvelopeV3, - }, -} - -pub struct FlashbotsClient { - sender: mpsc::Sender, - best_payload: Arc>>, - mailbox: mpsc::Receiver, -} - -impl FlashbotsClient { - pub fn new() -> Self { - let (sender, mailbox) = mpsc::channel(100); - - Self { - sender, - mailbox, - best_payload: Arc::new(RwLock::new(None)), - } - } - - pub async fn get_best_payload(&self) -> Option { - self.best_payload.read().await.clone() - } - - pub fn init(&mut self, ws_url: String) -> Result<(), Box> { - let url = Url::parse(&ws_url)?; - let sender = self.sender.clone(); - - // Spawn WebSocket handler - tokio::spawn(async move { - loop { - match connect_websocket(&url, sender.clone()).await { - Ok(()) => break, - Err(e) => { - error!( - message = "Flashbots WebSocket connection error, retrying in 5 seconds", - error = %e - ); - tokio::time::sleep(std::time::Duration::from_secs(5)).await; - } - } - } - }); - - // Take ownership of mailbox and state for the actor loop - let mut mailbox = std::mem::replace(&mut self.mailbox, mpsc::channel(1).1); - let best_payload = self.best_payload.clone(); - - // Spawn actor's event loop - tokio::spawn(async move { - while let Some(message) = mailbox.recv().await { - match message { - ActorMessage::BestPayload { response } => { - *best_payload.write().await = Some(response); - } - } - } - }); - - Ok(()) - } -} - -async fn connect_websocket( - url: &Url, - sender: mpsc::Sender, -) -> Result<(), Box> { - let (ws_stream, _) = connect_async(url.as_str()).await?; - let (_write, mut read) = ws_stream.split(); - - info!(message = "Flashbots WebSocket connected", url = %url); - - while let Some(msg) = read.next().await { - match msg { - Ok(Message::Text(text)) => { - match serde_json::from_str::(&text) { - Ok(payload) => { - debug!(message = "Received new payload from Flashbots"); - let _ = sender - .send(ActorMessage::BestPayload { response: payload }) - .await; - } - Err(e) => { - println!("{}", text); - error!(message = "Failed to parse payload", error = %e); - } - } - } - Ok(Message::Close(_)) => { - info!(message = "Received close frame"); - break; - } - Err(e) => { - error!(message = "WebSocket error", error = %e); - return Err(e.into()); - } - _ => {} // Ignore other message types - } - } - - Ok(()) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[tokio::test] - async fn test_flashbots_client() {} -} diff --git a/src/flashblocks/mod.rs b/src/flashblocks/mod.rs index 9cbe94cf..3a379ee5 100644 --- a/src/flashblocks/mod.rs +++ b/src/flashblocks/mod.rs @@ -1,4 +1,4 @@ -mod client; mod primitives; +mod service; -pub use client::FlashbotsClient; +pub use service::FlashblocksService; diff --git a/src/flashblocks/primitives.rs b/src/flashblocks/primitives.rs index 3c686d3c..73064481 100644 --- a/src/flashblocks/primitives.rs +++ b/src/flashblocks/primitives.rs @@ -1 +1,73 @@ -pub struct FlashbotsPayloadV1 {} +use alloy_eips::eip4895::Withdrawal; +use alloy_primitives::{Address, Bloom, Bytes, B256, U256}; +use alloy_rpc_types_engine::PayloadId; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +/// Represents the modified portions of an execution payload within a flashblock. +/// This structure contains only the fields that can be updated during block construction, +/// such as state root, receipts, logs, and new transactions. Other immutable block fields +/// like parent hash and block number are excluded since they remain constant throughout +/// the block's construction. +#[derive(Debug, Default, Deserialize, Serialize)] +pub struct ExecutionPayloadFlashblockDeltaV1 { + /// The state root of the block. + pub state_root: B256, + /// The receipts root of the block. + pub receipts_root: B256, + /// The logs bloom of the block. + pub logs_bloom: Bloom, + /// The gas used of the block. + #[serde(with = "alloy_serde::quantity")] + pub gas_used: u64, + /// The block hash of the block. + pub block_hash: B256, + /// The transactions of the block. + pub transactions: Vec, + /// Array of [`Withdrawal`] enabled with V2 + pub withdrawals: Vec, +} + +/// Represents the base configuration of an execution payload that remains constant +/// throughout block construction. This includes fundamental block properties like +/// parent hash, block number, and other header fields that are determined at +/// block creation and cannot be modified. +#[derive(Debug, Default, Deserialize, Serialize)] +pub struct ExecutionPayloadBaseV1 { + /// Ecotone parent beacon block root + pub parent_beacon_block_root: B256, + /// The parent hash of the block. + pub parent_hash: B256, + /// The fee recipient of the block. + pub fee_recipient: Address, + /// The previous randao of the block. + pub prev_randao: B256, + /// The block number. + #[serde(with = "alloy_serde::quantity")] + pub block_number: u64, + /// The gas limit of the block. + #[serde(with = "alloy_serde::quantity")] + pub gas_limit: u64, + /// The timestamp of the block. + #[serde(with = "alloy_serde::quantity")] + pub timestamp: u64, + /// The extra data of the block. + pub extra_data: Bytes, + /// The base fee per gas of the block. + pub base_fee_per_gas: U256, +} + +#[derive(Debug, Default, Deserialize, Serialize)] +pub struct FlashblocksPayloadV1 { + /// The payload id of the flashblock + pub payload_id: PayloadId, + /// The index of the flashblock in the block + pub index: u64, + /// The base execution payload configuration + #[serde(skip_serializing_if = "Option::is_none")] + pub base: Option, + /// The delta/diff containing modified portions of the execution payload + pub diff: ExecutionPayloadFlashblockDeltaV1, + /// Additional metadata associated with the flashblock + pub metadata: Value, +} diff --git a/src/flashblocks/service.rs b/src/flashblocks/service.rs new file mode 100644 index 00000000..99573ecc --- /dev/null +++ b/src/flashblocks/service.rs @@ -0,0 +1,199 @@ +use super::primitives::FlashblocksPayloadV1; +use alloy_rpc_types_engine::PayloadId; +use futures::{Stream, StreamExt}; +use op_alloy_rpc_types_engine::OpExecutionPayloadEnvelopeV3; +use serde::{Deserialize, Serialize}; +use std::pin::Pin; +use std::sync::Arc; +use tokio::sync::{mpsc, RwLock}; +use tokio_tungstenite::{connect_async, tungstenite::Message}; +use tracing::{debug, error, info}; +use url::Url; + +#[derive(Debug, Deserialize, Serialize)] +struct FlashbotsMessage { + method: String, + params: serde_json::Value, + #[serde(default)] + id: Option, +} + +// Simplify actor messages to just handle shutdown +#[derive(Debug)] +enum FlashblocksEngineMessage { + FlashblocksPayloadV1(FlashblocksPayloadV1), +} + +struct InMemoryFlashblock { + payload_id: PayloadId, + payload: Option, +} + +impl InMemoryFlashblock { + pub fn new() -> Self { + Self { + payload_id: PayloadId::default(), + payload: None, + } + } + + pub fn extend(&mut self, payload: OpExecutionPayloadEnvelopeV3) { + // append the transactions from the current payload and update. Use the header + // from the new payload + } +} + +pub struct FlashblocksService { + // sender: mpsc::Sender, + best_payload: Arc>, + // mailbox: mpsc::Receiver, + // stream: FlashblocksMessageStream, +} + +pub type FlashblocksMessageStream = + Pin + Send + Sync>>; + +impl FlashblocksService { + pub fn new() -> Self { + // let (sender, mailbox) = mpsc::channel(100); + + Self { + // sender, + // mailbox, + best_payload: Arc::new(RwLock::new(InMemoryFlashblock::new())), + // stream, + } + } + + pub async fn get_best_payload(&self) -> Option { + // self.best_payload.read().await.clone() + None + } + + pub async fn on_event(&mut self, event: FlashblocksEngineMessage) { + match event { + FlashblocksEngineMessage::FlashblocksPayloadV1(payload) => { + println!("Received payload: {:?}", payload); + } + } + } + + pub async fn run(&mut self, mut stream: FlashblocksMessageStream) { + loop { + let event = stream.next().await; + match event { + Some(event) => self.on_event(event).await, + None => break, + } + } + + /* + let url = Url::parse(&ws_url)?; + let sender = self.sender.clone(); + + // Spawn WebSocket handler + tokio::spawn(async move { + loop { + match connect_websocket(&url, sender.clone()).await { + Ok(()) => break, + Err(e) => { + error!( + message = "Flashbots WebSocket connection error, retrying in 5 seconds", + error = %e + ); + tokio::time::sleep(std::time::Duration::from_secs(5)).await; + } + } + } + }); + */ + + // Take ownership of mailbox and state for the actor loop + // let mut mailbox = std::mem::replace(&mut self.mailbox, mpsc::channel(1).1); + // let best_payload = self.best_payload.clone(); + + /* + // Spawn actor's event loop + tokio::spawn(async move { + while let Some(message) = mailbox.recv().await { + match message { + FlashblocksEngineMessage::BestPayload { response } => { + *best_payload.write().await = Some(response); + } + } + } + }); + */ + } +} + +async fn connect_websocket( + url: &Url, + sender: mpsc::Sender, +) -> Result<(), Box> { + let (ws_stream, _) = connect_async(url.as_str()).await?; + let (_write, mut read) = ws_stream.split(); + + info!(message = "Flashbots WebSocket connected", url = %url); + + while let Some(msg) = read.next().await { + match msg { + Ok(Message::Text(text)) => { + match serde_json::from_str::(&text) { + Ok(payload) => { + debug!(message = "Received new payload from Flashbots"); + /*let _ = sender + .send(FlashblocksEngineMessage::BestPayload { response: payload }) + .await;*/ + } + Err(e) => { + println!("{}", text); + error!(message = "Failed to parse payload", error = %e); + } + } + } + Ok(Message::Close(_)) => { + info!(message = "Received close frame"); + break; + } + Err(e) => { + error!(message = "WebSocket error", error = %e); + return Err(e.into()); + } + _ => {} // Ignore other message types + } + } + + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use futures::{Stream, StreamExt}; + use hyper::service; + use std::pin::Pin; + use tokio::sync::mpsc; + + pub fn get_test_stream() -> ( + Pin + Send + Sync>>, + mpsc::Sender, + ) { + let (tx, rx) = mpsc::channel(100); + let stream = Box::pin(futures::stream::unfold(rx, |mut rx| async move { + rx.recv().await.map(|item| (item, rx)) + })); + (stream, tx) + } + + #[tokio::test] + async fn test_flashbots_client() { + let mut service = FlashblocksService::new(); + + let msg = FlashblocksPayloadV1::default(); + + service + .on_event(FlashblocksEngineMessage::FlashblocksPayloadV1(msg)) + .await; + } +} diff --git a/src/main.rs b/src/main.rs index 564fff51..b0b15ca7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ use proxy::ProxyLayer; use reth_rpc_layer::JwtSecret; use server::RollupBoostServer; -use crate::flashblocks::FlashbotsClient; +use crate::flashblocks::FlashblocksService; use tokio::net::TcpListener; use tokio::signal::unix::{signal as unix_signal, SignalKind}; use tracing::{error, info, Level}; @@ -220,9 +220,12 @@ async fn main() -> eyre::Result<()> { } let flashblocks_client = if args.flashblocks { - let mut client = FlashbotsClient::new(); + /* + let mut client = FlashblocksService::new(); client.init(args.flashblocks_url).unwrap(); - Some(client) + */ + // Some(client) + None } else { None }; diff --git a/src/server.rs b/src/server.rs index cd3fdb8f..1aaffd42 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,6 +1,6 @@ use crate::client::ExecutionClient; use crate::debug_api; -use crate::flashblocks::FlashbotsClient; +use crate::flashblocks::FlashblocksService; use crate::metrics::ServerMetrics; use alloy_primitives::B256; use debug_api::DebugServer; @@ -111,7 +111,7 @@ pub struct RollupBoostServer { pub boost_sync: bool, pub metrics: Option>, pub payload_trace_context: Arc, - pub flashblocks_client: Option>, + pub flashblocks_client: Option>, pub dry_run: Arc>, } @@ -121,7 +121,7 @@ impl RollupBoostServer { builder_client: ExecutionClient, boost_sync: bool, metrics: Option>, - flashblocks_client: Option, + flashblocks_client: Option, ) -> Self { Self { l2_client, From 245b75e562d8b8e8c0e80c6cef9dd360bfab4097 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 18 Feb 2025 12:09:21 +0000 Subject: [PATCH 06/23] Add partial block building --- Cargo.lock | 20 +-- src/flashblocks/inbound.rs | 61 +++++++ src/flashblocks/mod.rs | 24 +++ src/flashblocks/primitives.rs | 2 +- src/flashblocks/service.rs | 291 +++++++++++++++++----------------- src/main.rs | 9 +- src/server.rs | 8 +- 7 files changed, 250 insertions(+), 165 deletions(-) create mode 100644 src/flashblocks/inbound.rs diff --git a/Cargo.lock b/Cargo.lock index 41b01a3c..8ada4936 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,9 +344,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.14" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bfd7853b65a2b4f49629ec975fee274faf6dff15ab8894c620943398ef283c0" +checksum = "a2708e27f58d747423ae21d31b7a6625159bd8d867470ddd0256f396a68efa11" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -358,9 +358,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.8.14" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82ec42f342d9a9261699f8078e57a7a4fda8aaa73c1a212ed3987080e6a9cd13" +checksum = "c6b7984d7e085dec382d2c5ef022b533fcdb1fe6129200af30ebf5afddb6a361" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -376,9 +376,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.8.14" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2c50e6a62ee2b4f7ab3c6d0366e5770a21cad426e109c2f40335a1b3aff3df" +checksum = "33d6a9fc4ed1a3c70bdb2357bec3924551c1a59f24e5a04a74472c755b37f87d" dependencies = [ "const-hex", "dunce", @@ -391,9 +391,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9dc0fffe397aa17628160e16b89f704098bf3c9d74d5d369ebc239575936de5" +checksum = "1174cafd6c6d810711b4e00383037bdb458efc4fe3dbafafa16567e0320c54d8" dependencies = [ "alloy-primitives", "alloy-sol-macro", @@ -5944,9 +5944,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.14" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0523f59468a2696391f2a772edc089342aacd53c3caa2ac3264e598edf119b" +checksum = "9c2de690018098e367beeb793991c7d4dc7270f42c9d2ac4ccc876c1368ca430" dependencies = [ "paste", "proc-macro2", diff --git a/src/flashblocks/inbound.rs b/src/flashblocks/inbound.rs new file mode 100644 index 00000000..fbefffbe --- /dev/null +++ b/src/flashblocks/inbound.rs @@ -0,0 +1,61 @@ +use super::primitives::FlashblocksPayloadV1; +use futures::StreamExt; +use tokio::sync::mpsc; +use tokio_tungstenite::{connect_async, tungstenite::Message}; +use tracing::{error, info}; +use url::Url; + +pub struct FlashblocksReceiverService { + url: Url, + sender: mpsc::Sender, +} + +impl FlashblocksReceiverService { + pub fn new( + url: String, + sender: mpsc::Sender, + ) -> Result { + Ok(Self { + url: Url::parse(&url)?, + sender, + }) + } + + pub async fn run(self) { + loop { + match self.connect_and_handle().await { + Ok(()) => break, + Err(e) => { + error!( + message = "Flashblocks receiver connection error, retrying in 5 seconds", + error = %e + ); + tokio::time::sleep(std::time::Duration::from_secs(5)).await; + } + } + } + } + + async fn connect_and_handle(&self) -> Result<(), Box> { + let (ws_stream, _) = connect_async(self.url.as_str()).await?; + let (_, mut read) = ws_stream.split(); + + info!("Connected to Flashblocks receiver at {}", self.url); + + while let Some(msg) = read.next().await { + let msg = msg?; + match msg { + Message::Text(text) => { + if let Ok(flashblocks_msg) = serde_json::from_str::(&text) + // TODO: Version this + { + self.sender.send(flashblocks_msg).await?; + } + } + _ => continue, + } + } + + Ok(()) + } +} diff --git a/src/flashblocks/mod.rs b/src/flashblocks/mod.rs index 3a379ee5..ccd628b8 100644 --- a/src/flashblocks/mod.rs +++ b/src/flashblocks/mod.rs @@ -1,4 +1,28 @@ +mod inbound; mod primitives; mod service; +use inbound::FlashblocksReceiverService; +use tokio::sync::mpsc; pub use service::FlashblocksService; + +pub struct Flashblocks {} + +impl Flashblocks { + pub fn run(builder_url: String) -> eyre::Result { + let (tx, rx) = mpsc::channel(100); + let receiver = FlashblocksReceiverService::new(builder_url, tx).unwrap(); + + tokio::spawn(async move { + let _ = receiver.run().await; + }); + + let service = FlashblocksService::new(); + let mut service_handle = service.clone(); + tokio::spawn(async move { + service_handle.run(rx).await; + }); + + Ok(service) + } +} diff --git a/src/flashblocks/primitives.rs b/src/flashblocks/primitives.rs index 73064481..6c8085ba 100644 --- a/src/flashblocks/primitives.rs +++ b/src/flashblocks/primitives.rs @@ -1,6 +1,6 @@ -use alloy_eips::eip4895::Withdrawal; use alloy_primitives::{Address, Bloom, Bytes, B256, U256}; use alloy_rpc_types_engine::PayloadId; +use alloy_rpc_types_eth::Withdrawal; use serde::{Deserialize, Serialize}; use serde_json::Value; diff --git a/src/flashblocks/service.rs b/src/flashblocks/service.rs index 99573ecc..171ee790 100644 --- a/src/flashblocks/service.rs +++ b/src/flashblocks/service.rs @@ -1,14 +1,29 @@ -use super::primitives::FlashblocksPayloadV1; +use super::primitives::{ + ExecutionPayloadBaseV1, ExecutionPayloadFlashblockDeltaV1, FlashblocksPayloadV1, +}; +use alloy_primitives::U256; use alloy_rpc_types_engine::PayloadId; -use futures::{Stream, StreamExt}; +use alloy_rpc_types_engine::{ + BlobsBundleV1, ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, +}; use op_alloy_rpc_types_engine::OpExecutionPayloadEnvelopeV3; use serde::{Deserialize, Serialize}; -use std::pin::Pin; use std::sync::Arc; -use tokio::sync::{mpsc, RwLock}; -use tokio_tungstenite::{connect_async, tungstenite::Message}; -use tracing::{debug, error, info}; -use url::Url; +use thiserror::Error; +use tokio::sync::mpsc; +use tokio::sync::RwLock; +use tracing::error; +#[derive(Debug, Error)] +pub enum FlashblocksError { + #[error("Missing base payload for initial flashblock")] + MissingBasePayload, + #[error("Unexpected base payload for non-initial flashblock")] + UnexpectedBasePayload, + #[error("Missing delta for flashblock")] + MissingDelta, + #[error("Invalid index for flashblock")] + InvalidIndex, +} #[derive(Debug, Deserialize, Serialize)] struct FlashbotsMessage { @@ -24,176 +39,160 @@ enum FlashblocksEngineMessage { FlashblocksPayloadV1(FlashblocksPayloadV1), } -struct InMemoryFlashblock { - payload_id: PayloadId, - payload: Option, +#[derive(Debug, Default)] +struct FlashblockBuilder { + base: Option, + flashblocks: Vec, } -impl InMemoryFlashblock { +impl FlashblockBuilder { pub fn new() -> Self { Self { - payload_id: PayloadId::default(), - payload: None, + base: None, + flashblocks: Vec::new(), + } + } + + pub fn extend(&mut self, payload: FlashblocksPayloadV1) -> Result<(), FlashblocksError> { + // Check base payload rules + match (payload.index, payload.base) { + // First payload must have a base + (0, None) => return Err(FlashblocksError::MissingBasePayload), + (0, Some(base)) => self.base = Some(base), + // Subsequent payloads must have no base + (_, Some(_)) => return Err(FlashblocksError::UnexpectedBasePayload), + (_, None) => {} // Non-zero index without base is fine + } + + // Validate the index is contiguous + if payload.index != self.flashblocks.len() as u64 { + return Err(FlashblocksError::InvalidIndex); } + + // Update latest diff and accumulate transactions and withdrawals + self.flashblocks.push(payload.diff); + + Ok(()) } - pub fn extend(&mut self, payload: OpExecutionPayloadEnvelopeV3) { - // append the transactions from the current payload and update. Use the header - // from the new payload + pub fn to_envelope(self) -> Result { + let base = self.base.ok_or(FlashblocksError::MissingBasePayload)?; + + // There must be at least one delta + let diff = self + .flashblocks + .last() + .ok_or(FlashblocksError::MissingDelta)?; + + let transactions = self + .flashblocks + .iter() + .flat_map(|diff| diff.transactions.clone()) + .collect(); + + let withdrawals = self + .flashblocks + .iter() + .flat_map(|diff| diff.withdrawals.clone()) + .map(|w| w.into()) + .collect(); + + Ok(OpExecutionPayloadEnvelopeV3 { + parent_beacon_block_root: base.parent_beacon_block_root, + block_value: U256::ZERO, + blobs_bundle: BlobsBundleV1 { + commitments: Vec::new(), + proofs: Vec::new(), + blobs: Vec::new(), + }, + should_override_builder: false, + execution_payload: ExecutionPayloadV3 { + blob_gas_used: 0, + excess_blob_gas: 0, + payload_inner: ExecutionPayloadV2 { + withdrawals: withdrawals, + payload_inner: ExecutionPayloadV1 { + parent_hash: base.parent_hash, + fee_recipient: base.fee_recipient, + state_root: diff.state_root, + receipts_root: diff.receipts_root, + logs_bloom: diff.logs_bloom, + prev_randao: base.prev_randao, + block_number: base.block_number, + gas_limit: base.gas_limit, + gas_used: diff.gas_used, + timestamp: base.timestamp, + extra_data: base.extra_data, + base_fee_per_gas: base.base_fee_per_gas, + block_hash: diff.block_hash, + transactions: transactions, + }, + }, + }, + }) } } +#[derive(Clone)] pub struct FlashblocksService { - // sender: mpsc::Sender, - best_payload: Arc>, - // mailbox: mpsc::Receiver, - // stream: FlashblocksMessageStream, -} + // Current payload ID we're processing (set from external notification) + current_payload_id: Arc>, -pub type FlashblocksMessageStream = - Pin + Send + Sync>>; + // flashblocks payload being constructed + best_payload: Arc>, +} impl FlashblocksService { pub fn new() -> Self { - // let (sender, mailbox) = mpsc::channel(100); - Self { - // sender, - // mailbox, - best_payload: Arc::new(RwLock::new(InMemoryFlashblock::new())), - // stream, + current_payload_id: Arc::new(RwLock::new(PayloadId::default())), + best_payload: Arc::new(RwLock::new(FlashblockBuilder::new())), } } - pub async fn get_best_payload(&self) -> Option { - // self.best_payload.read().await.clone() - None + pub async fn get_best_payload( + &self, + ) -> Result, FlashblocksError> { + // consume the best payload and reset the builder + let payload = { + let mut builder = self.best_payload.write().await; + std::mem::take(&mut *builder).to_envelope()? + }; + *self.best_payload.write().await = FlashblockBuilder::new(); + + Ok(Some(payload)) + } + + pub async fn set_current_payload_id(&self, payload_id: PayloadId) { + *self.current_payload_id.write().await = payload_id; } - pub async fn on_event(&mut self, event: FlashblocksEngineMessage) { + async fn on_event(&mut self, event: FlashblocksEngineMessage) { match event { FlashblocksEngineMessage::FlashblocksPayloadV1(payload) => { - println!("Received payload: {:?}", payload); + // make sure the payload id matches the current payload id + if *self.current_payload_id.read().await != payload.payload_id { + error!(message = "Payload ID mismatch",); + return; + } + + if let Err(e) = self.best_payload.write().await.extend(payload) { + error!(message = "Failed to extend payload", error = %e); + } } } } - pub async fn run(&mut self, mut stream: FlashblocksMessageStream) { + pub async fn run(&mut self, mut stream: mpsc::Receiver) { loop { - let event = stream.next().await; + let event = stream.recv().await; match event { - Some(event) => self.on_event(event).await, - None => break, - } - } - - /* - let url = Url::parse(&ws_url)?; - let sender = self.sender.clone(); - - // Spawn WebSocket handler - tokio::spawn(async move { - loop { - match connect_websocket(&url, sender.clone()).await { - Ok(()) => break, - Err(e) => { - error!( - message = "Flashbots WebSocket connection error, retrying in 5 seconds", - error = %e - ); - tokio::time::sleep(std::time::Duration::from_secs(5)).await; - } - } - } - }); - */ - - // Take ownership of mailbox and state for the actor loop - // let mut mailbox = std::mem::replace(&mut self.mailbox, mpsc::channel(1).1); - // let best_payload = self.best_payload.clone(); - - /* - // Spawn actor's event loop - tokio::spawn(async move { - while let Some(message) = mailbox.recv().await { - match message { - FlashblocksEngineMessage::BestPayload { response } => { - *best_payload.write().await = Some(response); - } - } - } - }); - */ - } -} - -async fn connect_websocket( - url: &Url, - sender: mpsc::Sender, -) -> Result<(), Box> { - let (ws_stream, _) = connect_async(url.as_str()).await?; - let (_write, mut read) = ws_stream.split(); - - info!(message = "Flashbots WebSocket connected", url = %url); - - while let Some(msg) = read.next().await { - match msg { - Ok(Message::Text(text)) => { - match serde_json::from_str::(&text) { - Ok(payload) => { - debug!(message = "Received new payload from Flashbots"); - /*let _ = sender - .send(FlashblocksEngineMessage::BestPayload { response: payload }) - .await;*/ - } - Err(e) => { - println!("{}", text); - error!(message = "Failed to parse payload", error = %e); - } + Some(event) => { + self.on_event(FlashblocksEngineMessage::FlashblocksPayloadV1(event)) + .await } + None => break, } - Ok(Message::Close(_)) => { - info!(message = "Received close frame"); - break; - } - Err(e) => { - error!(message = "WebSocket error", error = %e); - return Err(e.into()); - } - _ => {} // Ignore other message types } } - - Ok(()) -} - -#[cfg(test)] -mod tests { - use super::*; - use futures::{Stream, StreamExt}; - use hyper::service; - use std::pin::Pin; - use tokio::sync::mpsc; - - pub fn get_test_stream() -> ( - Pin + Send + Sync>>, - mpsc::Sender, - ) { - let (tx, rx) = mpsc::channel(100); - let stream = Box::pin(futures::stream::unfold(rx, |mut rx| async move { - rx.recv().await.map(|item| (item, rx)) - })); - (stream, tx) - } - - #[tokio::test] - async fn test_flashbots_client() { - let mut service = FlashblocksService::new(); - - let msg = FlashblocksPayloadV1::default(); - - service - .on_event(FlashblocksEngineMessage::FlashblocksPayloadV1(msg)) - .await; - } } diff --git a/src/main.rs b/src/main.rs index b0b15ca7..8b2c0add 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ use proxy::ProxyLayer; use reth_rpc_layer::JwtSecret; use server::RollupBoostServer; -use crate::flashblocks::FlashblocksService; +use crate::flashblocks::Flashblocks; use tokio::net::TcpListener; use tokio::signal::unix::{signal as unix_signal, SignalKind}; use tracing::{error, info, Level}; @@ -220,12 +220,7 @@ async fn main() -> eyre::Result<()> { } let flashblocks_client = if args.flashblocks { - /* - let mut client = FlashblocksService::new(); - client.init(args.flashblocks_url).unwrap(); - */ - // Some(client) - None + Some(Flashblocks::run(builder_args.builder_url.to_string()).unwrap()) } else { None }; diff --git a/src/server.rs b/src/server.rs index 1aaffd42..16f35a9f 100644 --- a/src/server.rs +++ b/src/server.rs @@ -333,6 +333,12 @@ impl RollupBoostServer { parent_span, ) .await; + + if let Some(flashblocks_client) = &self.flashblocks_client { + flashblocks_client + .set_current_payload_id(local_payload_id) + .await; + } Some( self.payload_trace_context .tracer @@ -471,7 +477,7 @@ impl RollupBoostServer { // Use the flashblocks payload if available let payload = if let Some(flashblocks_client) = &self.flashblocks_client { - flashblocks_client.get_best_payload().await + flashblocks_client.get_best_payload().await.unwrap() // TODO: handle error } else { None }; From 0074fede0fa3889ccc658ca97a0f5757546844cc Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 18 Feb 2025 12:57:34 +0000 Subject: [PATCH 07/23] Add lib --- src/flashblocks/mod.rs | 2 +- src/lib.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 src/lib.rs diff --git a/src/flashblocks/mod.rs b/src/flashblocks/mod.rs index ccd628b8..effa16bd 100644 --- a/src/flashblocks/mod.rs +++ b/src/flashblocks/mod.rs @@ -1,5 +1,5 @@ mod inbound; -mod primitives; +pub mod primitives; mod service; use inbound::FlashblocksReceiverService; use tokio::sync::mpsc; diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..522b9f9a --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,5 @@ +pub mod flashblocks; + +pub use flashblocks::primitives::{ + ExecutionPayloadBaseV1, ExecutionPayloadFlashblockDeltaV1, FlashblocksPayloadV1, +}; From 397628cec6a6c518828c4f477500c94e21453396 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 18 Feb 2025 21:39:06 +0000 Subject: [PATCH 08/23] Prov update alloy deps --- Cargo.lock | 233 +++++++++++++++++++++++++++------------------------- Cargo.toml | 16 ++-- src/main.rs | 3 +- 3 files changed, 130 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e82474f..da2ebaca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -70,16 +70,47 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-consensus" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e32ef5c74bbeb1733c37f4ac7f866f8c8af208b7b4265e21af609dcac5bd5e" +dependencies = [ + "alloy-eips 0.11.1", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.11.1", + "alloy-trie", + "auto_impl", + "c-kzg", + "derive_more", + "serde", +] + [[package]] name = "alloy-consensus-any" -version = "0.7.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa60357dda9a3d0f738f18844bd6d0f4a5924cc5cf00bfad2ff1369897966123" +checksum = "0fa13b7b1e1e3fedc42f0728103bfa3b4d566d3d42b606db449504d88dbdbdcf" dependencies = [ - "alloy-consensus", - "alloy-eips 0.7.3", + "alloy-consensus 0.11.1", + "alloy-eips 0.11.1", "alloy-primitives", "alloy-rlp", + "alloy-serde 0.11.1", + "serde", +] + +[[package]] +name = "alloy-eip2124" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675264c957689f0fd75f5993a73123c2cc3b5c235a38f5b9037fe6c826bfb2c0" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "crc", + "thiserror 2.0.11", ] [[package]] @@ -130,8 +161,6 @@ dependencies = [ "alloy-serde 0.7.3", "c-kzg", "derive_more", - "ethereum_ssz", - "ethereum_ssz_derive", "once_cell", "serde", "sha2", @@ -139,17 +168,21 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.9.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52dd5869ed09e399003e0e0ec6903d981b2a92e74c5d37e6b40890bad2517526" +checksum = "5591581ca2ab0b3e7226a4047f9a1bfcf431da1d0cce3752fda609fea3c27e37" dependencies = [ + "alloy-eip2124", "alloy-eip2930", "alloy-eip7702 0.5.0", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.9.2", + "alloy-serde 0.11.1", + "auto_impl", "c-kzg", "derive_more", + "ethereum_ssz", + "ethereum_ssz_derive", "once_cell", "serde", "sha2", @@ -157,14 +190,14 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.7.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20219d1ad261da7a6331c16367214ee7ded41d001fabbbd656fbf71898b2773" +checksum = "3a00ce618ae2f78369918be0c20f620336381502c83b6ed62c2f7b2db27698b0" dependencies = [ - "alloy-consensus", - "alloy-eips 0.7.3", + "alloy-consensus 0.11.1", + "alloy-eips 0.11.1", "alloy-primitives", - "alloy-serde 0.7.3", + "alloy-serde 0.11.1", "serde", ] @@ -225,12 +258,30 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d297268357e3eae834ddd6888b15f764cbc0f4b3be9265f5f6ec239013f3d68" dependencies = [ - "alloy-consensus", + "alloy-consensus 0.7.3", "alloy-eips 0.7.3", "alloy-primitives", "alloy-rlp", "alloy-serde 0.7.3", "derive_more", + "jsonwebtoken", + "rand 0.8.5", + "serde", + "strum", +] + +[[package]] +name = "alloy-rpc-types-engine" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83dde9fcf1ccb9b815cc0c89bba26bbbbaae5150a53ae624ed0fc63cb3676c1" +dependencies = [ + "alloy-consensus 0.11.1", + "alloy-eips 0.11.1", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.11.1", + "derive_more", "ethereum_ssz", "ethereum_ssz_derive", "jsonwebtoken", @@ -241,22 +292,22 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.7.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0600b8b5e2dc0cab12cbf91b5a885c35871789fb7b3a57b434bd4fced5b7a8b" +checksum = "8b4dbee4d82f8a22dde18c28257bed759afeae7ba73da4a1479a039fd1445d04" dependencies = [ - "alloy-consensus", + "alloy-consensus 0.11.1", "alloy-consensus-any", - "alloy-eips 0.7.3", + "alloy-eips 0.11.1", "alloy-network-primitives", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.7.3", + "alloy-serde 0.11.1", "alloy-sol-types", - "derive_more", "itertools 0.13.0", "serde", "serde_json", + "thiserror 2.0.11", ] [[package]] @@ -272,9 +323,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.9.2" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae0465c71d4dced7525f408d84873aeebb71faf807d22d74c4a426430ccd9b55" +checksum = "8732058f5ca28c1d53d241e8504620b997ef670315d7c8afab856b3e3b80d945" dependencies = [ "alloy-primitives", "serde", @@ -283,9 +334,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.14" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bfd7853b65a2b4f49629ec975fee274faf6dff15ab8894c620943398ef283c0" +checksum = "a2708e27f58d747423ae21d31b7a6625159bd8d867470ddd0256f396a68efa11" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -297,9 +348,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.8.14" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82ec42f342d9a9261699f8078e57a7a4fda8aaa73c1a212ed3987080e6a9cd13" +checksum = "c6b7984d7e085dec382d2c5ef022b533fcdb1fe6129200af30ebf5afddb6a361" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -315,9 +366,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.8.14" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2c50e6a62ee2b4f7ab3c6d0366e5770a21cad426e109c2f40335a1b3aff3df" +checksum = "33d6a9fc4ed1a3c70bdb2357bec3924551c1a59f24e5a04a74472c755b37f87d" dependencies = [ "const-hex", "dunce", @@ -330,9 +381,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9dc0fffe397aa17628160e16b89f704098bf3c9d74d5d369ebc239575936de5" +checksum = "1174cafd6c6d810711b4e00383037bdb458efc4fe3dbafafa16567e0320c54d8" dependencies = [ "alloy-primitives", "alloy-sol-macro", @@ -1077,6 +1128,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.2" @@ -2692,64 +2758,25 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "op-alloy-consensus" -version = "0.7.3" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f0daa0d0936d436a21b57571b1e27c5663aa2ab62f6edae5ba5be999f9f93e" +checksum = "23f7ff02e5f3ba62c8dd5d9a630c818f50147bca7b0d78e89de59ed46b5d02e1" dependencies = [ - "alloy-consensus", - "alloy-eips 0.7.3", + "alloy-consensus 0.11.1", + "alloy-eips 0.11.1", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.7.3", + "alloy-serde 0.11.1", "derive_more", "serde", "thiserror 2.0.11", ] -[[package]] -name = "op-alloy-genesis" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb0964932faa7050b74689f017aca66ffa3e52501080278a81bb0a43836c8dd" -dependencies = [ - "alloy-consensus", - "alloy-eips 0.7.3", - "alloy-primitives", - "alloy-sol-types", - "serde", - "serde_repr", - "thiserror 2.0.11", -] - -[[package]] -name = "op-alloy-protocol" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d8c057c1a5bdf72d1f86c470a4d90f2d2ad1b273caa547c04cd6affe45b466d" -dependencies = [ - "alloc-no-stdlib", - "alloy-consensus", - "alloy-eips 0.7.3", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.7.3", - "async-trait", - "brotli", - "cfg-if 1.0.0", - "miniz_oxide", - "op-alloy-consensus", - "op-alloy-genesis", - "serde", - "thiserror 2.0.11", - "tracing", - "unsigned-varint", -] - [[package]] name = "op-alloy-rpc-jsonrpsee" -version = "0.9.6" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446c38f9e3e86acac6f2972a4953ffdd8bfef032bec633b0280a95783c0babd" +checksum = "725e79490887d768e5f22badf93d8c8d12349aca6db63a050acb3472f2535e6c" dependencies = [ "alloy-primitives", "jsonrpsee", @@ -2757,16 +2784,16 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.7.3" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73741855ffaa2041b33cb616d7db7180c1149b648c68c23bee9e15501073fb32" +checksum = "9ed9af4583c4b3ea93f54092ebfe41172974de2042672e9850500f4d1f99844e" dependencies = [ - "alloy-consensus", - "alloy-eips 0.7.3", + "alloy-consensus 0.11.1", + "alloy-eips 0.11.1", "alloy-network-primitives", "alloy-primitives", "alloy-rpc-types-eth", - "alloy-serde 0.7.3", + "alloy-serde 0.11.1", "derive_more", "op-alloy-consensus", "serde", @@ -2775,19 +2802,18 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.7.3" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebedc32e24013c8b3faea62d091bccbb90f871286fe2238c6f7e2ff29974df8e" +checksum = "20120c629465e52e5cdb0ac8df0ba45e184b456fcd55d17ea9ec1247d6968bb4" dependencies = [ - "alloy-eips 0.7.3", + "alloy-consensus 0.11.1", + "alloy-eips 0.11.1", "alloy-primitives", - "alloy-rpc-types-engine", - "alloy-serde 0.7.3", + "alloy-rpc-types-engine 0.11.1", + "alloy-serde 0.11.1", "derive_more", "ethereum_ssz", "op-alloy-consensus", - "op-alloy-genesis", - "op-alloy-protocol", "serde", "snap", "thiserror 2.0.11", @@ -3470,7 +3496,7 @@ name = "reth-rpc-layer" version = "1.1.2" source = "git+https://github.com/paradigmxyz/reth.git?rev=e022b6fd92a33cd44e3ae51ee2fc2ecc0f773222#e022b6fd92a33cd44e3ae51ee2fc2ecc0f773222" dependencies = [ - "alloy-rpc-types-engine", + "alloy-rpc-types-engine 0.7.3", "http 1.1.0", "jsonrpsee-http-client", "pin-project", @@ -3527,11 +3553,11 @@ dependencies = [ name = "rollup-boost" version = "0.1.0" dependencies = [ - "alloy-eips 0.9.2", + "alloy-eips 0.11.1", "alloy-primitives", - "alloy-rpc-types-engine", + "alloy-rpc-types-engine 0.11.1", "alloy-rpc-types-eth", - "alloy-serde 0.7.3", + "alloy-serde 0.11.1", "anyhow", "assert_cmd", "bytes", @@ -3917,17 +3943,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_repr" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.90", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -4164,9 +4179,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.14" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0523f59468a2696391f2a772edc089342aacd53c3caa2ac3264e598edf119b" +checksum = "9c2de690018098e367beeb793991c7d4dc7270f42c9d2ac4ccc876c1368ca430" dependencies = [ "paste", "proc-macro2", @@ -4740,12 +4755,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "unsigned-varint" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" - [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 4afa2933..a44024cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,14 +4,14 @@ version = "0.1.0" edition = "2021" [dependencies] -op-alloy-rpc-types-engine = "0.7.3" -op-alloy-rpc-types = "0.7.3" -op-alloy-rpc-jsonrpsee = { version = "0.9.6", features = ["client"] } -alloy-rpc-types-engine = "0.7.3" -alloy-rpc-types-eth = "0.7.3" -alloy-serde = "0.7" -alloy-primitives = { version = "0.8.10", features = ["rand"] } -alloy-eips = { version = "0.9.2", features = ["serde"] } +op-alloy-rpc-types-engine = "0.10.3" +op-alloy-rpc-types = "0.10.3" +op-alloy-rpc-jsonrpsee = { version = "0.10.3", features = ["client"] } +alloy-rpc-types-engine = "0.11.1" +alloy-rpc-types-eth = "0.11.1" +alloy-serde = "0.11.1" +alloy-primitives = { version = "0.8.15", features = ["rand"] } +alloy-eips = { version = "0.11.1", features = ["serde"] } tokio = { version = "1", features = ["full"] } tracing = "0.1.4" tracing-subscriber = { version = "0.3.11", features = ["env-filter", "json"] } diff --git a/src/main.rs b/src/main.rs index 92aff9e4..7379e2b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -345,7 +345,6 @@ mod tests { use jsonrpsee::core::client::ClientT; use crate::auth_layer::AuthClientService; - use alloy_rpc_types_engine::JwtSecret; use jsonrpsee::http_client::transport::Error as TransportError; use jsonrpsee::http_client::transport::HttpBackend; use jsonrpsee::http_client::HttpClient; @@ -356,7 +355,7 @@ mod tests { server::{ServerBuilder, ServerHandle}, }; use predicates::prelude::*; - use reth_rpc_layer::{AuthLayer, JwtAuthValidator}; + use reth_rpc_layer::{AuthLayer, JwtAuthValidator, JwtSecret}; use std::result::Result; use std::str::FromStr; From 9c2632311e3f3eaaaf94addaba5f42c23ef24c45 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 18 Feb 2025 21:49:47 +0000 Subject: [PATCH 09/23] Fix imports and make fb service public --- Cargo.lock | 140 ++++++++++------------------------------- Cargo.toml | 2 +- src/integration/mod.rs | 2 - src/lib.rs | 2 + src/proxy.rs | 4 +- 5 files changed, 37 insertions(+), 113 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index da2ebaca..fe025168 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,33 +53,16 @@ dependencies = [ "alloc-no-stdlib", ] -[[package]] -name = "alloy-consensus" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a101d4d016f47f13890a74290fdd17b05dd175191d9337bc600791fb96e4dea8" -dependencies = [ - "alloy-eips 0.7.3", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.7.3", - "alloy-trie", - "auto_impl", - "c-kzg", - "derive_more", - "serde", -] - [[package]] name = "alloy-consensus" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69e32ef5c74bbeb1733c37f4ac7f866f8c8af208b7b4265e21af609dcac5bd5e" dependencies = [ - "alloy-eips 0.11.1", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.11.1", + "alloy-serde", "alloy-trie", "auto_impl", "c-kzg", @@ -93,11 +76,11 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa13b7b1e1e3fedc42f0728103bfa3b4d566d3d42b606db449504d88dbdbdcf" dependencies = [ - "alloy-consensus 0.11.1", - "alloy-eips 0.11.1", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.11.1", + "alloy-serde", "serde", ] @@ -124,18 +107,6 @@ dependencies = [ "serde", ] -[[package]] -name = "alloy-eip7702" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c986539255fb839d1533c128e190e557e52ff652c9ef62939e233a81dd93f7e" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "derive_more", - "serde", -] - [[package]] name = "alloy-eip7702" version = "0.5.0" @@ -148,24 +119,6 @@ dependencies = [ "serde", ] -[[package]] -name = "alloy-eips" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6755b093afef5925f25079dd5a7c8d096398b804ba60cb5275397b06b31689" -dependencies = [ - "alloy-eip2930", - "alloy-eip7702 0.4.2", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.7.3", - "c-kzg", - "derive_more", - "once_cell", - "serde", - "sha2", -] - [[package]] name = "alloy-eips" version = "0.11.1" @@ -174,10 +127,10 @@ checksum = "5591581ca2ab0b3e7226a4047f9a1bfcf431da1d0cce3752fda609fea3c27e37" dependencies = [ "alloy-eip2124", "alloy-eip2930", - "alloy-eip7702 0.5.0", + "alloy-eip7702", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.11.1", + "alloy-serde", "auto_impl", "c-kzg", "derive_more", @@ -194,10 +147,10 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a00ce618ae2f78369918be0c20f620336381502c83b6ed62c2f7b2db27698b0" dependencies = [ - "alloy-consensus 0.11.1", - "alloy-eips 0.11.1", + "alloy-consensus", + "alloy-eips", "alloy-primitives", - "alloy-serde 0.11.1", + "alloy-serde", "serde", ] @@ -252,35 +205,17 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "alloy-rpc-types-engine" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d297268357e3eae834ddd6888b15f764cbc0f4b3be9265f5f6ec239013f3d68" -dependencies = [ - "alloy-consensus 0.7.3", - "alloy-eips 0.7.3", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.7.3", - "derive_more", - "jsonwebtoken", - "rand 0.8.5", - "serde", - "strum", -] - [[package]] name = "alloy-rpc-types-engine" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e83dde9fcf1ccb9b815cc0c89bba26bbbbaae5150a53ae624ed0fc63cb3676c1" dependencies = [ - "alloy-consensus 0.11.1", - "alloy-eips 0.11.1", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.11.1", + "alloy-serde", "derive_more", "ethereum_ssz", "ethereum_ssz_derive", @@ -296,13 +231,13 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b4dbee4d82f8a22dde18c28257bed759afeae7ba73da4a1479a039fd1445d04" dependencies = [ - "alloy-consensus 0.11.1", + "alloy-consensus", "alloy-consensus-any", - "alloy-eips 0.11.1", + "alloy-eips", "alloy-network-primitives", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.11.1", + "alloy-serde", "alloy-sol-types", "itertools 0.13.0", "serde", @@ -310,17 +245,6 @@ dependencies = [ "thiserror 2.0.11", ] -[[package]] -name = "alloy-serde" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afa753a97002a33b2ccb707d9f15f31c81b8c1b786c95b73cc62bb1d1fd0c3f" -dependencies = [ - "alloy-primitives", - "serde", - "serde_json", -] - [[package]] name = "alloy-serde" version = "0.11.1" @@ -2762,11 +2686,11 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23f7ff02e5f3ba62c8dd5d9a630c818f50147bca7b0d78e89de59ed46b5d02e1" dependencies = [ - "alloy-consensus 0.11.1", - "alloy-eips 0.11.1", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.11.1", + "alloy-serde", "derive_more", "serde", "thiserror 2.0.11", @@ -2788,12 +2712,12 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9af4583c4b3ea93f54092ebfe41172974de2042672e9850500f4d1f99844e" dependencies = [ - "alloy-consensus 0.11.1", - "alloy-eips 0.11.1", + "alloy-consensus", + "alloy-eips", "alloy-network-primitives", "alloy-primitives", "alloy-rpc-types-eth", - "alloy-serde 0.11.1", + "alloy-serde", "derive_more", "op-alloy-consensus", "serde", @@ -2806,11 +2730,11 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20120c629465e52e5cdb0ac8df0ba45e184b456fcd55d17ea9ec1247d6968bb4" dependencies = [ - "alloy-consensus 0.11.1", - "alloy-eips 0.11.1", + "alloy-consensus", + "alloy-eips", "alloy-primitives", - "alloy-rpc-types-engine 0.11.1", - "alloy-serde 0.11.1", + "alloy-rpc-types-engine", + "alloy-serde", "derive_more", "ethereum_ssz", "op-alloy-consensus", @@ -3493,10 +3417,10 @@ dependencies = [ [[package]] name = "reth-rpc-layer" -version = "1.1.2" -source = "git+https://github.com/paradigmxyz/reth.git?rev=e022b6fd92a33cd44e3ae51ee2fc2ecc0f773222#e022b6fd92a33cd44e3ae51ee2fc2ecc0f773222" +version = "1.2.0" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.2.0#1e965caf5fa176f244a31c0d2662ba1b590938db" dependencies = [ - "alloy-rpc-types-engine 0.7.3", + "alloy-rpc-types-engine", "http 1.1.0", "jsonrpsee-http-client", "pin-project", @@ -3553,11 +3477,11 @@ dependencies = [ name = "rollup-boost" version = "0.1.0" dependencies = [ - "alloy-eips 0.11.1", + "alloy-eips", "alloy-primitives", - "alloy-rpc-types-engine 0.11.1", + "alloy-rpc-types-engine", "alloy-rpc-types-eth", - "alloy-serde 0.11.1", + "alloy-serde", "anyhow", "assert_cmd", "bytes", diff --git a/Cargo.toml b/Cargo.toml index a44024cf..5d330f85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,7 +62,7 @@ predicates = "3.1.2" tokio-util = { version = "0.7.13" } nix = "0.15.0" bytes = "1.2" -reth-rpc-layer = { git = "https://github.com/paradigmxyz/reth.git", rev = "e022b6fd92a33cd44e3ae51ee2fc2ecc0f773222" } +reth-rpc-layer = { git = "https://github.com/paradigmxyz/reth", tag = "v1.2.0" } [features] integration = [] diff --git a/src/integration/mod.rs b/src/integration/mod.rs index d73efaf3..e2070608 100644 --- a/src/integration/mod.rs +++ b/src/integration/mod.rs @@ -701,8 +701,6 @@ impl SimpleBlockGenerator { timestamp: self.timestamp + 1000, // 1 second later prev_randao: B256::ZERO, suggested_fee_recipient: Default::default(), - target_blobs_per_block: None, - max_blobs_per_block: None, }, transactions: None, no_tx_pool: Some(empty_blocks), diff --git a/src/lib.rs b/src/lib.rs index 522b9f9a..152f0a87 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,3 +3,5 @@ pub mod flashblocks; pub use flashblocks::primitives::{ ExecutionPayloadBaseV1, ExecutionPayloadFlashblockDeltaV1, FlashblocksPayloadV1, }; + +pub use flashblocks::Flashblocks; diff --git a/src/proxy.rs b/src/proxy.rs index c190db13..c5e27af8 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -193,7 +193,7 @@ mod tests { use super::*; use alloy_primitives::{hex, Bytes, B256, U128, U64}; use alloy_rpc_types_engine::JwtSecret; - use alloy_rpc_types_eth::erc4337::ConditionalOptions; + use alloy_rpc_types_eth::erc4337::TransactionConditional; use http_body_util::BodyExt; use hyper::service::service_fn; use hyper_util::rt::TokioIo; @@ -598,7 +598,7 @@ mod tests { let expected_tx: Bytes = hex!("1234").into(); let expected_method = "eth_sendRawTransactionConditional"; - let transact_conditionals = ConditionalOptions::default(); + let transact_conditionals = TransactionConditional::default(); test_harness .proxy_client .request::( From 0b089a37b8525d328ab93962bb8121811ee3ca1f Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 18 Feb 2025 22:09:02 +0000 Subject: [PATCH 10/23] Add log --- src/flashblocks/service.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/flashblocks/service.rs b/src/flashblocks/service.rs index 171ee790..fc548d55 100644 --- a/src/flashblocks/service.rs +++ b/src/flashblocks/service.rs @@ -54,6 +54,8 @@ impl FlashblockBuilder { } pub fn extend(&mut self, payload: FlashblocksPayloadV1) -> Result<(), FlashblocksError> { + println!("-> {:?} {:?}", payload.index, payload.base.is_some()); + // Check base payload rules match (payload.index, payload.base) { // First payload must have a base From e1d60685b2901e46c3b16129769ae9427273d31d Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Wed, 19 Feb 2025 10:45:18 +0000 Subject: [PATCH 11/23] Add better print statements --- src/flashblocks/service.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/flashblocks/service.rs b/src/flashblocks/service.rs index fc548d55..7c40faf8 100644 --- a/src/flashblocks/service.rs +++ b/src/flashblocks/service.rs @@ -23,6 +23,8 @@ pub enum FlashblocksError { MissingDelta, #[error("Invalid index for flashblock")] InvalidIndex, + #[error("Missing payload")] + MissingPayload, } #[derive(Debug, Deserialize, Serialize)] @@ -54,8 +56,6 @@ impl FlashblockBuilder { } pub fn extend(&mut self, payload: FlashblocksPayloadV1) -> Result<(), FlashblocksError> { - println!("-> {:?} {:?}", payload.index, payload.base.is_some()); - // Check base payload rules match (payload.index, payload.base) { // First payload must have a base @@ -78,7 +78,7 @@ impl FlashblockBuilder { } pub fn to_envelope(self) -> Result { - let base = self.base.ok_or(FlashblocksError::MissingBasePayload)?; + let base = self.base.ok_or(FlashblocksError::MissingPayload)?; // There must be at least one delta let diff = self @@ -166,12 +166,19 @@ impl FlashblocksService { } pub async fn set_current_payload_id(&self, payload_id: PayloadId) { + tracing::debug!(message = "Setting current payload ID", payload_id = %payload_id); *self.current_payload_id.write().await = payload_id; } async fn on_event(&mut self, event: FlashblocksEngineMessage) { match event { FlashblocksEngineMessage::FlashblocksPayloadV1(payload) => { + tracing::debug!( + message = "Received flashblock payload", + payload_id = %payload.payload_id, + index = payload.index + ); + // make sure the payload id matches the current payload id if *self.current_payload_id.read().await != payload.payload_id { error!(message = "Payload ID mismatch",); From ada938c24f7f72f27dd49cbcbf3b7d51650dc560 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Wed, 19 Feb 2025 12:14:07 +0000 Subject: [PATCH 12/23] Add outbound server --- src/flashblocks/mod.rs | 23 +++++++++-- src/flashblocks/outbound.rs | 77 +++++++++++++++++++++++++++++++++++ src/flashblocks/primitives.rs | 6 +-- src/flashblocks/service.rs | 13 +++++- src/main.rs | 24 ++++++++--- src/server.rs | 8 +++- 6 files changed, 137 insertions(+), 14 deletions(-) create mode 100644 src/flashblocks/outbound.rs diff --git a/src/flashblocks/mod.rs b/src/flashblocks/mod.rs index effa16bd..1d7be3d0 100644 --- a/src/flashblocks/mod.rs +++ b/src/flashblocks/mod.rs @@ -1,7 +1,10 @@ mod inbound; +mod outbound; pub mod primitives; mod service; use inbound::FlashblocksReceiverService; +use outbound::FlashblocksOutboundService; +use std::net::SocketAddr; use tokio::sync::mpsc; pub use service::FlashblocksService; @@ -9,15 +12,29 @@ pub use service::FlashblocksService; pub struct Flashblocks {} impl Flashblocks { - pub fn run(builder_url: String) -> eyre::Result { + pub fn run(builder_url: String, outbound_addr: String) -> eyre::Result { let (tx, rx) = mpsc::channel(100); - let receiver = FlashblocksReceiverService::new(builder_url, tx).unwrap(); + let (outbound_tx, outbound_rx) = mpsc::channel(100); + + let receiver = FlashblocksReceiverService::new(builder_url, tx)?; tokio::spawn(async move { let _ = receiver.run().await; }); - let service = FlashblocksService::new(); + // Create and spawn the outbound WebSocket service + let outbound_service = FlashblocksOutboundService::new(outbound_rx); + let addr: SocketAddr = outbound_addr + .parse() + .map_err(|e| eyre::eyre!("Invalid outbound address {}: {}", outbound_addr, e))?; + + tokio::spawn(async move { + if let Err(e) = outbound_service.run(addr).await { + tracing::error!("Outbound service error: {}", e); + } + }); + + let service = FlashblocksService::new(outbound_tx); let mut service_handle = service.clone(); tokio::spawn(async move { service_handle.run(rx).await; diff --git a/src/flashblocks/outbound.rs b/src/flashblocks/outbound.rs new file mode 100644 index 00000000..24f04514 --- /dev/null +++ b/src/flashblocks/outbound.rs @@ -0,0 +1,77 @@ +use super::primitives::FlashblocksPayloadV1; +use futures::{SinkExt, StreamExt}; +use std::{net::SocketAddr, sync::Arc}; +use tokio::{ + net::TcpListener, + sync::{mpsc, Mutex}, +}; +use tokio_tungstenite::{accept_async, tungstenite::Message}; +use tracing::{debug, error, info}; + +type WebSocketSink = + futures::stream::SplitSink, Message>; + +pub struct FlashblocksOutboundService { + clients: Arc>>, + receiver: mpsc::Receiver, +} + +impl FlashblocksOutboundService { + pub fn new(receiver: mpsc::Receiver) -> Self { + Self { + clients: Arc::new(Mutex::new(Vec::new())), + receiver, + } + } + + pub async fn run(mut self, addr: SocketAddr) -> Result<(), Box> { + let listener = TcpListener::bind(&addr).await?; + info!("Outbound WebSocket server listening on: {}", addr); + + let clients = self.clients.clone(); + + // Spawn a task to handle new WebSocket connections + tokio::spawn(async move { + while let Ok((stream, addr)) = listener.accept().await { + debug!("New WebSocket connection from: {}", addr); + let clients = clients.clone(); + + tokio::spawn(async move { + match accept_async(stream).await { + Ok(ws_stream) => { + let (sink, _) = ws_stream.split(); + clients.lock().await.push(sink); + debug!("Client added: {}", addr); + } + Err(e) => error!("Error accepting WebSocket connection: {}", e), + } + }); + } + }); + + // Handle incoming messages from the channel and broadcast them + while let Some(payload) = self.receiver.recv().await { + let message = match serde_json::to_string(&payload) { + Ok(msg) => Message::Text(msg.into()), + Err(e) => { + error!("Failed to serialize payload: {}", e); + continue; + } + }; + + let mut clients = self.clients.lock().await; + clients.retain_mut(|sink| { + let send_future = sink.send(message.clone()); + match futures::executor::block_on(send_future) { + Ok(_) => true, + Err(e) => { + error!("Failed to send message to client: {}", e); + false // Remove failed client + } + } + }); + } + + Ok(()) + } +} diff --git a/src/flashblocks/primitives.rs b/src/flashblocks/primitives.rs index 6c8085ba..bce17bb4 100644 --- a/src/flashblocks/primitives.rs +++ b/src/flashblocks/primitives.rs @@ -9,7 +9,7 @@ use serde_json::Value; /// such as state root, receipts, logs, and new transactions. Other immutable block fields /// like parent hash and block number are excluded since they remain constant throughout /// the block's construction. -#[derive(Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct ExecutionPayloadFlashblockDeltaV1 { /// The state root of the block. pub state_root: B256, @@ -32,7 +32,7 @@ pub struct ExecutionPayloadFlashblockDeltaV1 { /// throughout block construction. This includes fundamental block properties like /// parent hash, block number, and other header fields that are determined at /// block creation and cannot be modified. -#[derive(Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct ExecutionPayloadBaseV1 { /// Ecotone parent beacon block root pub parent_beacon_block_root: B256, @@ -57,7 +57,7 @@ pub struct ExecutionPayloadBaseV1 { pub base_fee_per_gas: U256, } -#[derive(Debug, Default, Deserialize, Serialize)] +#[derive(Clone, Debug, Default, Deserialize, Serialize)] pub struct FlashblocksPayloadV1 { /// The payload id of the flashblock pub payload_id: PayloadId, diff --git a/src/flashblocks/service.rs b/src/flashblocks/service.rs index 7c40faf8..04d31c09 100644 --- a/src/flashblocks/service.rs +++ b/src/flashblocks/service.rs @@ -142,13 +142,17 @@ pub struct FlashblocksService { // flashblocks payload being constructed best_payload: Arc>, + + // outbound sender for valid messages + outbound: mpsc::Sender, } impl FlashblocksService { - pub fn new() -> Self { + pub fn new(outbound: mpsc::Sender) -> Self { Self { current_payload_id: Arc::new(RwLock::new(PayloadId::default())), best_payload: Arc::new(RwLock::new(FlashblockBuilder::new())), + outbound, } } @@ -185,8 +189,13 @@ impl FlashblocksService { return; } - if let Err(e) = self.best_payload.write().await.extend(payload) { + if let Err(e) = self.best_payload.write().await.extend(payload.clone()) { error!(message = "Failed to extend payload", error = %e); + } else { + // Broadcast the valid message + if let Err(e) = self.outbound.send(payload).await { + error!(message = "Failed to broadcast payload", error = %e); + } } } } diff --git a/src/main.rs b/src/main.rs index 7379e2b3..ff678e00 100644 --- a/src/main.rs +++ b/src/main.rs @@ -90,6 +90,17 @@ struct Args { #[arg(long, env, default_value = "text")] log_format: String, + /// Debug server port + #[arg(long, env, default_value = "5555")] + debug_server_port: u16, + + /// Enable Flashblocks client + #[clap(flatten)] + flashblocks: FlashblocksArgs, +} + +#[derive(Parser, Debug)] +struct FlashblocksArgs { /// Enable Flashblocks client #[arg(long, env, default_value = "false")] flashblocks: bool, @@ -98,9 +109,9 @@ struct Args { #[arg(long, env, default_value = "ws://localhost:1111")] flashblocks_url: String, - /// Debug server port - #[arg(long, env, default_value = "5555")] - debug_server_port: u16, + /// Flashblocks outbound WebSocket URL + #[arg(long, env, default_value = "127.0.0.1:1112")] + flashblocks_outbound_url: String, } #[derive(Subcommand, Debug)] @@ -220,8 +231,11 @@ async fn main() -> eyre::Result<()> { info!("Boost sync enabled"); } - let flashblocks_client = if args.flashblocks { - Some(Flashblocks::run(builder_args.builder_url.to_string()).unwrap()) + let flashblocks_client = if args.flashblocks.flashblocks { + let inbound_url = args.flashblocks.flashblocks_url; + let outbound_url = args.flashblocks.flashblocks_outbound_url; + + Some(Flashblocks::run(inbound_url, outbound_url).unwrap()) } else { None }; diff --git a/src/server.rs b/src/server.rs index b47cea09..2fdfef46 100644 --- a/src/server.rs +++ b/src/server.rs @@ -471,7 +471,13 @@ impl RollupBoostServer { // Use the flashblocks payload if available let payload = if let Some(flashblocks_client) = &self.flashblocks_client { - flashblocks_client.get_best_payload().await.unwrap() // TODO: handle error + match flashblocks_client.get_best_payload().await { + Ok(payload) => payload, + Err(e) => { + error!(message = "error getting flashblocks payload", "error" = %e); + None + } + } } else { None }; From 691a11e5e0b9c93fdacdee0f16e2277096745d12 Mon Sep 17 00:00:00 2001 From: cody-wang-cb Date: Thu, 20 Feb 2025 03:37:12 -0500 Subject: [PATCH 13/23] add wss support (#106) --- Cargo.lock | 3 +++ Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index fe025168..4a2d02a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4358,7 +4358,9 @@ checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" dependencies = [ "futures-util", "log", + "native-tls", "tokio", + "tokio-native-tls", "tungstenite", ] @@ -4610,6 +4612,7 @@ dependencies = [ "http 1.1.0", "httparse", "log", + "native-tls", "rand 0.9.0", "sha1", "thiserror 2.0.11", diff --git a/Cargo.toml b/Cargo.toml index 5d330f85..6319935a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,7 @@ metrics = "0.24.0" metrics-exporter-prometheus = "0.16.0" metrics-process = "2.3.1" metrics-util = "0.18.0" -tokio-tungstenite = "0.26.1" +tokio-tungstenite = { version = "0.26.2", features = ["native-tls"] } url = "2.5" eyre = "0.6.12" paste = "1.0.15" From ef4a70c554feac4faaa331b218e966aad228f180 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Thu, 27 Feb 2025 10:37:27 +0000 Subject: [PATCH 14/23] Add debug statement --- src/flashblocks/service.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/flashblocks/service.rs b/src/flashblocks/service.rs index 04d31c09..0e56f964 100644 --- a/src/flashblocks/service.rs +++ b/src/flashblocks/service.rs @@ -56,6 +56,8 @@ impl FlashblockBuilder { } pub fn extend(&mut self, payload: FlashblocksPayloadV1) -> Result<(), FlashblocksError> { + tracing::debug!(message = "Extending payload", payload_id = %payload.payload_id, index = payload.index, has_base=payload.base.is_some()); + // Check base payload rules match (payload.index, payload.base) { // First payload must have a base From e74a1fd01366e4ddd13515da4efda59cdc8fbce0 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Thu, 27 Feb 2025 10:58:42 +0000 Subject: [PATCH 15/23] Bump rustTls version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 4327aa54..cea09926 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ http-body-util = "0.1.2" hyper = { version = "1.4.1", features = ["full"] } hyper-util = { version = "0.1", features = ["full"] } hyper-rustls = { version = "0.27.0", features = ["ring"] } -rustls = { version = "0.23.23", features = ["ring"] } +rustls = { version = "^0.23.5", features = ["ring"] } serde_json = "1.0.96" opentelemetry = { version = "0.26.0", features = ["trace"] } opentelemetry-http = "0.26.0" From 9bfd6f33a4e35be9b6c18192e8c79b46a2e3b7b4 Mon Sep 17 00:00:00 2001 From: File Large Date: Tue, 18 Mar 2025 09:37:49 +0100 Subject: [PATCH 16/23] deps: alloy 0.12.5 (#137) * deps: alloy 0.12.5 * fix reth dep * lint --- Cargo.lock | 398 +++++++++++++++++++++++++++---------- Cargo.toml | 18 +- src/flashblocks/service.rs | 9 +- 3 files changed, 304 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0e39d06..6fece4d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,9 +55,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.11.1" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e32ef5c74bbeb1733c37f4ac7f866f8c8af208b7b4265e21af609dcac5bd5e" +checksum = "a84efb7b8ddb9223346bfad9d8094e1a100c254037a3b5913243bfa8e04be266" dependencies = [ "alloy-eips", "alloy-primitives", @@ -66,15 +66,21 @@ dependencies = [ "alloy-trie", "auto_impl", "c-kzg", - "derive_more", + "derive_more 2.0.1", + "either", + "k256", + "once_cell", + "rand 0.8.5", "serde", + "serde_with", + "thiserror 2.0.11", ] [[package]] name = "alloy-consensus-any" -version = "0.11.1" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa13b7b1e1e3fedc42f0728103bfa3b4d566d3d42b606db449504d88dbdbdcf" +checksum = "fafded0c1ff8f0275c4a484239058e1c01c0c2589f8a16e03669ef7094a06f9b" dependencies = [ "alloy-consensus", "alloy-eips", @@ -93,6 +99,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "crc", + "serde", "thiserror 2.0.11", ] @@ -109,21 +116,21 @@ dependencies = [ [[package]] name = "alloy-eip7702" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabf647eb4650c91a9d38cb6f972bb320009e7e9d61765fb688a86f1563b33e8" +checksum = "9b15b13d38b366d01e818fe8e710d4d702ef7499eacd44926a06171dd9585d0c" dependencies = [ "alloy-primitives", "alloy-rlp", - "derive_more", "serde", + "thiserror 2.0.11", ] [[package]] name = "alloy-eips" -version = "0.11.1" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5591581ca2ab0b3e7226a4047f9a1bfcf431da1d0cce3752fda609fea3c27e37" +checksum = "5f4bffedaddc627520eabdcbfe27a2d2c2f716e15295e2ed1010df3feae67040" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -133,7 +140,8 @@ dependencies = [ "alloy-serde", "auto_impl", "c-kzg", - "derive_more", + "derive_more 2.0.1", + "either", "ethereum_ssz", "ethereum_ssz_derive", "once_cell", @@ -141,11 +149,23 @@ dependencies = [ "sha2", ] +[[package]] +name = "alloy-json-abi" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec80745c33797e8baf547a8cfeb850e60d837fe9b9e67b3f579c1fcd26f527e9" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + [[package]] name = "alloy-network-primitives" -version = "0.11.1" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a00ce618ae2f78369918be0c20f620336381502c83b6ed62c2f7b2db27698b0" +checksum = "4c06932646544ea341f0fda48d2c0fe4fda75bc132379cb84019cdfb6ddcb0fb" dependencies = [ "alloy-consensus", "alloy-eips", @@ -156,19 +176,18 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.15" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6259a506ab13e1d658796c31e6e39d2e2ee89243bcc505ddc613b35732e0a430" +checksum = "eacedba97e65cdc7ab592f2b22ef5d3ab8d60b2056bc3a6e6363577e8270ec6f" dependencies = [ "alloy-rlp", "bytes", "cfg-if 1.0.0", "const-hex", - "derive_more", + "derive_more 2.0.1", "foldhash", "getrandom 0.2.15", "hashbrown 0.15.0", - "hex-literal", "indexmap 2.6.0", "itoa", "k256", @@ -177,7 +196,7 @@ dependencies = [ "proptest", "rand 0.8.5", "ruint", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "serde", "sha3", "tiny-keccak", @@ -202,21 +221,21 @@ checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] name = "alloy-rpc-types-engine" -version = "0.11.1" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83dde9fcf1ccb9b815cc0c89bba26bbbbaae5150a53ae624ed0fc63cb3676c1" +checksum = "b1a1a0710dbfbab2b33200ef45c650963d63edf6a81b2c7399ede762b3586dfd" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", - "derive_more", + "derive_more 2.0.1", "ethereum_ssz", "ethereum_ssz_derive", "jsonwebtoken", @@ -227,9 +246,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.11.1" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b4dbee4d82f8a22dde18c28257bed759afeae7ba73da4a1479a039fd1445d04" +checksum = "8e18d94b1036302720b987564560e4a5b85035a17553c53a50afa2bd8762b487" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -247,9 +266,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.11.1" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8732058f5ca28c1d53d241e8504620b997ef670315d7c8afab856b3e3b80d945" +checksum = "9824e1bf92cd7848ca6fabb01c9aca15c9c5fb0ab96da5514ef0543f021c69f6" dependencies = [ "alloy-primitives", "serde", @@ -258,23 +277,23 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2708e27f58d747423ae21d31b7a6625159bd8d867470ddd0256f396a68efa11" +checksum = "3637022e781bc73a9e300689cd91105a0e6be00391dd4e2110a71cc7e9f20a94" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b7984d7e085dec382d2c5ef022b533fcdb1fe6129200af30ebf5afddb6a361" +checksum = "3b9bd22d0bba90e40f40c625c33d39afb7d62b22192476a2ce1dcf8409dce880" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -283,35 +302,48 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", "syn-solidity", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d6a9fc4ed1a3c70bdb2357bec3924551c1a59f24e5a04a74472c755b37f87d" +checksum = "05ae4646e8123ec2fd10f9c22e361ffe4365c42811431829c2eabae528546bcc" dependencies = [ "const-hex", "dunce", "heck", + "macro-string", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", "syn-solidity", ] +[[package]] +name = "alloy-sol-type-parser" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488a747fdcefeec5c1ed5aa9e08becd775106777fdeae2a35730729fc8a95910" +dependencies = [ + "serde", + "winnow 0.7.4", +] + [[package]] name = "alloy-sol-types" -version = "0.8.15" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1174cafd6c6d810711b4e00383037bdb458efc4fe3dbafafa16567e0320c54d8" +checksum = "767957235807b021126dca1598ac3ef477007eace07961607dc5f490550909c7" dependencies = [ + "alloy-json-abi", "alloy-primitives", "alloy-sol-macro", "const-hex", + "serde", ] [[package]] @@ -323,13 +355,28 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "arrayvec", - "derive_more", + "derive_more 1.0.0", "nybbles", "serde", "smallvec", "tracing", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.17" @@ -569,7 +616,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -580,7 +627,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -597,7 +644,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -736,7 +783,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.90", + "syn 2.0.100", "which", ] @@ -755,7 +802,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -930,6 +977,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + [[package]] name = "clang-sys" version = "1.8.1" @@ -972,7 +1032,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -1153,7 +1213,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -1164,7 +1224,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -1190,6 +1250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -1209,7 +1270,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" dependencies = [ - "derive_more-impl", + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl 2.0.1", ] [[package]] @@ -1220,7 +1290,19 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", + "unicode-xid", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", "unicode-xid", ] @@ -1279,15 +1361,19 @@ dependencies = [ "digest 0.10.7", "elliptic-curve", "rfc6979", + "serdect", "signature", "spki", ] [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +dependencies = [ + "serde", +] [[package]] name = "elliptic-curve" @@ -1304,6 +1390,7 @@ dependencies = [ "pkcs8", "rand_core 0.6.4", "sec1", + "serdect", "subtle", "zeroize", ] @@ -1377,7 +1464,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -1456,9 +1543,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "foreign-types" @@ -1552,7 +1639,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -1765,12 +1852,6 @@ dependencies = [ "serde", ] -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - [[package]] name = "hmac" version = "0.12.1" @@ -1951,6 +2032,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -2001,6 +2105,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", + "serde", ] [[package]] @@ -2167,7 +2272,7 @@ dependencies = [ "parking_lot", "pin-project", "rand 0.8.5", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "serde", "serde_json", "thiserror 1.0.65", @@ -2212,7 +2317,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -2303,6 +2408,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", + "serdect", "sha2", ] @@ -2410,6 +2516,17 @@ dependencies = [ "libc", ] +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "matchers" version = "0.1.0" @@ -2450,7 +2567,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -2667,7 +2784,9 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95f06be0417d97f81fe4e5c86d7d01b392655a9cac9c19a848aa033e18937b23" dependencies = [ + "alloy-rlp", "const-hex", + "proptest", "serde", "smallvec", ] @@ -2689,25 +2808,25 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "op-alloy-consensus" -version = "0.10.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23f7ff02e5f3ba62c8dd5d9a630c818f50147bca7b0d78e89de59ed46b5d02e1" +checksum = "971eaae9cfc8b6aabb62cef8d7d49640d2e8e948e5aa3177788c4dea3d226452" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", - "derive_more", + "derive_more 1.0.0", "serde", "thiserror 2.0.11", ] [[package]] name = "op-alloy-rpc-jsonrpsee" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "725e79490887d768e5f22badf93d8c8d12349aca6db63a050acb3472f2535e6c" +checksum = "20ad24013146aecff6fb5cc5f3ed2273830b79a1b12c1bad0bdd76e2f5fe43c6" dependencies = [ "alloy-primitives", "jsonrpsee", @@ -2715,9 +2834,9 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types" -version = "0.10.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9af4583c4b3ea93f54092ebfe41172974de2042672e9850500f4d1f99844e" +checksum = "398b77b1fe4a9ca83d031d59a19fa9aa4ffcc2a896a83b7861a94292c2098412" dependencies = [ "alloy-consensus", "alloy-eips", @@ -2725,7 +2844,7 @@ dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", - "derive_more", + "derive_more 1.0.0", "op-alloy-consensus", "serde", "serde_json", @@ -2733,16 +2852,16 @@ dependencies = [ [[package]] name = "op-alloy-rpc-types-engine" -version = "0.10.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20120c629465e52e5cdb0ac8df0ba45e184b456fcd55d17ea9ec1247d6968bb4" +checksum = "b59251cd112cb10792a041ea68d9423391e0e9e3576605ee52800890fdaa483c" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "alloy-serde", - "derive_more", + "derive_more 1.0.0", "ethereum_ssz", "op-alloy-consensus", "serde", @@ -2773,7 +2892,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -2991,7 +3110,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -3080,7 +3199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -3122,7 +3241,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -3196,7 +3315,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -3424,8 +3543,8 @@ dependencies = [ [[package]] name = "reth-rpc-layer" -version = "1.2.0" -source = "git+https://github.com/paradigmxyz/reth?tag=v1.2.0#1e965caf5fa176f244a31c0d2662ba1b590938db" +version = "1.3.1" +source = "git+https://github.com/paradigmxyz/reth?tag=v1.3.1#8142c6c327e6462f2f6a009036bc5c585afc52a0" dependencies = [ "alloy-rpc-types-engine", "http 1.1.0", @@ -3589,9 +3708,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" dependencies = [ "rand 0.8.5", ] @@ -3787,6 +3906,7 @@ dependencies = [ "der", "generic-array", "pkcs8", + "serdect", "subtle", "zeroize", ] @@ -3862,7 +3982,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -3889,6 +4009,46 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.6.0", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha1" version = "0.10.6" @@ -4063,24 +4223,24 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" -version = "0.26.3" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.26.4" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -4102,9 +4262,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.90" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -4113,14 +4273,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2de690018098e367beeb793991c7d4dc7270f42c9d2ac4ccc876c1368ca430" +checksum = "d975606bae72d8aad5b07d9342465e123a2cccf53a5a735aedf81ca92a709ecb" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -4210,7 +4370,7 @@ checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -4221,7 +4381,7 @@ checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -4324,7 +4484,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -4402,7 +4562,7 @@ checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.6.0", "toml_datetime", - "winnow", + "winnow 0.6.20", ] [[package]] @@ -4532,7 +4692,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -4819,7 +4979,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", "wasm-bindgen-shared", ] @@ -4853,7 +5013,7 @@ checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4942,7 +5102,16 @@ version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core", + "windows-core 0.58.0", + "windows-targets", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ "windows-targets", ] @@ -4967,7 +5136,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -4978,9 +5147,15 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + [[package]] name = "windows-registry" version = "0.2.0" @@ -5102,6 +5277,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen-rt" version = "0.33.0" @@ -5147,7 +5331,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -5158,7 +5342,7 @@ checksum = "76331675d372f91bf8d17e13afbd5fe639200b73d01f0fc748bb059f9cca2db7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] @@ -5178,7 +5362,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.90", + "syn 2.0.100", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cea09926..0c45db95 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,14 +4,14 @@ version = "0.1.0" edition = "2021" [dependencies] -op-alloy-rpc-types-engine = "0.10.3" -op-alloy-rpc-types = "0.10.3" -op-alloy-rpc-jsonrpsee = { version = "0.10.3", features = ["client"] } -alloy-rpc-types-engine = "0.11.1" -alloy-rpc-types-eth = "0.11.1" -alloy-serde = "0.11.1" -alloy-primitives = { version = "0.8.15", features = ["rand"] } -alloy-eips = { version = "0.11.1", features = ["serde"] } +alloy-primitives = { version = "0.8.20", features = ["rand"] } +alloy-rpc-types-engine = "0.12.5" +alloy-rpc-types-eth = "0.12.5" +alloy-serde = "0.12.5" +alloy-eips = { version = "0.12.5", features = ["serde"] } +op-alloy-rpc-types-engine = "0.11.1" +op-alloy-rpc-types = "0.11.1" +op-alloy-rpc-jsonrpsee = { version = "0.11.1", features = ["client"] } tokio = { version = "1", features = ["full"] } tracing = "0.1.4" tracing-subscriber = { version = "0.3.11", features = ["env-filter", "json"] } @@ -64,7 +64,7 @@ predicates = "3.1.2" tokio-util = { version = "0.7.13" } nix = "0.15.0" bytes = "1.2" -reth-rpc-layer = { git = "https://github.com/paradigmxyz/reth", tag = "v1.2.0" } +reth-rpc-layer = { git = "https://github.com/paradigmxyz/reth", tag = "v1.3.1" } ctor = "0.3.5" [features] diff --git a/src/flashblocks/service.rs b/src/flashblocks/service.rs index 0e56f964..9f9b360a 100644 --- a/src/flashblocks/service.rs +++ b/src/flashblocks/service.rs @@ -79,7 +79,7 @@ impl FlashblockBuilder { Ok(()) } - pub fn to_envelope(self) -> Result { + pub fn into_envelope(self) -> Result { let base = self.base.ok_or(FlashblocksError::MissingPayload)?; // There must be at least one delta @@ -98,7 +98,6 @@ impl FlashblockBuilder { .flashblocks .iter() .flat_map(|diff| diff.withdrawals.clone()) - .map(|w| w.into()) .collect(); Ok(OpExecutionPayloadEnvelopeV3 { @@ -114,7 +113,7 @@ impl FlashblockBuilder { blob_gas_used: 0, excess_blob_gas: 0, payload_inner: ExecutionPayloadV2 { - withdrawals: withdrawals, + withdrawals, payload_inner: ExecutionPayloadV1 { parent_hash: base.parent_hash, fee_recipient: base.fee_recipient, @@ -129,7 +128,7 @@ impl FlashblockBuilder { extra_data: base.extra_data, base_fee_per_gas: base.base_fee_per_gas, block_hash: diff.block_hash, - transactions: transactions, + transactions, }, }, }, @@ -164,7 +163,7 @@ impl FlashblocksService { // consume the best payload and reset the builder let payload = { let mut builder = self.best_payload.write().await; - std::mem::take(&mut *builder).to_envelope()? + std::mem::take(&mut *builder).into_envelope()? }; *self.best_payload.write().await = FlashblockBuilder::new(); From 67f5974cad17b9fef257e27f0a4ff6a097e75d5d Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Tue, 18 Mar 2025 16:19:06 +0100 Subject: [PATCH 17/23] Fix lint --- src/flashblocks/outbound.rs | 2 +- src/flashblocks/primitives.rs | 2 +- src/flashblocks/service.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flashblocks/outbound.rs b/src/flashblocks/outbound.rs index 24f04514..6e6e0ed9 100644 --- a/src/flashblocks/outbound.rs +++ b/src/flashblocks/outbound.rs @@ -3,7 +3,7 @@ use futures::{SinkExt, StreamExt}; use std::{net::SocketAddr, sync::Arc}; use tokio::{ net::TcpListener, - sync::{mpsc, Mutex}, + sync::{Mutex, mpsc}, }; use tokio_tungstenite::{accept_async, tungstenite::Message}; use tracing::{debug, error, info}; diff --git a/src/flashblocks/primitives.rs b/src/flashblocks/primitives.rs index bce17bb4..baf53ead 100644 --- a/src/flashblocks/primitives.rs +++ b/src/flashblocks/primitives.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{Address, Bloom, Bytes, B256, U256}; +use alloy_primitives::{Address, B256, Bloom, Bytes, U256}; use alloy_rpc_types_engine::PayloadId; use alloy_rpc_types_eth::Withdrawal; use serde::{Deserialize, Serialize}; diff --git a/src/flashblocks/service.rs b/src/flashblocks/service.rs index 9f9b360a..90d0e15f 100644 --- a/src/flashblocks/service.rs +++ b/src/flashblocks/service.rs @@ -10,8 +10,8 @@ use op_alloy_rpc_types_engine::OpExecutionPayloadEnvelopeV3; use serde::{Deserialize, Serialize}; use std::sync::Arc; use thiserror::Error; -use tokio::sync::mpsc; use tokio::sync::RwLock; +use tokio::sync::mpsc; use tracing::error; #[derive(Debug, Error)] pub enum FlashblocksError { From e20dbc5c3d7b5223fc2a3a6cfe4c99ed9692caf7 Mon Sep 17 00:00:00 2001 From: Ferran Borreguero Date: Fri, 4 Apr 2025 09:08:28 +0100 Subject: [PATCH 18/23] Fix lint --- Cargo.lock | 88 +----------------------------------------------------- Cargo.toml | 1 - 2 files changed, 1 insertion(+), 88 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9841829..94e63536 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -678,7 +678,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9f7720b74ed28ca77f90769a71fd8c637a0137f6fae4ae947e1050229cff57f" dependencies = [ - "bindgen 0.69.5", + "bindgen", "cc", "cmake", "dunce", @@ -788,24 +788,6 @@ dependencies = [ "which", ] -[[package]] -name = "bindgen" -version = "0.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" -dependencies = [ - "bitflags 2.9.0", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.100", -] - [[package]] name = "bit-set" version = "0.8.0" @@ -2542,17 +2524,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" -[[package]] -name = "libproc" -version = "0.14.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78a09b56be5adbcad5aa1197371688dc6bb249a26da3bca2011ee2fb987ebfb" -dependencies = [ - "bindgen 0.70.1", - "errno", - "libc", -] - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -2600,15 +2571,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "mach2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" -dependencies = [ - "libc", -] - [[package]] name = "macro-string" version = "0.1.4" @@ -2672,22 +2634,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "metrics-process" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a82c8add4382f29a122fa64fff1891453ed0f6b2867d971e7d60cb8dfa322ff" -dependencies = [ - "libc", - "libproc", - "mach2", - "metrics", - "once_cell", - "procfs", - "rlimit", - "windows", -] - [[package]] name = "metrics-util" version = "0.19.0" @@ -3331,28 +3277,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "procfs" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" -dependencies = [ - "bitflags 2.9.0", - "hex", - "procfs-core", - "rustix 0.38.44", -] - -[[package]] -name = "procfs-core" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" -dependencies = [ - "bitflags 2.9.0", - "hex", -] - [[package]] name = "proptest" version = "1.6.0" @@ -3664,15 +3588,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rlimit" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" -dependencies = [ - "libc", -] - [[package]] name = "rlp" version = "0.5.2" @@ -3709,7 +3624,6 @@ dependencies = [ "lazy_static", "metrics", "metrics-exporter-prometheus", - "metrics-process", "metrics-util", "moka", "nix", diff --git a/Cargo.toml b/Cargo.toml index fb885756..a2a5fce7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,6 @@ tracing-opentelemetry = "0.29.0" futures = "0.3.31" metrics = "0.24.0" metrics-exporter-prometheus = "0.16.0" -metrics-process = "2.3.1" tokio-tungstenite = { version = "0.26.2", features = ["native-tls"] } url = "2.5" metrics-util = "0.19.0" From dac67b08761ef2db7a923b3ea0df7129574bda04 Mon Sep 17 00:00:00 2001 From: Cody Wang Date: Wed, 16 Apr 2025 17:30:27 -0400 Subject: [PATCH 19/23] reth 1.3.11 --- Cargo.lock | 231 +++++++++++++++-------------------------------------- Cargo.toml | 17 ++-- 2 files changed, 72 insertions(+), 176 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9841829..42b5f7d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,9 +55,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27d301f5bcfd37e3aac727c360d8b50c33ddff9169ce0370198dedda36a9927d" +checksum = "c2179ba839ac532f50279f5da2a6c5047f791f03f6f808b4dfab11327b97902f" dependencies = [ "alloy-eips", "alloy-primitives", @@ -66,7 +66,7 @@ dependencies = [ "alloy-trie", "auto_impl", "c-kzg", - "derive_more 2.0.1", + "derive_more", "either", "k256", "once_cell", @@ -78,9 +78,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f4f97a85a45965e0e4f9f5b94bbafaa3e4ee6868bdbcf2e4a9acb4b358038fe" +checksum = "aec6f67bdc62aa277e0ec13c1b1fb396c8a62b65c8e9bd8c1d3583cc6d1a8dd3" dependencies = [ "alloy-consensus", "alloy-eips", @@ -92,9 +92,9 @@ dependencies = [ [[package]] name = "alloy-eip2124" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "675264c957689f0fd75f5993a73123c2cc3b5c235a38f5b9037fe6c826bfb2c0" +checksum = "741bdd7499908b3aa0b159bba11e71c8cddd009a2c2eb7a06e825f1ec87900a5" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -105,9 +105,9 @@ dependencies = [ [[package]] name = "alloy-eip2930" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" +checksum = "dbe3e16484669964c26ac48390245d84c410b1a5f968976076c17184725ef235" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -116,9 +116,9 @@ dependencies = [ [[package]] name = "alloy-eip7702" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b15b13d38b366d01e818fe8e710d4d702ef7499eacd44926a06171dd9585d0c" +checksum = "804cefe429015b4244966c006d25bda5545fa9db5990e9c9079faf255052f50a" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -128,9 +128,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b11c382ca8075128d1ae6822b60921cf484c911d9a5831797a01218f98125f" +checksum = "609515c1955b33af3d78d26357540f68c5551a90ef58fd53def04f2aa074ec43" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -140,7 +140,7 @@ dependencies = [ "alloy-serde", "auto_impl", "c-kzg", - "derive_more 2.0.1", + "derive_more", "either", "ethereum_ssz", "ethereum_ssz_derive", @@ -150,9 +150,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.8.25" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6beff64ad0aa6ad1019a3db26fef565aefeb011736150ab73ed3366c3cfd1b" +checksum = "5189fa9a8797e92396bc4b4454c5f2073a4945f7c2b366af9af60f9536558f7a" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -162,9 +162,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f736e1d1eb1b770dbd32919bdf46d4dcd4617f2eed07947dfb32649962baba" +checksum = "498f2ee2eef38a6db0fc810c7bf7daebdf5f2fa8d04adb8bd53e54e91ddbdea3" dependencies = [ "alloy-consensus", "alloy-eips", @@ -175,17 +175,17 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.25" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c77490fe91a0ce933a1f219029521f20fc28c2c0ca95d53fa4da9c00b8d9d4e" +checksum = "70b98b99c1dcfbe74d7f0b31433ff215e7d1555e367d90e62db904f3c9d4ff53" dependencies = [ "alloy-rlp", "bytes", "cfg-if 1.0.0", "const-hex", - "derive_more 2.0.1", + "derive_more", "foldhash", - "getrandom 0.2.15", + "getrandom 0.3.2", "hashbrown 0.15.2", "indexmap 2.8.0", "itoa", @@ -193,7 +193,7 @@ dependencies = [ "keccak-asm", "paste", "proptest", - "rand 0.8.5", + "rand 0.9.0", "ruint", "rustc-hash 2.1.1", "serde", @@ -225,16 +225,16 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "689521777149dabe210ef122605fb00050e038f2e85b8c9897534739f1a904f8" +checksum = "4235d79af20fe5583ca26096258fe9307571a345745c433cfd8c91b41aa2611e" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", - "derive_more 2.0.1", + "derive_more", "ethereum_ssz", "ethereum_ssz_derive", "jsonwebtoken", @@ -245,9 +245,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8b6d55bdaa0c4a08650d4b32f174494cbade56adf6f2fcfa2a4f3490cb5511" +checksum = "f2a9f64e0f69cfb6029e2a044519a1bdd44ce9fc334d5315a7b9837f7a6748e5" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -265,9 +265,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1824791912f468a481dedc1db50feef3e85a078f6d743a62db2ee9c2ca674882" +checksum = "d4dba6ff08916bc0a9cbba121ce21f67c0b554c39cf174bc7b9df6c651bd3c3b" dependencies = [ "alloy-primitives", "serde", @@ -276,9 +276,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.25" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10ae8e9a91d328ae954c22542415303919aabe976fe7a92eb06db1b68fd59f2" +checksum = "60fcfa26956bcb22f66ab13407115197f26ef23abca5b48d39a1946897382d74" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -290,9 +290,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.8.25" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83ad5da86c127751bc607c174d6c9fe9b85ef0889a9ca0c641735d77d4f98f26" +checksum = "72a9b402f0013f1ff8c24066eeafc2207a8e52810a2b18b77776ce7fead5af41" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -308,9 +308,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.8.25" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3d30f0d3f9ba3b7686f3ff1de9ee312647aac705604417a2f40c604f409a9e" +checksum = "d02d61741337bb6b3f4899c2e3173fe17ffa2810e143d3b28acd953197c8dd79" dependencies = [ "const-hex", "dunce", @@ -324,9 +324,9 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "0.8.25" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d162f8524adfdfb0e4bd0505c734c985f3e2474eb022af32eef0d52a4f3935c" +checksum = "d2b5f5f9f561c29f78ea521ebe2e5ac1633f1b1442dae582f68ecd57c6350042" dependencies = [ "serde", "winnow", @@ -334,9 +334,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.25" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d43d5e60466a440230c07761aa67671d4719d46f43be8ea6e7ed334d8db4a9ab" +checksum = "c02635bce18205ff8149fb752c753b0a91ea3f3c8ee04c58846448be4811a640" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -347,14 +347,14 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.7.9" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a94854e420f07e962f7807485856cde359ab99ab6413883e15235ad996e8b" +checksum = "983d99aa81f586cef9dae38443245e585840fcf0fc58b09aee0b1f27aed1d500" dependencies = [ "alloy-primitives", "alloy-rlp", "arrayvec", - "derive_more 1.0.0", + "derive_more", "nybbles", "serde", "smallvec", @@ -678,7 +678,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9f7720b74ed28ca77f90769a71fd8c637a0137f6fae4ae947e1050229cff57f" dependencies = [ - "bindgen 0.69.5", + "bindgen", "cc", "cmake", "dunce", @@ -788,24 +788,6 @@ dependencies = [ "which", ] -[[package]] -name = "bindgen" -version = "0.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" -dependencies = [ - "bitflags 2.9.0", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.100", -] - [[package]] name = "bit-set" version = "0.8.0" @@ -1317,33 +1299,13 @@ dependencies = [ "syn 2.0.100", ] -[[package]] -name = "derive_more" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" -dependencies = [ - "derive_more-impl 1.0.0", -] - [[package]] name = "derive_more" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" dependencies = [ - "derive_more-impl 2.0.1", -] - -[[package]] -name = "derive_more-impl" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "derive_more-impl", ] [[package]] @@ -1497,9 +1459,9 @@ dependencies = [ [[package]] name = "ethereum_serde_utils" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70cbccfccf81d67bff0ab36e591fa536c8a935b078a7b0e58c1d00d418332fc9" +checksum = "3dc1355dbb41fbbd34ec28d4fb2a57d9a70c67ac3c19f6a5ca4d4a176b9e997a" dependencies = [ "alloy-primitives", "hex", @@ -1510,9 +1472,9 @@ dependencies = [ [[package]] name = "ethereum_ssz" -version = "0.8.3" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86da3096d1304f5f28476ce383005385459afeaf0eea08592b65ddbc9b258d16" +checksum = "9ca8ba45b63c389c6e115b095ca16381534fdcc03cf58176a3f8554db2dbe19b" dependencies = [ "alloy-primitives", "ethereum_serde_utils", @@ -1525,9 +1487,9 @@ dependencies = [ [[package]] name = "ethereum_ssz_derive" -version = "0.8.3" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d832a5c38eba0e7ad92592f7a22d693954637fbb332b4f669590d66a5c3183e5" +checksum = "0dd55d08012b4e0dfcc92b8d6081234df65f2986ad34cc76eeed69c5e2ce7506" dependencies = [ "darling", "proc-macro2", @@ -2542,17 +2504,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" -[[package]] -name = "libproc" -version = "0.14.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78a09b56be5adbcad5aa1197371688dc6bb249a26da3bca2011ee2fb987ebfb" -dependencies = [ - "bindgen 0.70.1", - "errno", - "libc", -] - [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -2600,15 +2551,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "mach2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" -dependencies = [ - "libc", -] - [[package]] name = "macro-string" version = "0.1.4" @@ -2672,22 +2614,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "metrics-process" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a82c8add4382f29a122fa64fff1891453ed0f6b2867d971e7d60cb8dfa322ff" -dependencies = [ - "libc", - "libproc", - "mach2", - "metrics", - "once_cell", - "procfs", - "rlimit", - "windows", -] - [[package]] name = "metrics-util" version = "0.19.0" @@ -2909,32 +2835,33 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "op-alloy-consensus" -version = "0.12.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91764ebe0eddf6e3cfff41650332ff4e01defe372386027703f2e7e334734a05" +checksum = "f6f400404e37862bb974fbc3ad2d8ca2a2df286b718e762446496d04267ee912" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", - "derive_more 2.0.1", + "derive_more", "serde", "thiserror 2.0.12", ] [[package]] name = "op-alloy-rpc-types-engine" -version = "0.12.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc26f8288839926d0137d39d70628bb5ac00fca449bab24c54cebd66c71b9cf4" +checksum = "e614936d3f113b8e3dd2724382bd8db6700bd48fcd1f4d62bef537f3be8f710e" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-primitives", + "alloy-rlp", "alloy-rpc-types-engine", "alloy-serde", - "derive_more 2.0.1", + "derive_more", "ethereum_ssz", "op-alloy-consensus", "serde", @@ -3331,28 +3258,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "procfs" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" -dependencies = [ - "bitflags 2.9.0", - "hex", - "procfs-core", - "rustix 0.38.44", -] - -[[package]] -name = "procfs-core" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" -dependencies = [ - "bitflags 2.9.0", - "hex", -] - [[package]] name = "proptest" version = "1.6.0" @@ -3468,6 +3373,7 @@ checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", + "serde", "zerocopy 0.8.24", ] @@ -3507,6 +3413,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom 0.3.2", + "serde", ] [[package]] @@ -3628,8 +3535,8 @@ dependencies = [ [[package]] name = "reth-rpc-layer" -version = "1.3.7" -source = "git+https://github.com/paradigmxyz/reth.git?rev=v1.3.7#ed7da87da4de340a437bf46f39a7e1397ac82065" +version = "1.3.11" +source = "git+https://github.com/paradigmxyz/reth.git?rev=v1.3.11#e0e85aa10b98fa92d32c3e820c7ed2cee0b02931" dependencies = [ "alloy-rpc-types-engine", "http", @@ -3664,15 +3571,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rlimit" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7043b63bd0cd1aaa628e476b80e6d4023a3b50eb32789f2728908107bd0c793a" -dependencies = [ - "libc", -] - [[package]] name = "rlp" version = "0.5.2" @@ -3709,7 +3607,6 @@ dependencies = [ "lazy_static", "metrics", "metrics-exporter-prometheus", - "metrics-process", "metrics-util", "moka", "nix", @@ -4358,9 +4255,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.25" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4560533fbd6914b94a8fb5cc803ed6801c3455668db3b810702c57612bac9412" +checksum = "34c9c96de1f835488c1501092847b522be88c9ac6fb0d4c0fbea92992324c8f4" dependencies = [ "paste", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index fb885756..90ecd328 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,12 +4,12 @@ version = "0.1.0" edition = "2024" [dependencies] -op-alloy-rpc-types-engine = "0.12.0" -alloy-rpc-types-engine = "0.13.0" -alloy-rpc-types-eth = "0.13.0" -alloy-serde = "0.13.0" -alloy-eips = { version = "0.13.0", features = ["serde"], optional = true } -alloy-primitives = { version = "0.8.10", features = ["rand"] } +op-alloy-rpc-types-engine = "0.14.1" +alloy-rpc-types-engine = "0.14.0" +alloy-rpc-types-eth = "0.14.0" +alloy-serde = "0.14.0" +alloy-eips = { version = "0.14.0", features = ["serde"], optional = true } +alloy-primitives = { version = "1.0.0", features = ["rand"] } tokio = { version = "1", features = ["full"] } tracing = "0.1.4" tracing-subscriber = { version = "0.3.11", features = ["env-filter", "json"] } @@ -41,7 +41,6 @@ tracing-opentelemetry = "0.29.0" futures = "0.3.31" metrics = "0.24.0" metrics-exporter-prometheus = "0.16.0" -metrics-process = "2.3.1" tokio-tungstenite = { version = "0.26.2", features = ["native-tls"] } url = "2.5" metrics-util = "0.19.0" @@ -54,14 +53,14 @@ time = { version = "0.3.36", features = ["macros", "formatting", "parsing"], opt lazy_static = {version = "1.5.0", optional = true } [dev-dependencies] -op-alloy-consensus = "0.12.0" +op-alloy-consensus = "0.14.1" anyhow = "1.0" assert_cmd = "2.0.10" predicates = "3.1.2" tokio-util = { version = "0.7.13" } nix = "0.15.0" bytes = "1.2" -reth-rpc-layer = { git = "https://github.com/paradigmxyz/reth.git", rev = "v1.3.7" } +reth-rpc-layer = { git = "https://github.com/paradigmxyz/reth.git", rev = "v1.3.11" } ctor = "0.4.1" [features] From e224906e46c7dfa977f67d6f2517db0c19df587c Mon Sep 17 00:00:00 2001 From: Cody Wang Date: Wed, 16 Apr 2025 16:44:59 -0400 Subject: [PATCH 20/23] reth 1.3.9 and metrics --- src/client/rpc.rs | 6 ++++- src/proxy.rs | 4 +-- src/server.rs | 68 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/src/client/rpc.rs b/src/client/rpc.rs index bdf863e7..386de94a 100644 --- a/src/client/rpc.rs +++ b/src/client/rpc.rs @@ -12,6 +12,7 @@ use http::Uri; use jsonrpsee::http_client::transport::HttpBackend; use jsonrpsee::http_client::{HttpClient, HttpClientBuilder}; use jsonrpsee::types::ErrorObjectOwned; +use metrics::counter; use op_alloy_rpc_types_engine::{ OpExecutionPayloadEnvelopeV3, OpExecutionPayloadEnvelopeV4, OpExecutionPayloadV4, OpPayloadAttributes, @@ -153,6 +154,7 @@ impl RpcClient { } if res.is_invalid() { + counter!(format!("rpc_fork_choice_updated_v3_invalid_payload_{}", self.payload_source)).increment(1); return Err(RpcClientError::InvalidPayload( res.payload_status.status.to_string(), )) @@ -213,6 +215,7 @@ impl RpcClient { .set_code()?; if res.is_invalid() { + counter!(format!("rpc_new_payload_v3_invalid_payload_{}", self.payload_source)).increment(1); return Err(RpcClientError::InvalidPayload(res.status.to_string()).set_code()); } @@ -291,6 +294,7 @@ impl RpcClient { .set_code()?; if res.is_invalid() { + counter!(format!("rpc_new_payload_v4_invalid_payload_{}", self.payload_source)).increment(1); return Err(RpcClientError::InvalidPayload(res.status.to_string()).set_code()); } @@ -377,7 +381,7 @@ mod tests { use super::*; const AUTH_PORT: u32 = 8550; - const AUTH_ADDR: &str = "0.0.0.0"; + const AUTH_ADDR: &str = "127.0.0.1"; const SECRET: &str = "f79ae8046bc11c9927afe911db7143c51a806c4a537cc08e0d37140b0192f430"; #[test] diff --git a/src/proxy.rs b/src/proxy.rs index 7afd478d..927891eb 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -206,7 +206,7 @@ mod tests { // None, )); - let temp_listener = TcpListener::bind("0.0.0.0:0").await?; + let temp_listener = TcpListener::bind("127.0.0.1:0").await?; let server_addr = temp_listener.local_addr()?; drop(temp_listener); @@ -247,7 +247,7 @@ mod tests { impl MockHttpServer { async fn serve() -> eyre::Result { - let listener = TcpListener::bind("0.0.0.0:0").await?; + let listener = TcpListener::bind("127.0.0.1:0").await?; let addr = listener.local_addr()?; let requests = Arc::new(Mutex::new(vec![])); diff --git a/src/server.rs b/src/server.rs index 6d36789b..88b689b6 100644 --- a/src/server.rs +++ b/src/server.rs @@ -2,6 +2,7 @@ use crate::client::rpc::RpcClient; use crate::debug_api::DebugServer; use crate::flashblocks::FlashblocksService; use alloy_primitives::{B256, Bytes}; +use metrics::{counter, histogram}; use moka::sync::Cache; use opentelemetry::trace::SpanKind; use parking_lot::Mutex; @@ -424,6 +425,39 @@ impl OpExecutionPayloadEnvelope { OpExecutionPayloadEnvelope::V4(_) => Version::V4, } } + + pub fn transactions(&self) -> &[Bytes] { + match self { + OpExecutionPayloadEnvelope::V3(v3) => { + &v3.execution_payload + .payload_inner + .payload_inner + .transactions + } + OpExecutionPayloadEnvelope::V4(v4) => { + &v4.execution_payload + .payload_inner + .payload_inner + .payload_inner + .transactions + } + } + } + + pub fn gas_used(&self) -> u64 { + match self { + OpExecutionPayloadEnvelope::V3(v3) => { + v3.execution_payload.payload_inner.payload_inner.gas_used + } + OpExecutionPayloadEnvelope::V4(v4) => { + v4.execution_payload + .payload_inner + .payload_inner + .payload_inner + .gas_used + } + } + } } impl From for ExecutionPayload { @@ -534,10 +568,20 @@ impl RollupBoostServer { let builder = self.builder_client.clone(); let new_payload_clone = new_payload.clone(); tokio::spawn(async move { - let _ = builder.new_payload(new_payload_clone).await; + let result = builder.new_payload(new_payload_clone).await; + if let Err(_) = &result { + error!("Invalid payload (builder): {:?}", result); + counter!("block_building_invalid_builder_payload").increment(1); + } }); } - Ok(self.l2_client.new_payload(new_payload).await?) + let result = self.l2_client.new_payload(new_payload).await; + if let Err(_) = &result { + error!("Invalid payload (l2): {:?}", result); + counter!("block_building_invalid_l2_payload").increment(1); + } + + Ok(result?) } async fn get_payload( @@ -605,8 +649,18 @@ impl RollupBoostServer { let (l2_payload, builder_payload) = tokio::join!(l2_client_future, builder_client_future); let (payload, context) = match (builder_payload, l2_payload) { - (Ok(Some(builder)), _) => Ok((builder, PayloadSource::Builder)), - (_, Ok(l2)) => Ok((l2, PayloadSource::L2)), + (Ok(Some(builder)), Ok(l2)) => { + histogram!("block_building_gas_difference") + .record((builder.transactions().len() - l2.transactions().len()) as f64); + histogram!("block_building_tx_count_difference") + .record((builder.gas_used() - l2.gas_used()) as f64); + counter!("block_building_builder_payloads_returned").increment(1); + Ok((builder, PayloadSource::Builder)) + }, + (_, Ok(l2)) => { + counter!("block_building_l2_payloads_returned").increment(1); + Ok((l2, PayloadSource::L2)) + }, (_, Err(e)) => Err(e), }?; @@ -651,12 +705,12 @@ mod tests { use std::sync::Arc; use tokio::time::sleep; - const HOST: &str = "0.0.0.0"; + const HOST: &str = "127.0.0.1"; const L2_PORT: u16 = 8545; const L2_ADDR: &str = "127.0.0.1:8545"; const BUILDER_PORT: u16 = 8544; const BUILDER_ADDR: &str = "127.0.0.1:8544"; - const SERVER_ADDR: &str = "0.0.0.0:8556"; + const SERVER_ADDR: &str = "127.0.0.1:8556"; #[derive(Debug, Clone)] pub struct MockEngineServer { @@ -753,7 +807,7 @@ mod tests { let module: RpcModule<()> = rollup_boost_client.try_into().unwrap(); let proxy_server = ServerBuilder::default() - .build("0.0.0.0:8556".parse::().unwrap()) + .build(SERVER_ADDR.parse::().unwrap()) .await .unwrap() .start(module); From 62723d7db54d7717ae395f8689a402954ca3d8a2 Mon Sep 17 00:00:00 2001 From: Joe Parks <26990067+jowparks@users.noreply.github.com> Date: Wed, 16 Apr 2025 14:55:27 -0700 Subject: [PATCH 21/23] metrics updates --- src/client/rpc.rs | 6 +++--- src/server.rs | 25 +++++++------------------ src/tracing.rs | 27 +++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/client/rpc.rs b/src/client/rpc.rs index 386de94a..64cb24ea 100644 --- a/src/client/rpc.rs +++ b/src/client/rpc.rs @@ -154,7 +154,7 @@ impl RpcClient { } if res.is_invalid() { - counter!(format!("rpc_fork_choice_updated_v3_invalid_payload_{}", self.payload_source)).increment(1); + counter!("rpc_invalid_payload", "method" => "fork_choice_updated_v3", "payload_source" => self.payload_source.to_string()).increment(1); return Err(RpcClientError::InvalidPayload( res.payload_status.status.to_string(), )) @@ -215,7 +215,7 @@ impl RpcClient { .set_code()?; if res.is_invalid() { - counter!(format!("rpc_new_payload_v3_invalid_payload_{}", self.payload_source)).increment(1); + counter!("rpc_invalid_payload", "method" => "new_payload_v3", "payload_source" => self.payload_source.to_string()).increment(1); return Err(RpcClientError::InvalidPayload(res.status.to_string()).set_code()); } @@ -294,7 +294,7 @@ impl RpcClient { .set_code()?; if res.is_invalid() { - counter!(format!("rpc_new_payload_v4_invalid_payload_{}", self.payload_source)).increment(1); + counter!("rpc_invalid_payload", "method" => "new_payload_v4", "payload_source" => self.payload_source.to_string()).increment(1); return Err(RpcClientError::InvalidPayload(res.status.to_string()).set_code()); } diff --git a/src/server.rs b/src/server.rs index 88b689b6..dc49b726 100644 --- a/src/server.rs +++ b/src/server.rs @@ -2,7 +2,7 @@ use crate::client::rpc::RpcClient; use crate::debug_api::DebugServer; use crate::flashblocks::FlashblocksService; use alloy_primitives::{B256, Bytes}; -use metrics::{counter, histogram}; +use metrics::counter; use moka::sync::Cache; use opentelemetry::trace::SpanKind; use parking_lot::Mutex; @@ -571,17 +571,11 @@ impl RollupBoostServer { let result = builder.new_payload(new_payload_clone).await; if let Err(_) = &result { error!("Invalid payload (builder): {:?}", result); - counter!("block_building_invalid_builder_payload").increment(1); + counter!("invalid_payload", "method" => "new_payload", "payload_source" => "builder").increment(1); } }); } - let result = self.l2_client.new_payload(new_payload).await; - if let Err(_) = &result { - error!("Invalid payload (l2): {:?}", result); - counter!("block_building_invalid_l2_payload").increment(1); - } - - Ok(result?) + Ok(self.l2_client.new_payload(new_payload).await?) } async fn get_payload( @@ -650,17 +644,12 @@ impl RollupBoostServer { let (l2_payload, builder_payload) = tokio::join!(l2_client_future, builder_client_future); let (payload, context) = match (builder_payload, l2_payload) { (Ok(Some(builder)), Ok(l2)) => { - histogram!("block_building_gas_difference") - .record((builder.transactions().len() - l2.transactions().len()) as f64); - histogram!("block_building_tx_count_difference") - .record((builder.gas_used() - l2.gas_used()) as f64); - counter!("block_building_builder_payloads_returned").increment(1); + tracing::Span::current().record("gas_delta", (builder.gas_used() - l2.gas_used()).to_string()); + tracing::Span::current().record("tx_count_delta", (builder.transactions().len() - l2.transactions().len()).to_string()); Ok((builder, PayloadSource::Builder)) }, - (_, Ok(l2)) => { - counter!("block_building_l2_payloads_returned").increment(1); - Ok((l2, PayloadSource::L2)) - }, + (Ok(Some(builder)), _) => Ok((builder, PayloadSource::Builder)), + (_, Ok(l2)) => Ok((l2, PayloadSource::L2)), (_, Err(e)) => Err(e), }?; diff --git a/src/tracing.rs b/src/tracing.rs index fdd917c7..0701d951 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -1,5 +1,5 @@ use eyre::Context as _; -use metrics::histogram; +use metrics::{counter, histogram}; use opentelemetry::trace::{Status, TracerProvider as _}; use opentelemetry::{KeyValue, global}; use opentelemetry_otlp::WithExportConfig; @@ -18,7 +18,7 @@ use crate::cli::{Args, LogFormat}; /// Use caution when adding new attributes here and keep /// label cardinality in mind. Not all span attributes make /// appropriate labels. -pub const SPAN_ATTRIBUTE_LABELS: [&str; 3] = ["code", "has_attributes", "payload_source"]; +pub const SPAN_ATTRIBUTE_LABELS: [&str; 5] = ["code", "has_attributes", "payload_source", "gas_delta", "tx_count_delta"]; /// Custom span processor that records span durations as histograms #[derive(Debug)] @@ -56,6 +56,29 @@ impl SpanProcessor for MetricsSpanProcessor { ("status".to_string(), status.into()), ]) .collect::>(); + + let payload_source = span.attributes.iter() + .find(|attr| attr.key.as_str() == "payload_source") + .map(|attr| attr.value.as_str().to_string()) + .unwrap_or("unknown".to_string()); + + counter!("block_building_payload_returned", "payload_source" => payload_source.clone()).increment(1); + + let gas_delta = span.attributes.iter() + .find(|attr| attr.key.as_str() == "gas_delta") + .map(|attr| attr.value.as_str().to_string()); + + if let Some(gas_delta) = gas_delta { + counter!("block_building_gas_delta").increment(gas_delta.parse::().unwrap_or_default()); + } + + let tx_count_delta = span.attributes.iter() + .find(|attr| attr.key.as_str() == "tx_count_delta") + .map(|attr| attr.value.as_str().to_string()); + + if let Some(tx_count_delta) = tx_count_delta { + counter!("block_building_tx_count_delta").increment(tx_count_delta.parse::().unwrap_or_default()); + } histogram!(format!("{}_duration", span.name), &labels).record(duration); } From 616df18a309b360d7564ee4c94ebaf1c4329685e Mon Sep 17 00:00:00 2001 From: Joe Parks <26990067+jowparks@users.noreply.github.com> Date: Thu, 17 Apr 2025 11:17:35 -0700 Subject: [PATCH 22/23] Update metrics and error handling - Added gas_delta and tx_count_delta to payload metrics in get_payload_v3 and get_payload_v4. - Updated MetricsSpanProcessor to include INVALID_PAYLOAD tracking. - Refactored error handling in RpcClient to log invalid payloads instead of incrementing counters directly. --- src/client/rpc.rs | 20 +++++++++++++------- src/server.rs | 27 ++++++++++++++++----------- src/tracing.rs | 34 ++++++++++++++++++++++------------ 3 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/client/rpc.rs b/src/client/rpc.rs index 64cb24ea..fb63854d 100644 --- a/src/client/rpc.rs +++ b/src/client/rpc.rs @@ -12,7 +12,6 @@ use http::Uri; use jsonrpsee::http_client::transport::HttpBackend; use jsonrpsee::http_client::{HttpClient, HttpClientBuilder}; use jsonrpsee::types::ErrorObjectOwned; -use metrics::counter; use op_alloy_rpc_types_engine::{ OpExecutionPayloadEnvelopeV3, OpExecutionPayloadEnvelopeV4, OpExecutionPayloadV4, OpPayloadAttributes, @@ -25,6 +24,9 @@ use thiserror::Error; use tracing::{error, info, instrument}; const INTERNAL_ERROR: i32 = 13; +const INVALID_PAYLOAD: i32 = 1337; +const IO_ERROR: i32 = 1338; +const JWT_ERROR: i32 = 1339; pub(crate) type ClientResult = Result; @@ -44,7 +46,8 @@ trait Code: Sized { fn code(&self) -> i32; fn set_code(self) -> Self { - tracing::Span::current().record("code", self.code()); + let code_value: i64 = self.code().into(); + tracing::Span::current().record("code", code_value.to_string()); self } } @@ -62,9 +65,10 @@ impl Code for Result { impl Code for RpcClientError { fn code(&self) -> i32 { match self { + RpcClientError::InvalidPayload(_) => INVALID_PAYLOAD, + RpcClientError::Io(_) => IO_ERROR, + RpcClientError::Jwt(_) => JWT_ERROR, RpcClientError::Jsonrpsee(e) => e.code(), - // Status code 13 == internal error - _ => INTERNAL_ERROR, } } } @@ -154,7 +158,7 @@ impl RpcClient { } if res.is_invalid() { - counter!("rpc_invalid_payload", "method" => "fork_choice_updated_v3", "payload_source" => self.payload_source.to_string()).increment(1); + error!("Invalid payload ({}): {:?}", self.payload_source, res); return Err(RpcClientError::InvalidPayload( res.payload_status.status.to_string(), )) @@ -172,6 +176,7 @@ impl RpcClient { target = self.payload_source.to_string(), url = %self.auth_rpc, %payload_id, + code, ) )] pub async fn get_payload_v3( @@ -215,7 +220,7 @@ impl RpcClient { .set_code()?; if res.is_invalid() { - counter!("rpc_invalid_payload", "method" => "new_payload_v3", "payload_source" => self.payload_source.to_string()).increment(1); + error!("Invalid payload ({}): {:?}", self.payload_source, res); return Err(RpcClientError::InvalidPayload(res.status.to_string()).set_code()); } @@ -230,6 +235,7 @@ impl RpcClient { target = self.payload_source.to_string(), url = %self.auth_rpc, %payload_id, + code, ) )] pub async fn get_payload_v4( @@ -294,7 +300,7 @@ impl RpcClient { .set_code()?; if res.is_invalid() { - counter!("rpc_invalid_payload", "method" => "new_payload_v4", "payload_source" => self.payload_source.to_string()).increment(1); + error!("Invalid payload ({}): {:?}", self.payload_source, res); return Err(RpcClientError::InvalidPayload(res.status.to_string()).set_code()); } diff --git a/src/server.rs b/src/server.rs index dc49b726..a7f15a13 100644 --- a/src/server.rs +++ b/src/server.rs @@ -2,7 +2,6 @@ use crate::client::rpc::RpcClient; use crate::debug_api::DebugServer; use crate::flashblocks::FlashblocksService; use alloy_primitives::{B256, Bytes}; -use metrics::counter; use moka::sync::Cache; use opentelemetry::trace::SpanKind; use parking_lot::Mutex; @@ -319,7 +318,9 @@ impl EngineApiServer for RollupBoostServer { fields( otel.kind = ?SpanKind::Server, %payload_id, - payload_source + payload_source, + gas_delta, + tx_count_delta, ) )] async fn get_payload_v3( @@ -367,7 +368,9 @@ impl EngineApiServer for RollupBoostServer { fields( otel.kind = ?SpanKind::Server, %payload_id, - payload_source + payload_source, + gas_delta, + tx_count_delta, ) )] async fn get_payload_v4( @@ -568,11 +571,7 @@ impl RollupBoostServer { let builder = self.builder_client.clone(); let new_payload_clone = new_payload.clone(); tokio::spawn(async move { - let result = builder.new_payload(new_payload_clone).await; - if let Err(_) = &result { - error!("Invalid payload (builder): {:?}", result); - counter!("invalid_payload", "method" => "new_payload", "payload_source" => "builder").increment(1); - } + let _ = builder.new_payload(new_payload_clone).await; }); } Ok(self.l2_client.new_payload(new_payload).await?) @@ -644,10 +643,16 @@ impl RollupBoostServer { let (l2_payload, builder_payload) = tokio::join!(l2_client_future, builder_client_future); let (payload, context) = match (builder_payload, l2_payload) { (Ok(Some(builder)), Ok(l2)) => { - tracing::Span::current().record("gas_delta", (builder.gas_used() - l2.gas_used()).to_string()); - tracing::Span::current().record("tx_count_delta", (builder.transactions().len() - l2.transactions().len()).to_string()); + tracing::Span::current().record( + "gas_delta", + (builder.gas_used() - l2.gas_used()).to_string(), + ); + tracing::Span::current().record( + "tx_count_delta", + (builder.transactions().len() - l2.transactions().len()).to_string(), + ); Ok((builder, PayloadSource::Builder)) - }, + } (Ok(Some(builder)), _) => Ok((builder, PayloadSource::Builder)), (_, Ok(l2)) => Ok((l2, PayloadSource::L2)), (_, Err(e)) => Err(e), diff --git a/src/tracing.rs b/src/tracing.rs index 0701d951..5d2d9411 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -18,7 +18,7 @@ use crate::cli::{Args, LogFormat}; /// Use caution when adding new attributes here and keep /// label cardinality in mind. Not all span attributes make /// appropriate labels. -pub const SPAN_ATTRIBUTE_LABELS: [&str; 5] = ["code", "has_attributes", "payload_source", "gas_delta", "tx_count_delta"]; +pub const SPAN_ATTRIBUTE_LABELS: [&str; 3] = ["code", "has_attributes", "payload_source"]; /// Custom span processor that records span durations as histograms #[derive(Debug)] @@ -56,28 +56,38 @@ impl SpanProcessor for MetricsSpanProcessor { ("status".to_string(), status.into()), ]) .collect::>(); - - let payload_source = span.attributes.iter() - .find(|attr| attr.key.as_str() == "payload_source") - .map(|attr| attr.value.as_str().to_string()) - .unwrap_or("unknown".to_string()); - counter!("block_building_payload_returned", "payload_source" => payload_source.clone()).increment(1); + let code = span + .attributes + .iter() + .find(|attr| attr.key.as_str() == "code") + .and_then(|attr| attr.value.as_str().parse::().ok()) + .unwrap_or(0); - let gas_delta = span.attributes.iter() + if code != 0 { + counter!("error", &labels).increment(1); + } + + let gas_delta = span + .attributes + .iter() .find(|attr| attr.key.as_str() == "gas_delta") .map(|attr| attr.value.as_str().to_string()); if let Some(gas_delta) = gas_delta { - counter!("block_building_gas_delta").increment(gas_delta.parse::().unwrap_or_default()); + histogram!("block_building_gas_delta", &labels) + .record(gas_delta.parse::().unwrap_or_default() as f64); } - - let tx_count_delta = span.attributes.iter() + + let tx_count_delta = span + .attributes + .iter() .find(|attr| attr.key.as_str() == "tx_count_delta") .map(|attr| attr.value.as_str().to_string()); if let Some(tx_count_delta) = tx_count_delta { - counter!("block_building_tx_count_delta").increment(tx_count_delta.parse::().unwrap_or_default()); + histogram!("block_building_tx_count_delta", &labels) + .record(tx_count_delta.parse::().unwrap_or_default() as f64); } histogram!(format!("{}_duration", span.name), &labels).record(duration); From 2c867b01573f5e95cdda9dabd05f0b4855dbfbb4 Mon Sep 17 00:00:00 2001 From: Joe Parks <26990067+jowparks@users.noreply.github.com> Date: Mon, 21 Apr 2025 09:19:36 -0700 Subject: [PATCH 23/23] add code commenting, remove unneeded error metric, PR comments --- src/tracing.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/tracing.rs b/src/tracing.rs index 5d2d9411..90a45fc7 100644 --- a/src/tracing.rs +++ b/src/tracing.rs @@ -57,17 +57,9 @@ impl SpanProcessor for MetricsSpanProcessor { ]) .collect::>(); - let code = span - .attributes - .iter() - .find(|attr| attr.key.as_str() == "code") - .and_then(|attr| attr.value.as_str().parse::().ok()) - .unwrap_or(0); - - if code != 0 { - counter!("error", &labels).increment(1); - } - + // 0 = no difference in gas build via builder vs l2 + // > 0 = gas used by builder block is greater than l2 block + // < 0 = gas used by l2 block is greater than builder block let gas_delta = span .attributes .iter() @@ -79,6 +71,9 @@ impl SpanProcessor for MetricsSpanProcessor { .record(gas_delta.parse::().unwrap_or_default() as f64); } + // 0 = no difference in tx count build via builder vs l2 + // > 0 = num txs in builder block is greater than l2 block + // < 0 = num txs in l2 block is greater than builder block let tx_count_delta = span .attributes .iter()