This repository has been archived by the owner on Dec 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
VerifyStage: headers validation using preferified hashes. (#27)
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 When we have a HeaderSlice and need to verify it, the algorithm verifies that the top of the slice matches one of the preverified hashes, and that all blocks down to the root of the slice are properly connected by the parent_hash field. For example, if we have a HeaderSlice[192...384] (with block headers from 192 to 384 inclusive), it verifies that: hash(slice[384]) == preverified hash(384) hash(slice[383]) == slice[384].parent_hash hash(slice[382]) == slice[383].parent_hash ... hash(slice[192]) == slice[193].parent_hash Thus verifying hashes of all the headers.
- Loading branch information
1 parent
785dca2
commit 490a90b
Showing
6 changed files
with
120,926 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
Oops, something went wrong.