add execution module

This commit is contained in:
Noah Citron 2022-08-20 13:18:40 -04:00
parent 4dd8ba253f
commit a441bde2c8
3 changed files with 46 additions and 16 deletions

33
src/execution.rs Normal file
View File

@ -0,0 +1,33 @@
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;
pub struct ExecutionClient {
execution_rpc: ExecutionRpc
}
impl ExecutionClient {
pub fn new(rpc: &str) -> Self {
let execution_rpc = ExecutionRpc::new(rpc);
ExecutionClient { execution_rpc }
}
pub async fn get_balance(&self, account: &Address, payload: &ExecutionPayload) -> Result<U256> {
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);
if !is_valid {
eyre::bail!("Invalid Proof");
}
Ok(proof.balance)
}
}

View File

@ -14,10 +14,11 @@ impl ExecutionRpc {
ExecutionRpc { rpc: rpc.to_string() }
}
pub async fn get_proof(&self, address: &str, block: u64) -> Result<Proof> {
pub async fn get_proof(&self, address: &Address, block: u64) -> Result<Proof> {
let client = HttpClientBuilder::default().build(&self.rpc)?;
let block_hex = format!("0x{:x}", block);
let params = rpc_params!(address, [""], block_hex);
let addr_hex = format!("0x{}", hex::encode(address.as_bytes()));
let params = rpc_params!(addr_hex, [""], block_hex);
Ok(client.request("eth_getProof", params).await?)
}
}

View File

@ -1,12 +1,14 @@
use std::str::FromStr;
use ethers::prelude::Address;
use eyre::Result;
use consensus::*;
use execution_rpc::*;
use proof::*;
use utils::hex_str_to_bytes;
use execution::*;
pub mod consensus;
pub mod consensus_rpc;
pub mod execution;
pub mod execution_rpc;
pub mod utils;
pub mod proof;
@ -19,22 +21,16 @@ async fn main() -> Result<()> {
let mut client = ConsensusClient::new(rpc, checkpoint).await?;
let rpc = "https://eth-goerli.g.alchemy.com:443/v2/o_8Qa9kgwDPf9G8sroyQ-uQtyhyWa3ao";
let execution = ExecutionRpc::new(rpc);
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 = "0x25c4a76E7d118705e7Ea2e9b7d8C59930d8aCD3b";
let proof = execution.get_proof(addr, payload.block_number).await?;
let account_path = get_account_path(&hex_str_to_bytes(addr)?);
let account_encoded = encode_account(&proof);
let is_valid = verify_proof(&proof.account_proof, &payload.state_root, &account_path, &account_encoded);
println!("is account proof valid: {}", is_valid);
let addr = Address::from_str("0x25c4a76E7d118705e7Ea2e9b7d8C59930d8aCD3b")?;
let balance = execution.get_balance(&addr, &payload).await?;
println!("verified account balance: {}", balance);
Ok(())
}