Skip to content
This repository has been archived by the owner on Dec 2, 2022. It is now read-only.

VerifyStage: headers validation using preferified hashes. #27

Merged
merged 3 commits into from
Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/downloader/downloader_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use crate::downloader::{
chain_config::{ChainConfig, ChainsConfig},
headers::{
fetch_receive_stage::FetchReceiveStage, fetch_request_stage::FetchRequestStage,
header_slices::HeaderSlices, refill_stage::RefillStage, retry_stage::RetryStage,
save_stage::SaveStage, verify_stage::VerifyStage,
header_slices::HeaderSlices, preverified_hashes_config::PreverifiedHashesConfig,
refill_stage::RefillStage, retry_stage::RetryStage, save_stage::SaveStage,
verify_stage::VerifyStage,
},
opts::Opts,
sentry_client,
Expand Down Expand Up @@ -79,7 +80,10 @@ impl Downloader {

let retry_stage = RetryStage::new(Arc::clone(&header_slices));

let verify_stage = VerifyStage::new(Arc::clone(&header_slices));
let verify_stage = VerifyStage::new(
Arc::clone(&header_slices),
PreverifiedHashesConfig::new(&self.opts.chain_name)?,
);

let save_stage = SaveStage::new(Arc::clone(&header_slices));

Expand Down
2 changes: 2 additions & 0 deletions src/downloader/headers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod header_slices;

pub mod fetch_receive_stage;
pub mod fetch_request_stage;
pub mod preverified_hashes_config;
pub mod refill_stage;
pub mod retry_stage;
pub mod save_stage;
Expand All @@ -14,5 +15,6 @@ pub use ui_crossterm::HeaderSlicesView;

#[cfg(not(feature = "crossterm"))]
pub mod ui_tracing;

#[cfg(not(feature = "crossterm"))]
pub use ui_tracing::HeaderSlicesView;
56 changes: 56 additions & 0 deletions src/downloader/headers/preverified_hashes_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use serde::{de, Deserialize};
use std::str::FromStr;

/// The preverified hashes is a list of known precomputed hashes of every 192-th block in the chain:
///
/// hash(0), hash(192), hash(384), hash(576), ...
///
/// The preverified hashes are copied from:
/// https://github.com/ledgerwatch/erigon/blob/devel/turbo/stages/headerdownload/preverified_hashes_mainnet.go
/// https://github.com/ledgerwatch/erigon/blob/devel/turbo/stages/headerdownload/preverified_hashes_ropsten.go
pub struct PreverifiedHashesConfig {
pub hashes: Vec<ethereum_types::H256>,
}

struct UnprefixedHexH256(pub ethereum_types::H256);

#[derive(Deserialize)]
struct PreverifiedHashesConfigUnprefixedHex {
pub hashes: Vec<UnprefixedHexH256>,
}

impl PreverifiedHashesConfig {
pub fn new(chain_name: &str) -> anyhow::Result<Self> {
let config_text = match chain_name {
"mainnet" => include_str!("preverified_hashes_mainnet.toml"),
"ropsten" => include_str!("preverified_hashes_ropsten.toml"),
_ => anyhow::bail!("unsupported chain"),
};
let config: PreverifiedHashesConfigUnprefixedHex = toml::from_str(config_text)?;
Ok(PreverifiedHashesConfig {
hashes: config.hashes.iter().map(|hash| hash.0).collect(),
})
}
}

impl FromStr for UnprefixedHexH256 {
type Err = hex::FromHexError;

fn from_str(hash_str: &str) -> Result<Self, Self::Err> {
let mut hash_bytes = [0u8; 32];
hex::decode_to_slice(hash_str, &mut hash_bytes)?;
let hash = ethereum_types::H256::from(hash_bytes);

Ok(UnprefixedHexH256(hash))
}
}

impl<'de> Deserialize<'de> for UnprefixedHexH256 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
let hash_str = String::deserialize(deserializer)?;
FromStr::from_str(&hash_str).map_err(de::Error::custom)
}
}
Loading