diff --git a/src/consensus.rs b/src/consensus.rs index 37220e9..636794b 100644 --- a/src/consensus.rs +++ b/src/consensus.rs @@ -1,10 +1,10 @@ -use eyre::Result; -use ssz_rs::prelude::*; use blst::min_pk::{PublicKey, Signature}; use blst::BLST_ERROR; +use eyre::Result; +use ssz_rs::prelude::*; -use super::consensus_rpc::*; -use super::utils::*; +use crate::consensus_rpc::*; +use crate::utils::*; pub struct ConsensusClient { consensus_rpc: ConsensusRpc, @@ -20,7 +20,6 @@ struct Store { impl ConsensusClient { pub async fn new(nimbus_rpc: &str, checkpoint_block_root: &str) -> Result { - let consensus_rpc = ConsensusRpc::new(nimbus_rpc); let mut bootstrap = consensus_rpc.get_bootstrap(checkpoint_block_root).await?; @@ -28,7 +27,7 @@ impl ConsensusClient { let committee_valid = is_current_committee_proof_valid( &bootstrap.header, &mut bootstrap.current_sync_committee, - &bootstrap.current_sync_committee_branch + &bootstrap.current_sync_committee_branch, ); let header_hash = bootstrap.header.hash_tree_root()?; @@ -44,7 +43,10 @@ impl ConsensusClient { next_sync_committee: None, }; - Ok(ConsensusClient { consensus_rpc, store }) + Ok(ConsensusClient { + consensus_rpc, + store, + }) } pub async fn get_execution_payload(&mut self) -> Result { @@ -52,7 +54,7 @@ impl ConsensusClient { let mut block = self.consensus_rpc.get_block(slot).await?; let block_hash = block.hash_tree_root()?; let verified_block_hash = self.store.header.hash_tree_root()?; - + if verified_block_hash != block_hash { Err(eyre::eyre!("Block Root Mismatch")) } else { @@ -61,7 +63,6 @@ impl ConsensusClient { } pub async fn sync(&mut self) -> Result<()> { - let current_period = calc_sync_period(self.store.header.slot); let updates = self.consensus_rpc.get_updates(current_period).await?; @@ -85,7 +86,7 @@ impl ConsensusClient { self.apply_update(&finality_update_generic); println!("synced up to slot: {}", self.store.header.slot); - + self.consensus_rpc.get_block(self.store.header.slot).await?; Ok(()) @@ -94,7 +95,7 @@ impl ConsensusClient { fn verify_update(&mut self, update: &mut Update) -> Result<()> { let current_slot = self.store.header.slot; let update_slot = update.finalized_header.slot; - + let current_period = calc_sync_period(current_slot); let update_period = calc_sync_period(update_slot); @@ -102,14 +103,16 @@ impl ConsensusClient { return Err(eyre::eyre!("Invalid Update")); } - if !(update.signature_slot > update.attested_header.slot && update.attested_header.slot > update.finalized_header.slot) { + if !(update.signature_slot > update.attested_header.slot + && update.attested_header.slot > update.finalized_header.slot) + { return Err(eyre::eyre!("Invalid Update")); } let finality_branch_valid = is_finality_proof_valid( &update.attested_header, &mut update.finalized_header, - &update.finality_branch + &update.finality_branch, ); if !(finality_branch_valid) { @@ -120,7 +123,7 @@ impl ConsensusClient { let next_committee_branch_valid = is_next_committee_proof_valid( &update.attested_header, &mut update.next_sync_committee.clone().unwrap(), - &update.next_sync_committee_branch + &update.next_sync_committee_branch, ); if !next_committee_branch_valid { @@ -134,7 +137,8 @@ impl ConsensusClient { self.store.next_sync_committee.as_ref().unwrap() }; - let pks = get_participating_keys(sync_committee, &update.sync_aggregate.sync_committee_bits)?; + let pks = + get_participating_keys(sync_committee, &update.sync_aggregate.sync_committee_bits)?; let pks: Vec<&PublicKey> = pks.iter().map(|pk| pk).collect(); let committee_quorum = pks.len() > 1; @@ -155,32 +159,37 @@ impl ConsensusClient { } fn apply_update(&mut self, update: &Update) { - let current_period = calc_sync_period(self.store.header.slot); let update_period = calc_sync_period(update.finalized_header.slot); self.store.header = update.finalized_header.clone(); if self.store.next_sync_committee.is_none() { - self.store.next_sync_committee = Some(update.next_sync_committee.as_ref().unwrap().clone()); + self.store.next_sync_committee = + Some(update.next_sync_committee.as_ref().unwrap().clone()); } else if update_period == current_period + 1 { - self.store.current_sync_committee = self.store.next_sync_committee.as_ref().unwrap().clone(); - self.store.next_sync_committee = Some(update.next_sync_committee.as_ref().unwrap().clone()); + self.store.current_sync_committee = + self.store.next_sync_committee.as_ref().unwrap().clone(); + self.store.next_sync_committee = + Some(update.next_sync_committee.as_ref().unwrap().clone()); } } } -fn get_participating_keys(committee: &SyncCommittee, bitfield: &Bitvector<512>) -> Result> { - let mut pks: Vec = Vec::new(); - bitfield.iter().enumerate().for_each(|(i, bit)| { - if bit == true { - let pk = &committee.pubkeys[i]; - let pk = PublicKey::from_bytes(&pk).unwrap(); - pks.push(pk); - } - }); +fn get_participating_keys( + committee: &SyncCommittee, + bitfield: &Bitvector<512>, +) -> Result> { + let mut pks: Vec = Vec::new(); + bitfield.iter().enumerate().for_each(|(i, bit)| { + if bit == true { + let pk = &committee.pubkeys[i]; + let pk = PublicKey::from_bytes(&pk).unwrap(); + pks.push(pk); + } + }); - Ok(pks) + Ok(pks) } fn is_aggregate_valid(sig_bytes: &SignatureBytes, msg: &[u8], pks: &[&PublicKey]) -> bool { @@ -192,35 +201,39 @@ fn is_aggregate_valid(sig_bytes: &SignatureBytes, msg: &[u8], pks: &[&PublicKey] } } -fn is_finality_proof_valid(attested_header: &Header, finality_header: &mut Header, finality_branch: &Vec) -> bool { - let finality_header_hash_res = finality_header.hash_tree_root(); - if finality_header_hash_res.is_err() { - return false; - } +fn is_finality_proof_valid( + attested_header: &Header, + finality_header: &mut Header, + finality_branch: &Vec, +) -> bool { + let finality_header_hash_res = finality_header.hash_tree_root(); + if finality_header_hash_res.is_err() { + return false; + } - let attested_header_state_root_res = bytes32_to_node(&attested_header.state_root); - if attested_header_state_root_res.is_err() { - return false; - } + let attested_header_state_root_res = bytes32_to_node(&attested_header.state_root); + if attested_header_state_root_res.is_err() { + return false; + } - let finality_branch_res = branch_to_nodes(finality_branch.clone()); - if finality_branch_res.is_err() { - return false; - } + let finality_branch_res = branch_to_nodes(finality_branch.clone()); + if finality_branch_res.is_err() { + return false; + } - is_valid_merkle_branch( - &finality_header_hash_res.unwrap(), - finality_branch_res.unwrap().iter(), - 6, - 41, - &attested_header_state_root_res.unwrap() - ) + is_valid_merkle_branch( + &finality_header_hash_res.unwrap(), + finality_branch_res.unwrap().iter(), + 6, + 41, + &attested_header_state_root_res.unwrap(), + ) } fn is_next_committee_proof_valid( attested_header: &Header, next_committee: &mut SyncCommittee, - next_committee_branch: &Vec + next_committee_branch: &Vec, ) -> bool { let next_committee_hash_res = next_committee.hash_tree_root(); if next_committee_hash_res.is_err() { @@ -242,14 +255,14 @@ fn is_next_committee_proof_valid( next_committee_branch_res.unwrap().iter(), 5, 23, - &attested_header_state_root_res.unwrap() + &attested_header_state_root_res.unwrap(), ) } fn is_current_committee_proof_valid( attested_header: &Header, current_committee: &mut SyncCommittee, - current_committee_branch: &Vec + current_committee_branch: &Vec, ) -> bool { let next_committee_hash_res = current_committee.hash_tree_root(); if next_committee_hash_res.is_err() { @@ -271,7 +284,7 @@ fn is_current_committee_proof_valid( next_committee_branch_res.unwrap().iter(), 5, 22, - &attested_header_state_root_res.unwrap() + &attested_header_state_root_res.unwrap(), ) } @@ -281,11 +294,18 @@ fn calc_sync_period(slot: u64) -> u64 { } fn branch_to_nodes(branch: Vec) -> Result> { - branch.iter().map(|elem| bytes32_to_node(elem)).collect::>>() + branch + .iter() + .map(|elem| bytes32_to_node(elem)) + .collect::>>() } fn compute_committee_sign_root(header: Bytes32) -> Result { - let genesis_root = hex::decode("043db0d9a83813551ee2f33450d23797757d430911a9320530ad8a0eabc43efb")?.to_vec().try_into().unwrap(); + let genesis_root = + hex::decode("043db0d9a83813551ee2f33450d23797757d430911a9320530ad8a0eabc43efb")? + .to_vec() + .try_into() + .unwrap(); let domain_type = &hex::decode("07000000")?[..]; let fork_version = Vector::from_iter(hex::decode("02001020").unwrap()); let domain = compute_domain(domain_type, fork_version, genesis_root)?; @@ -295,7 +315,7 @@ fn compute_committee_sign_root(header: Bytes32) -> Result { #[derive(SimpleSerialize, Default, Debug)] struct SigningData { object_root: Bytes32, - domain: Bytes32 + domain: Bytes32, } #[derive(SimpleSerialize, Default, Debug)] @@ -305,11 +325,18 @@ struct ForkData { } fn compute_signing_root(object_root: Bytes32, domain: Bytes32) -> Result { - let mut data = SigningData { object_root, domain }; + let mut data = SigningData { + object_root, + domain, + }; Ok(data.hash_tree_root()?) } -fn compute_domain(domain_type: &[u8], fork_version: Vector, genesis_root: Bytes32) -> Result { +fn compute_domain( + domain_type: &[u8], + fork_version: Vector, + genesis_root: Bytes32, +) -> Result { let fork_data_root = compute_fork_data_root(fork_version, genesis_root)?; let start = domain_type; let end = &fork_data_root.as_bytes()[..28]; @@ -317,9 +344,14 @@ fn compute_domain(domain_type: &[u8], fork_version: Vector, genesis_root: Ok(d.to_vec().try_into().unwrap()) } -fn compute_fork_data_root(current_version: Vector, genesis_validator_root: Bytes32) -> Result { +fn compute_fork_data_root( + current_version: Vector, + genesis_validator_root: Bytes32, +) -> Result { let current_version = current_version.try_into()?; - let mut fork_data = ForkData { current_version, genesis_validator_root }; + let mut fork_data = ForkData { + current_version, + genesis_validator_root, + }; Ok(fork_data.hash_tree_root()?) } - diff --git a/src/consensus_rpc.rs b/src/consensus_rpc.rs index 026635f..4d78b70 100644 --- a/src/consensus_rpc.rs +++ b/src/consensus_rpc.rs @@ -1,7 +1,8 @@ use eyre::Result; -use ssz_rs::prelude::*; -use super::utils::*; use serde::de::Error; +use ssz_rs::prelude::*; + +use crate::utils::*; pub struct ConsensusRpc { rpc: String, @@ -9,30 +10,44 @@ pub struct ConsensusRpc { impl ConsensusRpc { pub fn new(rpc: &str) -> Self { - ConsensusRpc { rpc: rpc.to_string() } + ConsensusRpc { + rpc: rpc.to_string(), + } } pub async fn get_bootstrap(&self, block_root: &str) -> Result { - let req = format!("{}/eth/v0/beacon/light_client/bootstrap/{}", self.rpc, block_root); + let req = format!( + "{}/eth/v0/beacon/light_client/bootstrap/{}", + self.rpc, block_root + ); let res = reqwest::get(req).await?.json::().await?; Ok(res.data.v) } pub async fn get_updates(&self, period: u64) -> Result> { - let req = format!("{}/eth/v0/beacon/light_client/updates?start_period={}&count=1000", self.rpc, period); + let req = format!( + "{}/eth/v0/beacon/light_client/updates?start_period={}&count=1000", + self.rpc, period + ); let res = reqwest::get(req).await?.json::().await?; Ok(res.data) } pub async fn get_finality_update(&self) -> Result { let req = format!("{}/eth/v0/beacon/light_client/finality_update", self.rpc); - let res = reqwest::get(req).await?.json::().await?; + let res = reqwest::get(req) + .await? + .json::() + .await?; Ok(res.data) } - pub async fn get_block(&self, slot: u64) -> Result{ + pub async fn get_block(&self, slot: u64) -> Result { let req = format!("{}/eth/v2/beacon/blocks/{}", self.rpc, slot); - let res = reqwest::get(req).await?.json::().await?; + let res = reqwest::get(req) + .await? + .json::() + .await?; Ok(res.data.message) } } @@ -99,7 +114,7 @@ pub struct ExecutionPayload { gas_used: u64, #[serde(deserialize_with = "u64_deserialize")] timestamp: u64, - #[serde(deserialize_with ="extra_data_deserialize")] + #[serde(deserialize_with = "extra_data_deserialize")] extra_data: List, #[serde(deserialize_with = "u256_deserialize")] base_fee_per_gas: U256, @@ -147,7 +162,7 @@ pub struct Eth1Data { #[serde(deserialize_with = "bytes32_deserialize")] deposit_root: Bytes32, #[serde(deserialize_with = "u64_deserialize")] - deposit_count: u64, + deposit_count: u64, #[serde(deserialize_with = "bytes32_deserialize")] block_hash: Bytes32, } @@ -244,76 +259,120 @@ struct BootstrapData { v: Bootstrap, } -fn pubkey_deserialize<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de> { +fn pubkey_deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ let key: String = serde::Deserialize::deserialize(deserializer)?; let key_bytes = hex_str_to_bytes(&key).map_err(D::Error::custom)?; Ok(Vector::from_iter(key_bytes)) } -fn pubkeys_deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de> { +fn pubkeys_deserialize<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ let keys: Vec = serde::Deserialize::deserialize(deserializer)?; - Ok(keys.iter().map(|key| { - let key_bytes = hex_str_to_bytes(key)?; - Ok(Vector::from_iter(key_bytes)) - }).collect::>>().map_err(D::Error::custom)?) + Ok(keys + .iter() + .map(|key| { + let key_bytes = hex_str_to_bytes(key)?; + Ok(Vector::from_iter(key_bytes)) + }) + .collect::>>() + .map_err(D::Error::custom)?) } -fn signature_deserialize<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de> { +fn signature_deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ let sig: String = serde::Deserialize::deserialize(deserializer)?; let sig_bytes = hex_str_to_bytes(&sig).map_err(D::Error::custom)?; Ok(Vector::from_iter(sig_bytes)) } -fn branch_deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de> { +fn branch_deserialize<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ let branch: Vec = serde::Deserialize::deserialize(deserializer)?; - Ok(branch.iter().map(|elem| { - let elem_bytes = hex_str_to_bytes(elem)?; - Ok(Vector::from_iter(elem_bytes)) - }).collect::>().map_err(D::Error::custom)?) + Ok(branch + .iter() + .map(|elem| { + let elem_bytes = hex_str_to_bytes(elem)?; + Ok(Vector::from_iter(elem_bytes)) + }) + .collect::>() + .map_err(D::Error::custom)?) } -fn u64_deserialize<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de> { +fn u64_deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ let val: String = serde::Deserialize::deserialize(deserializer)?; Ok(val.parse().unwrap()) } -fn u256_deserialize<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de> { +fn u256_deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ let val: String = serde::Deserialize::deserialize(deserializer)?; // TODO: support larger values let i = val.parse::().map_err(D::Error::custom)?; Ok(U256::from(i)) } -fn bytes32_deserialize<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de> { +fn bytes32_deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ let bytes: String = serde::Deserialize::deserialize(deserializer)?; let bytes = hex::decode(bytes.strip_prefix("0x").unwrap()).unwrap(); Ok(bytes.to_vec().try_into().unwrap()) } -fn logs_bloom_deserialize<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de> { +fn logs_bloom_deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ let bytes: String = serde::Deserialize::deserialize(deserializer)?; let bytes = hex::decode(bytes.strip_prefix("0x").unwrap()).unwrap(); Ok(bytes.to_vec().try_into().unwrap()) } -fn address_deserialize<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de> { +fn address_deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ let bytes: String = serde::Deserialize::deserialize(deserializer)?; let bytes = hex::decode(bytes.strip_prefix("0x").unwrap()).unwrap(); Ok(bytes.to_vec().try_into().unwrap()) } -fn extra_data_deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de> { +fn extra_data_deserialize<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ let bytes: String = serde::Deserialize::deserialize(deserializer)?; let bytes = hex::decode(bytes.strip_prefix("0x").unwrap()).unwrap(); Ok(bytes.to_vec().try_into().unwrap()) } -fn transactions_deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de> { +fn transactions_deserialize<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ let transactions: Vec = serde::Deserialize::deserialize(deserializer)?; - let transactions = transactions.iter().map(|tx| { - let tx = hex_str_to_bytes(tx).unwrap(); - let tx: Transaction = List::from_iter(tx); - tx - }).collect::>(); + let transactions = transactions + .iter() + .map(|tx| { + let tx = hex_str_to_bytes(tx).unwrap(); + let tx: Transaction = List::from_iter(tx); + tx + }) + .collect::>(); Ok(transactions) } diff --git a/src/execution.rs b/src/execution.rs index fdf7f42..75790bc 100644 --- a/src/execution.rs +++ b/src/execution.rs @@ -1,13 +1,13 @@ +use ethers::prelude::{Address, U256}; use ethers::utils::keccak256; use eyre::Result; -use ethers::prelude::{U256, Address}; -use crate::proof::{encode_account, verify_proof}; use crate::consensus_rpc::ExecutionPayload; use crate::execution_rpc::ExecutionRpc; +use crate::proof::{encode_account, verify_proof}; pub struct ExecutionClient { - execution_rpc: ExecutionRpc + execution_rpc: ExecutionRpc, } impl ExecutionClient { @@ -17,12 +17,20 @@ impl ExecutionClient { } pub async fn get_balance(&self, account: &Address, payload: &ExecutionPayload) -> Result { - let proof = self.execution_rpc.get_proof(&account, payload.block_number).await?; + let proof = self + .execution_rpc + .get_proof(&account, payload.block_number) + .await?; let account_path = keccak256(account.as_bytes()).to_vec(); let account_encoded = encode_account(&proof); - let is_valid = verify_proof(&proof.account_proof, &payload.state_root, &account_path, &account_encoded); + let is_valid = verify_proof( + &proof.account_proof, + &payload.state_root, + &account_path, + &account_encoded, + ); if !is_valid { eyre::bail!("Invalid Proof"); diff --git a/src/execution_rpc.rs b/src/execution_rpc.rs index 2f07e3b..5fd2b07 100644 --- a/src/execution_rpc.rs +++ b/src/execution_rpc.rs @@ -1,9 +1,10 @@ -use ethers::prelude::{Address, U256, H256}; -use jsonrpsee::{http_client::HttpClientBuilder, rpc_params, core::client::ClientT}; +use ethers::prelude::{Address, H256, U256}; use eyre::Result; -use serde::Deserialize; +use jsonrpsee::{core::client::ClientT, http_client::HttpClientBuilder, rpc_params}; use serde::de::Error; -use super::utils::*; +use serde::Deserialize; + +use crate::utils::hex_str_to_bytes; pub struct ExecutionRpc { rpc: String, @@ -11,7 +12,9 @@ pub struct ExecutionRpc { impl ExecutionRpc { pub fn new(rpc: &str) -> Self { - ExecutionRpc { rpc: rpc.to_string() } + ExecutionRpc { + rpc: rpc.to_string(), + } } pub async fn get_proof(&self, address: &Address, block: u64) -> Result { @@ -35,10 +38,14 @@ pub struct Proof { pub account_proof: Vec>, } -fn proof_deserialize<'de, D>(deserializer: D) -> Result>, D::Error> where D: serde::Deserializer<'de> { +fn proof_deserialize<'de, D>(deserializer: D) -> Result>, D::Error> +where + D: serde::Deserializer<'de>, +{ let branch: Vec = serde::Deserialize::deserialize(deserializer)?; - Ok(branch.iter().map(|elem| { - hex_str_to_bytes(elem) - }).collect::>().map_err(D::Error::custom)?) + Ok(branch + .iter() + .map(|elem| hex_str_to_bytes(elem)) + .collect::>() + .map_err(D::Error::custom)?) } - diff --git a/src/main.rs b/src/main.rs index ab465c8..86f90f1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,23 +10,25 @@ pub mod consensus; pub mod consensus_rpc; pub mod execution; pub mod execution_rpc; -pub mod utils; pub mod proof; +pub mod utils; #[tokio::main] async fn main() -> Result<()> { - let rpc = "http://testing.prater.beacon-api.nimbus.team"; let checkpoint = "0x172128eadf1da46467f4d6a822206698e2d3f957af117dd650954780d680dc99"; - let mut client = ConsensusClient::new(rpc, checkpoint).await?; - + let mut client = ConsensusClient::new(rpc, checkpoint).await?; + let rpc = "https://eth-goerli.g.alchemy.com:443/v2/o_8Qa9kgwDPf9G8sroyQ-uQtyhyWa3ao"; let execution = ExecutionClient::new(rpc); - + client.sync().await?; let payload = client.get_execution_payload().await?; - println!("verified execution block hash: {}", hex::encode(&payload.block_hash)); + println!( + "verified execution block hash: {}", + hex::encode(&payload.block_hash) + ); let addr = Address::from_str("0x25c4a76E7d118705e7Ea2e9b7d8C59930d8aCD3b")?; let balance = execution.get_balance(&addr, &payload).await?; @@ -34,4 +36,3 @@ async fn main() -> Result<()> { Ok(()) } - diff --git a/src/proof.rs b/src/proof.rs index 15771f0..e9f414c 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -1,9 +1,9 @@ use ethers::utils::keccak256; -use ethers::utils::rlp::{RlpStream, decode_list}; -use super::execution_rpc::Proof; +use ethers::utils::rlp::{decode_list, RlpStream}; + +use crate::execution_rpc::Proof; pub fn verify_proof(proof: &Vec>, root: &Vec, path: &Vec, value: &Vec) -> bool { - let mut expected_hash = root.clone(); let mut path_offset = 0; @@ -13,14 +13,12 @@ pub fn verify_proof(proof: &Vec>, root: &Vec, path: &Vec, value: } let node_list: Vec> = decode_list(node); - - if node_list.len() == 17 { + if node_list.len() == 17 { let nibble = get_nibble(&path, path_offset); expected_hash = node_list[nibble as usize].clone(); path_offset += 1; - } else if node_list.len() == 2 { if i == proof.len() - 1 { if &node_list[1] != value { @@ -59,4 +57,3 @@ pub fn encode_account(proof: &Proof) -> Vec { pub fn get_account_path(addr: &Vec) -> Vec { keccak256(addr).to_vec() } - diff --git a/src/utils.rs b/src/utils.rs index cbc85db..708f92d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,7 @@ use eyre::Result; use ssz_rs::{Node, Vector}; -use super::consensus_rpc::Bytes32; + +use crate::consensus_rpc::Bytes32; pub fn hex_str_to_bytes(s: &str) -> Result> { let stripped = s.strip_prefix("0x").unwrap_or(s);