Skip to content

Commit c4e0066

Browse files
authored
chore: refactor payload logic into separate module (#230)
* chore: refactor into payload.rs and engine.rs * fix: fix tests * chore: clippy * chore: restructure RollupBoost impl * chore: remove unused import * chore: move engine api trait into server * fix: fix imports * fmt: cargo fmt
1 parent eba81d4 commit c4e0066

File tree

9 files changed

+397
-382
lines changed

9 files changed

+397
-382
lines changed

src/cli.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ use tokio::signal::unix::{SignalKind, signal as unix_signal};
88
use tracing::{Level, info};
99

1010
use crate::{
11-
DebugClient, PayloadSource, ProxyLayer, RollupBoostServer, RpcClient,
11+
DebugClient, ProxyLayer, RollupBoostServer, RpcClient,
1212
client::rpc::{BuilderArgs, L2ClientArgs},
1313
debug_api::ExecutionMode,
1414
init_metrics, init_tracing,
15+
payload::PayloadSource,
1516
probe::ProbeLayer,
1617
};
1718

src/client/http.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::client::auth::AuthLayer;
2-
use crate::server::PayloadSource;
2+
use crate::payload::PayloadSource;
33
use alloy_rpc_types_engine::JwtSecret;
44
use http::Uri;
55
use http_body_util::BodyExt;

src/client/rpc.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use crate::client::auth::AuthLayer;
2-
use crate::server::{
3-
EngineApiClient, NewPayload, OpExecutionPayloadEnvelope, PayloadSource, Version,
4-
};
5-
2+
use crate::payload::{NewPayload, OpExecutionPayloadEnvelope, PayloadSource, PayloadVersion};
3+
use crate::server::EngineApiClient;
64
use alloy_primitives::{B256, Bytes};
75
use alloy_rpc_types_engine::{
86
ExecutionPayload, ExecutionPayloadV3, ForkchoiceState, ForkchoiceUpdated, JwtError, JwtSecret,
@@ -249,13 +247,13 @@ impl RpcClient {
249247
pub async fn get_payload(
250248
&self,
251249
payload_id: PayloadId,
252-
version: Version,
250+
version: PayloadVersion,
253251
) -> ClientResult<OpExecutionPayloadEnvelope> {
254252
match version {
255-
Version::V3 => Ok(OpExecutionPayloadEnvelope::V3(
253+
PayloadVersion::V3 => Ok(OpExecutionPayloadEnvelope::V3(
256254
self.get_payload_v3(payload_id).await.set_code()?,
257255
)),
258-
Version::V4 => Ok(OpExecutionPayloadEnvelope::V4(
256+
PayloadVersion::V4 => Ok(OpExecutionPayloadEnvelope::V4(
259257
self.get_payload_v4(payload_id).await.set_code()?,
260258
)),
261259
}
@@ -374,7 +372,7 @@ pub mod tests {
374372
use jsonrpsee::core::client::ClientT;
375373
use parking_lot::Mutex;
376374

377-
use crate::server::PayloadSource;
375+
use crate::payload::PayloadSource;
378376
use alloy_rpc_types_engine::JwtSecret;
379377
use jsonrpsee::RpcModule;
380378
use jsonrpsee::http_client::transport::Error as TransportError;

src/health.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ mod tests {
7676
use tokio::net::TcpListener;
7777

7878
use super::*;
79-
use crate::{PayloadSource, Probes};
79+
use crate::{Probes, payload::PayloadSource};
8080

8181
pub struct MockHttpServer {
8282
addr: SocketAddr,

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ pub use probe::*;
2727

2828
mod health;
2929
pub use health::*;
30+
31+
mod payload;
32+
pub use payload::*;

src/payload.rs

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
use alloy_primitives::{B256, Bytes};
2+
use futures::{StreamExt as _, stream};
3+
use moka::future::Cache;
4+
5+
use alloy_rpc_types_engine::{ExecutionPayload, ExecutionPayloadV3, PayloadId};
6+
use op_alloy_rpc_types_engine::{
7+
OpExecutionPayloadEnvelopeV3, OpExecutionPayloadEnvelopeV4, OpExecutionPayloadV4,
8+
};
9+
10+
const CACHE_SIZE: u64 = 100;
11+
12+
#[derive(Debug, Clone)]
13+
pub enum OpExecutionPayloadEnvelope {
14+
V3(OpExecutionPayloadEnvelopeV3),
15+
V4(OpExecutionPayloadEnvelopeV4),
16+
}
17+
18+
impl OpExecutionPayloadEnvelope {
19+
pub fn version(&self) -> PayloadVersion {
20+
match self {
21+
OpExecutionPayloadEnvelope::V3(_) => PayloadVersion::V3,
22+
OpExecutionPayloadEnvelope::V4(_) => PayloadVersion::V4,
23+
}
24+
}
25+
}
26+
27+
impl From<OpExecutionPayloadEnvelope> for ExecutionPayload {
28+
fn from(envelope: OpExecutionPayloadEnvelope) -> Self {
29+
match envelope {
30+
OpExecutionPayloadEnvelope::V3(v3) => ExecutionPayload::from(v3.execution_payload),
31+
OpExecutionPayloadEnvelope::V4(v4) => {
32+
ExecutionPayload::from(v4.execution_payload.payload_inner)
33+
}
34+
}
35+
}
36+
}
37+
38+
#[derive(Debug, Clone)]
39+
pub struct NewPayloadV3 {
40+
pub payload: ExecutionPayloadV3,
41+
pub versioned_hashes: Vec<B256>,
42+
pub parent_beacon_block_root: B256,
43+
}
44+
45+
#[derive(Debug, Clone)]
46+
pub struct NewPayloadV4 {
47+
pub payload: OpExecutionPayloadV4,
48+
pub versioned_hashes: Vec<B256>,
49+
pub parent_beacon_block_root: B256,
50+
pub execution_requests: Vec<Bytes>,
51+
}
52+
53+
#[derive(Debug, Clone)]
54+
pub enum NewPayload {
55+
V3(NewPayloadV3),
56+
V4(NewPayloadV4),
57+
}
58+
59+
impl NewPayload {
60+
pub fn version(&self) -> PayloadVersion {
61+
match self {
62+
NewPayload::V3(_) => PayloadVersion::V3,
63+
NewPayload::V4(_) => PayloadVersion::V4,
64+
}
65+
}
66+
}
67+
68+
impl From<OpExecutionPayloadEnvelope> for NewPayload {
69+
fn from(envelope: OpExecutionPayloadEnvelope) -> Self {
70+
match envelope {
71+
OpExecutionPayloadEnvelope::V3(v3) => NewPayload::V3(NewPayloadV3 {
72+
payload: v3.execution_payload,
73+
versioned_hashes: vec![],
74+
parent_beacon_block_root: v3.parent_beacon_block_root,
75+
}),
76+
OpExecutionPayloadEnvelope::V4(v4) => NewPayload::V4(NewPayloadV4 {
77+
payload: v4.execution_payload,
78+
versioned_hashes: vec![],
79+
parent_beacon_block_root: v4.parent_beacon_block_root,
80+
execution_requests: v4.execution_requests,
81+
}),
82+
}
83+
}
84+
}
85+
86+
impl From<NewPayload> for ExecutionPayload {
87+
fn from(new_payload: NewPayload) -> Self {
88+
match new_payload {
89+
NewPayload::V3(v3) => ExecutionPayload::from(v3.payload),
90+
NewPayload::V4(v4) => ExecutionPayload::from(v4.payload.payload_inner),
91+
}
92+
}
93+
}
94+
95+
#[derive(Debug, Clone, Copy)]
96+
pub enum PayloadVersion {
97+
V3,
98+
V4,
99+
}
100+
101+
impl PayloadVersion {
102+
pub fn as_str(&self) -> &'static str {
103+
match self {
104+
PayloadVersion::V3 => "v3",
105+
PayloadVersion::V4 => "v4",
106+
}
107+
}
108+
}
109+
110+
#[derive(Debug, Clone)]
111+
pub enum PayloadSource {
112+
L2,
113+
Builder,
114+
}
115+
116+
impl std::fmt::Display for PayloadSource {
117+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118+
match self {
119+
PayloadSource::L2 => write!(f, "l2"),
120+
PayloadSource::Builder => write!(f, "builder"),
121+
}
122+
}
123+
}
124+
125+
#[allow(dead_code)]
126+
impl PayloadSource {
127+
pub fn is_builder(&self) -> bool {
128+
matches!(self, PayloadSource::Builder)
129+
}
130+
131+
pub fn is_l2(&self) -> bool {
132+
matches!(self, PayloadSource::L2)
133+
}
134+
}
135+
136+
#[derive(Debug, Clone)]
137+
pub struct PayloadTrace {
138+
pub builder_has_payload: bool,
139+
pub trace_id: Option<tracing::Id>,
140+
}
141+
142+
pub struct PayloadTraceContext {
143+
block_hash_to_payload_ids: Cache<B256, Vec<PayloadId>>,
144+
payload_id: Cache<PayloadId, PayloadTrace>,
145+
}
146+
147+
impl Default for PayloadTraceContext {
148+
fn default() -> Self {
149+
Self::new()
150+
}
151+
}
152+
153+
impl PayloadTraceContext {
154+
pub fn new() -> Self {
155+
PayloadTraceContext {
156+
block_hash_to_payload_ids: Cache::new(CACHE_SIZE),
157+
payload_id: Cache::new(CACHE_SIZE),
158+
}
159+
}
160+
161+
pub async fn store(
162+
&self,
163+
payload_id: PayloadId,
164+
parent_hash: B256,
165+
builder_has_payload: bool,
166+
trace_id: Option<tracing::Id>,
167+
) {
168+
self.payload_id
169+
.insert(
170+
payload_id,
171+
PayloadTrace {
172+
builder_has_payload,
173+
trace_id,
174+
},
175+
)
176+
.await;
177+
self.block_hash_to_payload_ids
178+
.entry(parent_hash)
179+
.and_upsert_with(|o| match o {
180+
Some(e) => {
181+
let mut payloads = e.into_value();
182+
payloads.push(payload_id);
183+
std::future::ready(payloads)
184+
}
185+
None => std::future::ready(vec![payload_id]),
186+
})
187+
.await;
188+
}
189+
190+
pub async fn trace_ids_from_parent_hash(&self, parent_hash: &B256) -> Option<Vec<tracing::Id>> {
191+
match self.block_hash_to_payload_ids.get(parent_hash).await {
192+
Some(payload_ids) => Some(
193+
stream::iter(payload_ids.iter())
194+
.filter_map(|payload_id| async {
195+
self.payload_id
196+
.get(payload_id)
197+
.await
198+
.and_then(|x| x.trace_id)
199+
})
200+
.collect()
201+
.await,
202+
),
203+
None => None,
204+
}
205+
}
206+
207+
pub async fn trace_id(&self, payload_id: &PayloadId) -> Option<tracing::Id> {
208+
self.payload_id
209+
.get(payload_id)
210+
.await
211+
.and_then(|x| x.trace_id)
212+
}
213+
214+
pub async fn has_builder_payload(&self, payload_id: &PayloadId) -> bool {
215+
self.payload_id
216+
.get(payload_id)
217+
.await
218+
.map(|x| x.builder_has_payload)
219+
.unwrap_or_default()
220+
}
221+
222+
pub async fn remove_by_parent_hash(&self, block_hash: &B256) {
223+
if let Some(payload_ids) = self.block_hash_to_payload_ids.remove(block_hash).await {
224+
for payload_id in payload_ids.iter() {
225+
self.payload_id.remove(payload_id).await;
226+
}
227+
}
228+
}
229+
}

src/proxy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::client::http::HttpClient;
2-
use crate::server::PayloadSource;
2+
use crate::payload::PayloadSource;
33
use alloy_rpc_types_engine::JwtSecret;
44
use http::Uri;
55
use jsonrpsee::core::{BoxError, http_helpers};

0 commit comments

Comments
 (0)