Skip to main content

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 for persistence to complete, in microseconds.
17    /// `None` when no persistence was in-flight.
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub persistence_wait_us: Option<u64>,
20    /// Time spent waiting for the execution cache lock, in microseconds.
21    pub execution_cache_wait_us: u64,
22    /// Time spent waiting for the sparse trie lock, in microseconds.
23    pub sparse_trie_wait_us: u64,
24}
25
26/// Input for `reth_newPayload` that accepts either `ExecutionData` directly or an RLP-encoded
27/// block.
28#[derive(Debug, Clone, Serialize, Deserialize)]
29#[serde(untagged)]
30pub enum RethNewPayloadInput<ExecutionData> {
31    /// Standard execution data (payload + sidecar).
32    ExecutionData(ExecutionData),
33    /// An RLP-encoded block.
34    BlockRlp(Bytes),
35}
36
37/// Reth-specific engine API extensions.
38///
39/// This trait provides a `reth_newPayload` endpoint that accepts either `ExecutionData` directly
40/// (payload + sidecar) or an RLP-encoded block, waiting for persistence and cache locks before
41/// processing.
42///
43/// Responses include timing breakdowns with server-measured execution latency.
44#[cfg_attr(not(feature = "client"), rpc(server, namespace = "reth"))]
45#[cfg_attr(feature = "client", rpc(server, client, namespace = "reth"))]
46pub trait RethEngineApi<ExecutionData> {
47    /// Reth-specific newPayload that accepts either `ExecutionData` directly or an RLP-encoded
48    /// block.
49    ///
50    /// Waits for persistence, execution cache, and sparse trie locks before processing.
51    #[method(name = "newPayload")]
52    async fn reth_new_payload(
53        &self,
54        payload: RethNewPayloadInput<ExecutionData>,
55    ) -> RpcResult<RethPayloadStatus>;
56
57    /// Reth-specific forkchoiceUpdated that sends a regular forkchoice update with no payload
58    /// attributes.
59    #[method(name = "forkchoiceUpdated")]
60    async fn reth_forkchoice_updated(
61        &self,
62        forkchoice_state: ForkchoiceState,
63    ) -> RpcResult<ForkchoiceUpdated>;
64}