reth_rpc_api/reth_engine.rs
1//! Reth-specific engine API extensions.
2
3use alloy_primitives::Bytes;
4use alloy_rpc_types_engine::{ForkchoiceState, ForkchoiceUpdated, PayloadStatus};
5use jsonrpsee::{core::RpcResult, proc_macros::rpc};
6use serde::{Deserialize, Serialize};
7
8/// Reth-specific payload status that includes server-measured execution latency.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct RethPayloadStatus {
11 /// The standard payload status.
12 #[serde(flatten)]
13 pub status: PayloadStatus,
14 /// Server-side execution latency in microseconds.
15 pub latency_us: u64,
16 /// Time spent waiting on persistence in microseconds, including both time spent
17 /// queued due to persistence backpressure and, when requested, the explicit wait
18 /// for in-flight persistence to complete.
19 pub persistence_wait_us: u64,
20 /// Time spent waiting for the execution cache lock, in microseconds.
21 ///
22 /// `None` when wasn't asked to wait.
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub execution_cache_wait_us: Option<u64>,
25 /// Time spent waiting for the sparse trie lock, in microseconds.
26 ///
27 /// `None` when wasn't asked to wait.
28 #[serde(skip_serializing_if = "Option::is_none")]
29 pub sparse_trie_wait_us: Option<u64>,
30}
31
32/// Input for `reth_newPayload` that accepts either `ExecutionData` directly or an RLP-encoded
33/// block.
34#[derive(Debug, Clone, Serialize, Deserialize)]
35#[serde(untagged)]
36pub enum RethNewPayloadInput<ExecutionData> {
37 /// Standard execution data (payload + sidecar).
38 ExecutionData(ExecutionData),
39 /// An RLP-encoded block.
40 BlockRlp(Bytes),
41}
42
43/// Reth-specific engine API extensions.
44///
45/// This trait provides a `reth_newPayload` endpoint that accepts either `ExecutionData` directly
46/// (payload + sidecar) or an RLP-encoded block, optionally alongside a block access list and
47/// waiting for persistence and cache locks before processing.
48///
49/// By default, the endpoint waits for both in-flight persistence and cache updates to complete
50/// before executing the payload, providing unbiased timing measurements. Each can be independently
51/// disabled via `wait_for_persistence` and `wait_for_caches`.
52///
53/// Responses include timing breakdowns with server-measured execution latency.
54#[cfg_attr(not(feature = "client"), rpc(server, namespace = "reth"))]
55#[cfg_attr(feature = "client", rpc(server, client, namespace = "reth"))]
56pub trait RethEngineApi<ExecutionData> {
57 /// Reth-specific newPayload that accepts either `ExecutionData` directly or an RLP-encoded
58 /// block.
59 ///
60 /// `wait_for_persistence` (default `true`): waits for in-flight persistence to complete.
61 /// `wait_for_caches` (default `true`): waits for execution cache and sparse trie locks.
62 #[method(name = "newPayload")]
63 async fn reth_new_payload(
64 &self,
65 payload: RethNewPayloadInput<ExecutionData>,
66 wait_for_persistence: Option<bool>,
67 wait_for_caches: Option<bool>,
68 ) -> RpcResult<RethPayloadStatus>;
69
70 /// Reth-specific forkchoiceUpdated that sends a regular forkchoice update with no payload
71 /// attributes.
72 #[method(name = "forkchoiceUpdated")]
73 async fn reth_forkchoice_updated(
74 &self,
75 forkchoice_state: ForkchoiceState,
76 ) -> RpcResult<ForkchoiceUpdated>;
77}