support exclusion proofs ending at leaf

This commit is contained in:
Noah Citron 2022-08-26 18:13:35 -04:00
parent e18aa704e1
commit e0beceb8dd
3 changed files with 23 additions and 8 deletions

View File

@ -1,5 +1,3 @@
use std::sync::Arc;
use ethers::prelude::{Address, U256}; use ethers::prelude::{Address, U256};
use eyre::Result; use eyre::Result;
@ -10,7 +8,7 @@ use crate::execution::ExecutionClient;
pub struct Client { pub struct Client {
consensus: ConsensusClient, consensus: ConsensusClient,
execution: Arc<ExecutionClient>, execution: ExecutionClient,
} }
impl Client { impl Client {
@ -24,7 +22,7 @@ impl Client {
Ok(Client { Ok(Client {
consensus, consensus,
execution: Arc::new(execution), execution,
}) })
} }

View File

@ -1,4 +1,4 @@
use std::{str::FromStr, sync::Arc, thread}; use std::{str::FromStr, thread};
use bytes::Bytes; use bytes::Bytes;
use ethers::prelude::{Address, H160, H256, U256}; use ethers::prelude::{Address, H160, H256, U256};
@ -14,7 +14,7 @@ pub struct Evm {
} }
impl Evm { impl Evm {
pub fn new(execution: Arc<ExecutionClient>, payload: ExecutionPayload) -> Self { pub fn new(execution: ExecutionClient, payload: ExecutionPayload) -> Self {
let mut evm: EVM<ProofDB> = EVM::new(); let mut evm: EVM<ProofDB> = EVM::new();
let db = ProofDB::new(execution, payload); let db = ProofDB::new(execution, payload);
evm.database(db); evm.database(db);
@ -47,13 +47,13 @@ impl Evm {
} }
struct ProofDB { struct ProofDB {
execution: Arc<ExecutionClient>, execution: ExecutionClient,
payload: ExecutionPayload, payload: ExecutionPayload,
error: Option<String>, error: Option<String>,
} }
impl ProofDB { impl ProofDB {
pub fn new(execution: Arc<ExecutionClient>, payload: ExecutionPayload) -> Self { pub fn new(execution: ExecutionClient, payload: ExecutionPayload) -> Self {
ProofDB { ProofDB {
execution, execution,
payload, payload,

View File

@ -7,6 +7,7 @@ pub fn verify_proof(proof: &Vec<Vec<u8>>, root: &Vec<u8>, path: &Vec<u8>, value:
let mut expected_hash = root.clone(); let mut expected_hash = root.clone();
let mut path_offset = 0; let mut path_offset = 0;
for (i, node) in proof.iter().enumerate() { for (i, node) in proof.iter().enumerate() {
if expected_hash != keccak256(node).to_vec() { if expected_hash != keccak256(node).to_vec() {
return false; return false;
@ -21,6 +22,13 @@ pub fn verify_proof(proof: &Vec<Vec<u8>>, root: &Vec<u8>, path: &Vec<u8>, value:
path_offset += 1; path_offset += 1;
} else if node_list.len() == 2 { } else if node_list.len() == 2 {
if i == proof.len() - 1 { if i == proof.len() - 1 {
// exclusion proof
if &node_list[0][skip_length(&node_list[0])..] != &path[path_offset..] && value[0] == 0x80 {
return true
}
// inclusion proof
if &node_list[1] != value { if &node_list[1] != value {
return false; return false;
} }
@ -35,6 +43,15 @@ pub fn verify_proof(proof: &Vec<Vec<u8>>, root: &Vec<u8>, path: &Vec<u8>, value:
true true
} }
fn skip_length(node: &Vec<u8>) -> usize {
let nibble = get_nibble(node, 0);
match nibble {
2 => 2,
3 => 1,
_ => 0,
}
}
fn get_nibble(path: &Vec<u8>, offset: usize) -> u8 { fn get_nibble(path: &Vec<u8>, offset: usize) -> u8 {
let byte = path[offset / 2]; let byte = path[offset / 2];
if offset % 2 == 0 { if offset % 2 == 0 {