add proof helpers

This commit is contained in:
Noah Citron 2022-08-18 20:33:44 -04:00
parent 32603f56c3
commit f71bff19f6
4 changed files with 1967 additions and 19 deletions

1904
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -13,3 +13,5 @@ serde = { version = "1.0.143", features = ["derive"] }
hex = "0.4.3" hex = "0.4.3"
ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs" } ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs" }
blst = "0.3.10" blst = "0.3.10"
ethers = "0.17.0"
jsonrpsee = { version = "0.15.1", features = ["full"] }

View File

@ -3,22 +3,28 @@ use ssz_rs::prelude::*;
use blst::{min_pk::*, BLST_ERROR}; use blst::{min_pk::*, BLST_ERROR};
use consensus_client::*; use consensus_client::*;
use utils::*; use utils::*;
use proof::*;
pub mod consensus_client; pub mod consensus_client;
pub mod utils; pub mod utils;
pub mod proof;
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
let mut client = LightClient::new( // let mut client = LightClient::new(
"http://testing.prater.beacon-api.nimbus.team", // "http://testing.prater.beacon-api.nimbus.team",
"0x172128eadf1da46467f4d6a822206698e2d3f957af117dd650954780d680dc99" // "0x172128eadf1da46467f4d6a822206698e2d3f957af117dd650954780d680dc99"
).await?; // ).await?;
//
// client.sync().await?;
client.sync().await?; // let payload = client.get_execution_payload().await?;
// println!("verified execution block hash: {}", hex::encode(payload.block_hash));
let payload = client.get_execution_payload().await?; let proof = get_proof("0xf6401adc23Faa6B9AD83eA8604CA7254CB7F53e7", 15365978).await?;
println!("verified execution block hash: {}", hex::encode(payload.block_hash)); verify(&proof)?;
// println!("{:?}", proof);
Ok(()) Ok(())
} }

58
src/proof.rs Normal file
View File

@ -0,0 +1,58 @@
use ethers::utils::keccak256;
use eyre::Result;
use serde::Deserialize;
use serde::de::Error;
use jsonrpsee::{http_client::HttpClientBuilder, rpc_params, core::client::ClientT};
use ethers::utils::rlp::RlpStream;
use ethers::prelude::{U256, H256, Address};
use super::utils::hex_str_to_bytes;
pub async fn get_proof(address: &str, block: u64) -> Result<Proof> {
let rpc = "https://eth-mainnet.g.alchemy.com:443/v2/sUiZsY3BSTYXjSHIvPc9rGDipR7lAlT4";
let client = HttpClientBuilder::default().build(rpc)?;
let block_hex = format!("0x{:x}", block);
let params = rpc_params!(address, [""], block_hex);
Ok(client.request("eth_getProof", params).await?)
}
pub fn verify(proof: &Proof) -> Result<()> {
let account_encoded = encode_account(proof);
println!("{:?}", account_encoded);
let state_root = hex_str_to_bytes("0xeb5eb01bd4f503a5698d136c75b37ef2660d6842bf77d0453f2a7fa4a6780d91")?;
let address_hash = keccak256(proof.address);
Ok(())
}
fn encode_account(proof: &Proof) -> Vec<u8> {
let mut stream = RlpStream::new_list(4);
stream.append(&proof.nonce);
stream.append(&proof.balance);
stream.append(&proof.storage_hash);
stream.append(&proof.code_hash);
let encoded = stream.out();
encoded.to_vec()
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Proof {
address: Address,
balance: U256,
code_hash: H256,
nonce: U256,
storage_hash: H256,
#[serde(deserialize_with = "proof_deserialize")]
account_proof: Vec<Vec<u8>>,
}
fn proof_deserialize<'de, D>(deserializer: D) -> Result<Vec<Vec<u8>>, D::Error> where D: serde::Deserializer<'de> {
let branch: Vec<String> = serde::Deserialize::deserialize(deserializer)?;
Ok(branch.iter().map(|elem| {
hex_str_to_bytes(elem)
}).collect::<Result<_>>().map_err(D::Error::custom)?)
}