reth_node_core/
utils.rs
1use alloy_consensus::BlockHeader;
5use alloy_eips::BlockHashOrNumber;
6use alloy_rpc_types_engine::{JwtError, JwtSecret};
7use eyre::Result;
8use reth_consensus::{Consensus, ConsensusError};
9use reth_network_p2p::{
10 bodies::client::BodiesClient, headers::client::HeadersClient, priority::Priority,
11};
12use reth_primitives_traits::{Block, SealedBlock, SealedHeader};
13use std::{
14 env::VarError,
15 path::{Path, PathBuf},
16};
17use tracing::{debug, info};
18
19pub fn parse_path(value: &str) -> Result<PathBuf, shellexpand::LookupError<VarError>> {
22 shellexpand::full(value).map(|path| PathBuf::from(path.into_owned()))
23}
24
25pub fn get_or_create_jwt_secret_from_path(path: &Path) -> Result<JwtSecret, JwtError> {
27 if path.exists() {
28 debug!(target: "reth::cli", ?path, "Reading JWT auth secret file");
29 JwtSecret::from_file(path)
30 } else {
31 info!(target: "reth::cli", ?path, "Creating JWT auth secret file");
32 JwtSecret::try_create_random(path)
33 }
34}
35
36pub async fn get_single_header<Client>(
38 client: Client,
39 id: BlockHashOrNumber,
40) -> Result<SealedHeader<Client::Header>>
41where
42 Client: HeadersClient<Header: reth_primitives_traits::BlockHeader>,
43{
44 let (peer_id, response) = client.get_header_with_priority(id, Priority::High).await?.split();
45
46 let Some(header) = response else {
47 client.report_bad_message(peer_id);
48 eyre::bail!("Invalid number of headers received. Expected: 1. Received: 0")
49 };
50
51 let header = SealedHeader::seal_slow(header);
52
53 let valid = match id {
54 BlockHashOrNumber::Hash(hash) => header.hash() == hash,
55 BlockHashOrNumber::Number(number) => header.number() == number,
56 };
57
58 if !valid {
59 client.report_bad_message(peer_id);
60 eyre::bail!(
61 "Received invalid header. Received: {:?}. Expected: {:?}",
62 header.num_hash(),
63 id
64 );
65 }
66
67 Ok(header)
68}
69
70pub async fn get_single_body<B, Client>(
72 client: Client,
73 header: SealedHeader<B::Header>,
74 consensus: impl Consensus<B, Error = ConsensusError>,
75) -> Result<SealedBlock<B>>
76where
77 B: Block,
78 Client: BodiesClient<Body = B::Body>,
79{
80 let (peer_id, response) = client.get_block_body(header.hash()).await?.split();
81
82 let Some(body) = response else {
83 client.report_bad_message(peer_id);
84 eyre::bail!("Invalid number of bodies received. Expected: 1. Received: 0")
85 };
86
87 let block = SealedBlock::from_sealed_parts(header, body);
88 consensus.validate_block_pre_execution(&block)?;
89
90 Ok(block)
91}