use alloy_consensus::BlockHeader;
use alloy_eips::BlockHashOrNumber;
use alloy_rpc_types_engine::{JwtError, JwtSecret};
use eyre::Result;
use reth_consensus::Consensus;
use reth_network_p2p::{
bodies::client::BodiesClient, headers::client::HeadersClient, priority::Priority,
};
use reth_primitives::SealedBlock;
use reth_primitives_traits::SealedHeader;
use std::{
env::VarError,
path::{Path, PathBuf},
};
use tracing::{debug, info};
pub fn parse_path(value: &str) -> Result<PathBuf, shellexpand::LookupError<VarError>> {
shellexpand::full(value).map(|path| PathBuf::from(path.into_owned()))
}
pub fn get_or_create_jwt_secret_from_path(path: &Path) -> Result<JwtSecret, JwtError> {
if path.exists() {
debug!(target: "reth::cli", ?path, "Reading JWT auth secret file");
JwtSecret::from_file(path)
} else {
info!(target: "reth::cli", ?path, "Creating JWT auth secret file");
JwtSecret::try_create_random(path)
}
}
pub async fn get_single_header<Client>(
client: Client,
id: BlockHashOrNumber,
) -> Result<SealedHeader<Client::Header>>
where
Client: HeadersClient<Header: reth_primitives_traits::BlockHeader>,
{
let (peer_id, response) = client.get_header_with_priority(id, Priority::High).await?.split();
let Some(header) = response else {
client.report_bad_message(peer_id);
eyre::bail!("Invalid number of headers received. Expected: 1. Received: 0")
};
let header = SealedHeader::seal(header);
let valid = match id {
BlockHashOrNumber::Hash(hash) => header.hash() == hash,
BlockHashOrNumber::Number(number) => header.number() == number,
};
if !valid {
client.report_bad_message(peer_id);
eyre::bail!(
"Received invalid header. Received: {:?}. Expected: {:?}",
header.num_hash(),
id
);
}
Ok(header)
}
pub async fn get_single_body<H, Client>(
client: Client,
header: SealedHeader<H>,
consensus: impl Consensus<H, Client::Body>,
) -> Result<SealedBlock<H, Client::Body>>
where
Client: BodiesClient,
{
let (peer_id, response) = client.get_block_body(header.hash()).await?.split();
let Some(body) = response else {
client.report_bad_message(peer_id);
eyre::bail!("Invalid number of bodies received. Expected: 1. Received: 0")
};
let block = SealedBlock { header, body };
consensus.validate_block_pre_execution(&block)?;
Ok(block)
}