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