ethrex_rpc/engine/
exchange_transition_config.rs1use ethrex_common::{H256, serde_utils};
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4use tracing::{debug, warn};
5
6use crate::{
7 rpc::{RpcApiContext, RpcHandler},
8 utils::RpcErr,
9};
10
11#[derive(Debug, Serialize, Deserialize)]
12#[serde(rename_all = "camelCase")]
13pub struct ExchangeTransitionConfigPayload {
14 #[serde(with = "serde_utils::u128::hex_str")]
15 terminal_total_difficulty: u128,
16 terminal_block_hash: H256,
17 #[serde(with = "serde_utils::u64::hex_str")]
18 terminal_block_number: u64,
19}
20
21#[derive(Debug)]
22pub struct ExchangeTransitionConfigV1Req {
23 payload: ExchangeTransitionConfigPayload,
24}
25
26impl std::fmt::Display for ExchangeTransitionConfigV1Req {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 write!(
29 f,
30 "ExchangeTransitionConfigV1Req {{ terminal_total_difficulty: {}, terminal_block_hash: {:?}, terminal_block_number: {} }}",
31 self.payload.terminal_total_difficulty,
32 self.payload.terminal_block_hash,
33 self.payload.terminal_block_number
34 )
35 }
36}
37
38impl RpcHandler for ExchangeTransitionConfigV1Req {
39 fn parse(params: &Option<Vec<Value>>) -> Result<ExchangeTransitionConfigV1Req, RpcErr> {
40 let params = params
41 .as_ref()
42 .ok_or(RpcErr::BadParams("No params provided".to_owned()))?;
43 if params.len() != 1 {
44 return Err(RpcErr::BadParams("Expected 1 param".to_owned()));
45 };
46 let payload: ExchangeTransitionConfigPayload = serde_json::from_value(params[0].clone())?;
47 Ok(ExchangeTransitionConfigV1Req { payload })
48 }
49
50 async fn handle(&self, context: RpcApiContext) -> Result<Value, RpcErr> {
51 debug!("Requested new engine request: {self}");
52 let payload = &self.payload;
53
54 let chain_config = context.storage.get_chain_config();
55 let terminal_total_difficulty = chain_config.terminal_total_difficulty;
56
57 if terminal_total_difficulty.unwrap_or_default() != payload.terminal_total_difficulty {
58 warn!(
59 "Invalid terminal total difficulty configured: execution {:?} consensus {}",
60 terminal_total_difficulty, payload.terminal_total_difficulty
61 );
62 };
63
64 let block = context
65 .storage
66 .get_block_header(payload.terminal_block_number)?;
67 let terminal_block_hash = block.map_or(H256::zero(), |block| block.hash());
68
69 serde_json::to_value(ExchangeTransitionConfigPayload {
70 terminal_block_hash,
71 terminal_block_number: payload.terminal_block_number,
72 terminal_total_difficulty: terminal_total_difficulty.unwrap_or_default(),
73 })
74 .map_err(|error| RpcErr::Internal(error.to_string()))
75 }
76}