From fd87bfa7ba3ed57d94a268c94c424ff5b934982b Mon Sep 17 00:00:00 2001 From: Bartosz Nowak Date: Tue, 17 Dec 2024 13:31:19 +0100 Subject: [PATCH] proof fetcher & batching refactor --- crates/fetcher/src/main.rs | 8 +-- crates/fetcher/src/proof_keys.rs | 39 +++++++---- .../src/hint_processor/mod.rs | 3 - .../hint_processor/models/proofs/header.rs | 4 +- .../src/hint_processor/models/proofs/mmr.rs | 1 - .../src/hint_processor/models/proofs/mod.rs | 10 ++- .../lib/verifiers/evm/header_verifier.rs | 42 ++++++++--- .../src/hints/lib/verifiers/verify.rs | 70 +++++-------------- crates/hdp_hint_processor/src/hints/vars.rs | 1 + crates/provider/src/indexer/types.rs | 2 + src/types.cairo | 1 - src/utils/utils.cairo | 1 - src/verifiers/evm/header_verifier.cairo | 27 ++++--- src/verifiers/evm/verify.cairo | 31 ++++---- src/verifiers/mmr_verifier.cairo | 17 +++-- src/verifiers/starknet/header_verifier.cairo | 15 ++-- src/verifiers/verify.cairo | 46 ++---------- 17 files changed, 147 insertions(+), 171 deletions(-) diff --git a/crates/fetcher/src/main.rs b/crates/fetcher/src/main.rs index d5524e44..0d174223 100644 --- a/crates/fetcher/src/main.rs +++ b/crates/fetcher/src/main.rs @@ -3,7 +3,7 @@ use clap::{Parser, ValueHint}; use fetcher::{proof_keys::ProofKeys, FetcherError}; use hdp_hint_processor::{ - hint_processor::models::proofs::{account::Account, header::Header, mmr::MmrMeta, storage::Storage, Proofs}, + hint_processor::models::proofs::{account::Account, storage::Storage, HeaderMmrMeta, Proofs}, syscall_handler::evm::{self, dryrun::SyscallHandler}, }; use std::{collections::HashSet, fs, path::PathBuf}; @@ -44,7 +44,7 @@ fn main() -> Result<(), FetcherError> { .header_keys .iter() .map(ProofKeys::fetch_header_proof) - .collect::, FetcherError>>()?; + .collect::, FetcherError>>()?; let mut accounts: HashSet = HashSet::default(); @@ -52,7 +52,7 @@ fn main() -> Result<(), FetcherError> { .account_keys .iter() .map(ProofKeys::fetch_account_proof) - .collect::, FetcherError>>()? + .collect::, FetcherError>>()? .into_iter() { headers_with_mmr.insert(header_with_mmr); @@ -65,7 +65,7 @@ fn main() -> Result<(), FetcherError> { .storage_keys .iter() .map(ProofKeys::fetch_storage_proof) - .collect::, FetcherError>>()? + .collect::, FetcherError>>()? .into_iter() { headers_with_mmr.insert(header_with_mmr); diff --git a/crates/fetcher/src/proof_keys.rs b/crates/fetcher/src/proof_keys.rs index caf72c44..d6d0b965 100644 --- a/crates/fetcher/src/proof_keys.rs +++ b/crates/fetcher/src/proof_keys.rs @@ -11,6 +11,7 @@ use hdp_hint_processor::{ mmr::MmrMeta, mpt::MPTProof, storage::Storage, + HeaderMmrMeta, }, syscall_handler::keys, }; @@ -33,7 +34,12 @@ pub struct ProofKeys { } impl ProofKeys { - pub fn fetch_header_proof(key: &keys::header::Key) -> Result<(MmrMeta, Header), FetcherError> { + fn normalize_hex(input: &str) -> String { + let hex_str = input.trim_start_matches("0x"); + format!("{:0>width$}", hex_str, width = (hex_str.len() + 1) / 2 * 2) + } + + pub fn fetch_header_proof(key: &keys::header::Key) -> Result { let provider = Indexer::default(); let runtime = tokio::runtime::Runtime::new().unwrap(); @@ -48,45 +54,54 @@ impl ProofKeys { let mmr_meta = MmrMeta { id: u64::from_str_radix(&response.mmr_meta.mmr_id[2..], 16)?, size: response.mmr_meta.mmr_size, - root: response.mmr_meta.mmr_root.parse()?, - chain_id: key.chain_id, + root: Self::normalize_hex(&response.mmr_meta.mmr_root).parse()?, peaks: response .mmr_meta .mmr_peaks .iter() - .map(|peak| peak.parse()) + .map(|peak| Self::normalize_hex(peak).parse()) .collect::, FromHexError>>()?, }; - // Retrieve MMR proof let mmr_proof = response .headers .get(&key.block_number) .ok_or_else(|| FetcherError::InternalError("block not found".into()))?; // Parse RLP - let rlp = match &mmr_proof.block_header { - BlockHeader::RlpString(rlp) => rlp, + let rlp: Bytes = match &mmr_proof.block_header { + BlockHeader::RlpString(rlp) => rlp.parse()?, + BlockHeader::RlpLittleEndian8ByteChunks(rlp) => { + let rlp_chunks: Vec = rlp + .clone() + .iter() + .map(|x| Self::normalize_hex(x).parse()) + .collect::, FromHexError>>()?; + rlp_chunks.iter().flat_map(|x| x.iter().rev().cloned()).collect::>().into() + } _ => return Err(FetcherError::InternalError("wrong rlp format".into())), }; // Construct Header let header = Header { - rlp: rlp.parse()?, + rlp, proof: HeaderProof { leaf_idx: mmr_proof.element_index, mmr_path: mmr_proof .siblings_hashes .iter() - .map(|hash| hash.parse()) + .map(|hash| Self::normalize_hex(hash).parse()) .collect::, FromHexError>>()?, }, }; - Ok((mmr_meta, header)) + Ok(HeaderMmrMeta { + mmr_meta, + headers: vec![header], + }) } - pub fn fetch_account_proof(key: &keys::account::Key) -> Result<((MmrMeta, Header), Account), FetcherError> { + pub fn fetch_account_proof(key: &keys::account::Key) -> Result<(HeaderMmrMeta, Account), FetcherError> { let runtime = tokio::runtime::Runtime::new().unwrap(); let provider = RootProvider::>::new_http(Url::parse(&env::var(RPC).unwrap()).unwrap()); let value = runtime @@ -98,7 +113,7 @@ impl ProofKeys { )) } - pub fn fetch_storage_proof(key: &keys::storage::Key) -> Result<((MmrMeta, Header), Account, Storage), FetcherError> { + pub fn fetch_storage_proof(key: &keys::storage::Key) -> Result<(HeaderMmrMeta, Account, Storage), FetcherError> { let runtime = tokio::runtime::Runtime::new().unwrap(); let provider = RootProvider::>::new_http(Url::parse(&env::var(RPC).unwrap()).unwrap()); let value = runtime diff --git a/crates/hdp_hint_processor/src/hint_processor/mod.rs b/crates/hdp_hint_processor/src/hint_processor/mod.rs index 5dde7b97..c825421a 100644 --- a/crates/hdp_hint_processor/src/hint_processor/mod.rs +++ b/crates/hdp_hint_processor/src/hint_processor/mod.rs @@ -103,7 +103,6 @@ impl CustomHintProcessor { hints.insert(lib::verifiers::evm::transaction_verifier::HINT_SET_TX_BLOCK_NUMBER.into(), lib::verifiers::evm::transaction_verifier::hint_set_tx_block_number); hints.insert(lib::verifiers::evm::transaction_verifier::HINT_PROOF_BYTES_LEN.into(), lib::verifiers::evm::transaction_verifier::hint_proof_bytes_len); hints.insert(lib::verifiers::evm::transaction_verifier::HINT_MPT_PROOF.into(), lib::verifiers::evm::transaction_verifier::hint_mpt_proof); - hints.insert(lib::verifiers::evm::header_verifier::HINT_BATCH_HEADERS_LEN.into(), lib::verifiers::evm::header_verifier::hint_batch_headers_len); hints.insert(lib::verifiers::evm::header_verifier::HINT_LEAF_IDX.into(), lib::verifiers::evm::header_verifier::hint_leaf_idx); hints.insert(lib::verifiers::evm::header_verifier::HINT_MMR_PATH_LEN.into(), lib::verifiers::evm::header_verifier::hint_mmr_path_len); hints.insert(lib::verifiers::evm::header_verifier::HINT_MMR_PATH.into(), lib::verifiers::evm::header_verifier::hint_mmr_path); @@ -128,8 +127,6 @@ impl CustomHintProcessor { hints.insert(lib::verifiers::evm::storage_item_verifier::HINT_SET_STORAGE_PROOFS_LEN.into(), lib::verifiers::evm::storage_item_verifier::hint_set_storage_proofs_len); hints.insert(lib::verifiers::evm::storage_item_verifier::HINT_SET_STORAGE_PROOF_AT.into(), lib::verifiers::evm::storage_item_verifier::hint_set_storage_proof_at); hints.insert(lib::verifiers::evm::storage_item_verifier::HINT_SET_STORAGE_SLOT.into(), lib::verifiers::evm::storage_item_verifier::hint_set_storage_slot); - hints.insert(lib::verifiers::verify::HINT_BATCH_LEN.into(), lib::verifiers::verify::hint_batch_len); - hints.insert(lib::verifiers::verify::HINT_CHAIN_ID.into(), lib::verifiers::verify::hint_chain_id); hints.insert(lib::verifiers::verify::HINT_VM_ENTER_SCOPE.into(), lib::verifiers::verify::hint_vm_enter_scope); hints.insert(lib::verifiers::utils::HINT_PRINT_TASK_RESULT.into(), lib::verifiers::utils::hint_print_task_result); hints diff --git a/crates/hdp_hint_processor/src/hint_processor/models/proofs/header.rs b/crates/hdp_hint_processor/src/hint_processor/models/proofs/header.rs index c29630fa..54d65e38 100644 --- a/crates/hdp_hint_processor/src/hint_processor/models/proofs/header.rs +++ b/crates/hdp_hint_processor/src/hint_processor/models/proofs/header.rs @@ -2,14 +2,14 @@ use alloy::primitives::Bytes; use serde::{Deserialize, Serialize}; use serde_with::serde_as; -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq, Hash, Default)] #[serde_as] pub struct HeaderProof { pub leaf_idx: u64, pub mmr_path: Vec, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq, Hash, Default)] pub struct Header { pub rlp: Bytes, pub proof: HeaderProof, diff --git a/crates/hdp_hint_processor/src/hint_processor/models/proofs/mmr.rs b/crates/hdp_hint_processor/src/hint_processor/models/proofs/mmr.rs index 22e1d605..ea407beb 100644 --- a/crates/hdp_hint_processor/src/hint_processor/models/proofs/mmr.rs +++ b/crates/hdp_hint_processor/src/hint_processor/models/proofs/mmr.rs @@ -8,7 +8,6 @@ pub struct MmrMeta { pub id: u64, pub size: u64, pub root: Bytes, - pub chain_id: u64, pub peaks: Vec, } diff --git a/crates/hdp_hint_processor/src/hint_processor/models/proofs/mod.rs b/crates/hdp_hint_processor/src/hint_processor/models/proofs/mod.rs index 261ee474..410c82d4 100644 --- a/crates/hdp_hint_processor/src/hint_processor/models/proofs/mod.rs +++ b/crates/hdp_hint_processor/src/hint_processor/models/proofs/mod.rs @@ -14,11 +14,15 @@ use serde::{Deserialize, Serialize}; use storage::Storage; use transaction::Transaction; +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default, Hash)] +pub struct HeaderMmrMeta { + pub headers: Vec
, + pub mmr_meta: MmrMeta, +} + #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)] pub struct Proofs { - pub mmr_meta: MmrMeta, - pub headers: Vec
, - pub headers_with_mmr: Vec<(MmrMeta, Header)>, + pub headers_with_mmr: Vec, pub accounts: Vec, pub storages: Vec, pub transactions: Vec, diff --git a/crates/hdp_hint_processor/src/hints/lib/verifiers/evm/header_verifier.rs b/crates/hdp_hint_processor/src/hints/lib/verifiers/evm/header_verifier.rs index 4cb4edbc..e253eaba 100644 --- a/crates/hdp_hint_processor/src/hints/lib/verifiers/evm/header_verifier.rs +++ b/crates/hdp_hint_processor/src/hints/lib/verifiers/evm/header_verifier.rs @@ -1,33 +1,57 @@ use cairo_vm::{ hint_processor::builtin_hint_processor::{ builtin_hint_processor_definition::HintProcessorData, + dict_manager::DictManager, hint_utils::{get_integer_from_var_name, get_ptr_from_var_name, insert_value_into_ap}, }, types::exec_scope::ExecutionScopes, vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, Felt252, }; -use std::collections::HashMap; +use std::{any::Any, collections::HashMap}; use crate::{ - hint_processor::models::proofs::{header::Header, Proofs}, + hint_processor::models::proofs::{header::Header, HeaderMmrMeta, Proofs}, hints::vars, }; -pub const HINT_BATCH_HEADERS_LEN: &str = "memory[ap] = to_felt_or_relocatable(len(batch.headers))"; +pub const HINT_VM_ENTER_SCOPE: &str = "vm_enter_scope({'header_with_mmr': batch.header_with_mmr[ids.idx], '__dict_manager': __dict_manager})"; -pub fn hint_batch_headers_len( +pub fn hint_vm_enter_scope( + vm: &mut VirtualMachine, + exec_scopes: &mut ExecutionScopes, + hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let proofs = exec_scopes.get::(vars::scopes::BATCH)?; + let idx: usize = get_integer_from_var_name(vars::ids::IDX, vm, &hint_data.ids_data, &hint_data.ap_tracking)? + .try_into() + .unwrap(); + + let headers_with_mmr: Box = Box::new(proofs.headers_with_mmr[idx].clone()); + let dict_manager: Box = Box::new(exec_scopes.get::(vars::scopes::DICT_MANAGER)?); + exec_scopes.enter_scope(HashMap::from([ + (String::from(vars::scopes::HEADER_WITH_MMR), headers_with_mmr), + (String::from(vars::scopes::DICT_MANAGER), dict_manager), + ])); + + Ok(()) +} + +pub const HINT_HEADERS_WITH_MMR_HEADERS_LEN: &str = "memory[ap] = to_felt_or_relocatable(len(headers_with_mmr.headers))"; + +pub fn hint_headers_with_mmr_headers_len( vm: &mut VirtualMachine, exec_scopes: &mut ExecutionScopes, _hint_data: &HintProcessorData, _constants: &HashMap, ) -> Result<(), HintError> { - let batch = exec_scopes.get::(vars::scopes::BATCH)?; + let header_with_mmr = exec_scopes.get::(vars::scopes::HEADER_WITH_MMR)?; - insert_value_into_ap(vm, Felt252::from(batch.headers.len())) + insert_value_into_ap(vm, Felt252::from(header_with_mmr.headers.len())) } -pub const HINT_SET_HEADER: &str = "header = batch.headers[ids.idx - 1]\nsegments.write_arg(ids.rlp, [int(x, 16) for x in header.rlp])"; +pub const HINT_SET_HEADER: &str = "header = header_with_mmr.headers[ids.idx - 1]\nsegments.write_arg(ids.rlp, [int(x, 16) for x in header.rlp])"; pub fn hint_set_header( vm: &mut VirtualMachine, @@ -35,11 +59,11 @@ pub fn hint_set_header( hint_data: &HintProcessorData, _constants: &HashMap, ) -> Result<(), HintError> { - let batch = exec_scopes.get::(vars::scopes::BATCH)?; + let headers_with_mmr = exec_scopes.get::(vars::scopes::HEADER_WITH_MMR)?; let idx: usize = get_integer_from_var_name(vars::ids::IDX, vm, &hint_data.ids_data, &hint_data.ap_tracking)? .try_into() .unwrap(); - let header = batch.headers[idx - 1].clone(); + let header = headers_with_mmr.headers[idx - 1].clone(); let rlp_le_chunks: Vec = header.rlp.chunks(8).map(Felt252::from_bytes_le_slice).collect(); exec_scopes.insert_value::
(vars::scopes::HEADER, header); diff --git a/crates/hdp_hint_processor/src/hints/lib/verifiers/verify.rs b/crates/hdp_hint_processor/src/hints/lib/verifiers/verify.rs index b0737466..c1773004 100644 --- a/crates/hdp_hint_processor/src/hints/lib/verifiers/verify.rs +++ b/crates/hdp_hint_processor/src/hints/lib/verifiers/verify.rs @@ -1,9 +1,6 @@ -use cairo_vm::{ - hint_processor::builtin_hint_processor::{ - builtin_hint_processor_definition::HintProcessorData, dict_manager::DictManager, hint_utils::insert_value_from_var_name, - }, - types::relocatable::MaybeRelocatable, -}; +use crate::{hint_processor::models::proofs::Proofs, hints::vars}; +use cairo_vm::hint_processor::builtin_hint_processor::hint_utils::insert_value_into_ap; +use cairo_vm::hint_processor::builtin_hint_processor::{builtin_hint_processor_definition::HintProcessorData, dict_manager::DictManager}; use cairo_vm::{ types::exec_scope::ExecutionScopes, vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, @@ -11,49 +8,7 @@ use cairo_vm::{ }; use std::{any::Any, collections::HashMap}; -use crate::{hint_processor::models::proofs::Proofs, hints::vars}; - -pub const HINT_BATCH_LEN: &str = "ids.batch_len = len(proofs)"; - -pub fn hint_batch_len( - vm: &mut VirtualMachine, - exec_scopes: &mut ExecutionScopes, - hint_data: &HintProcessorData, - _constants: &HashMap, -) -> Result<(), HintError> { - let proofs = exec_scopes.get::>(vars::scopes::PROOFS)?; - - insert_value_from_var_name( - vars::ids::BATCH_LEN, - MaybeRelocatable::Int(proofs.len().into()), - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - ) -} - -pub const HINT_CHAIN_ID: &str = "ids.chain_id = proofs[ids.batch_len - 1].mmr_meta.chain_id"; - -pub fn hint_chain_id( - vm: &mut VirtualMachine, - exec_scopes: &mut ExecutionScopes, - hint_data: &HintProcessorData, - _constants: &HashMap, -) -> Result<(), HintError> { - let proofs = exec_scopes.get::>(vars::scopes::PROOFS)?; - - let chain_id = proofs[proofs.len() - 1].mmr_meta.chain_id; - - insert_value_from_var_name( - vars::ids::CHAIN_ID, - MaybeRelocatable::Int(chain_id.into()), - vm, - &hint_data.ids_data, - &hint_data.ap_tracking, - ) -} - -pub const HINT_VM_ENTER_SCOPE: &str = "vm_enter_scope({'batch': proofs[ids.batch_len - 1], '__dict_manager': __dict_manager})"; +pub const HINT_VM_ENTER_SCOPE: &str = "vm_enter_scope({'batch': proofs, '__dict_manager': __dict_manager})"; pub fn hint_vm_enter_scope( _vm: &mut VirtualMachine, @@ -61,9 +16,9 @@ pub fn hint_vm_enter_scope( _hint_data: &HintProcessorData, _constants: &HashMap, ) -> Result<(), HintError> { - let proofs = exec_scopes.get::>(vars::scopes::PROOFS)?; + let proofs = exec_scopes.get::(vars::scopes::PROOFS)?; - let batch: Box = Box::new(proofs[proofs.len() - 1].clone()); + let batch: Box = Box::new(proofs); let dict_manager: Box = Box::new(exec_scopes.get::(vars::scopes::DICT_MANAGER)?); exec_scopes.enter_scope(HashMap::from([ (String::from(vars::scopes::BATCH), batch), @@ -72,3 +27,16 @@ pub fn hint_vm_enter_scope( Ok(()) } + +pub const HINT_HEADERS_WITH_MMR_LEN: &str = "memory[ap] = to_felt_or_relocatable(len(batch.headers_with_mmr))"; + +pub fn hint_headers_with_mmr_headers_len( + vm: &mut VirtualMachine, + exec_scopes: &mut ExecutionScopes, + _hint_data: &HintProcessorData, + _constants: &HashMap, +) -> Result<(), HintError> { + let proofs = exec_scopes.get::(vars::scopes::PROOF)?; + + insert_value_into_ap(vm, Felt252::from(proofs.headers_with_mmr.len())) +} diff --git a/crates/hdp_hint_processor/src/hints/vars.rs b/crates/hdp_hint_processor/src/hints/vars.rs index 2e4f1046..190e849a 100644 --- a/crates/hdp_hint_processor/src/hints/vars.rs +++ b/crates/hdp_hint_processor/src/hints/vars.rs @@ -12,6 +12,7 @@ pub mod scopes { pub const STORAGE: &str = "storage"; pub const SYSCALL_HANDLER: &str = "syscall_handler"; pub const TRANSACTION: &str = "transaction"; + pub const HEADER_WITH_MMR: &str = "header_with_mmr"; } pub mod ids { diff --git a/crates/provider/src/indexer/types.rs b/crates/provider/src/indexer/types.rs index a2fcc4ae..860e75e3 100644 --- a/crates/provider/src/indexer/types.rs +++ b/crates/provider/src/indexer/types.rs @@ -59,6 +59,7 @@ pub struct IndexerQuery { pub is_whole_tree: bool, pub is_rlp_included: bool, pub is_pure_rlp: bool, + pub prefer_native_block_header: bool, } impl IndexerQuery { @@ -74,6 +75,7 @@ impl IndexerQuery { is_whole_tree: true, is_rlp_included: true, is_pure_rlp: true, + prefer_native_block_header: false, } } } diff --git a/src/types.cairo b/src/types.cairo index 762bfc2d..baef9a28 100644 --- a/src/types.cairo +++ b/src/types.cairo @@ -11,7 +11,6 @@ struct MMRMeta { id: felt, root: felt, size: felt, - chain_id: felt, } struct ModuleTask { diff --git a/src/utils/utils.cairo b/src/utils/utils.cairo index 035b971d..aea4cca3 100644 --- a/src/utils/utils.cairo +++ b/src/utils/utils.cairo @@ -39,7 +39,6 @@ func write_output_ptr{output_ptr: felt*}( assert [output_ptr + counter * 4] = mmr_metas[counter].id; assert [output_ptr + counter * 4 + 1] = mmr_metas[counter].size; - assert [output_ptr + counter * 4 + 2] = mmr_metas[counter].chain_id; assert [output_ptr + counter * 4 + 3] = mmr_metas[counter].root; [ap] = counter + 1, ap++; diff --git a/src/verifiers/evm/header_verifier.cairo b/src/verifiers/evm/header_verifier.cairo index 5b1c0ede..9655c7cc 100644 --- a/src/verifiers/evm/header_verifier.cairo +++ b/src/verifiers/evm/header_verifier.cairo @@ -18,22 +18,30 @@ func verify_mmr_batches{ pow2_array: felt*, evm_memorizer: DictAccess*, mmr_metas: MMRMeta*, - chain_id: felt, -}(mmr_meta_idx: felt) -> (mmr_meta_idx: felt) { + chain_info: ChainInfo, +}(idx: felt, mmr_meta_idx: felt) -> (mmr_meta_idx: felt) { alloc_locals; - let (mmr_meta, peaks_dict, peaks_dict_start) = validate_mmr_meta(chain_id); + if (0 == idx) { + return (mmr_meta_idx=mmr_meta_idx); + } + + %{ vm_enter_scope({'header_with_mmr': batch.header_with_mmr[ids.idx], '__dict_manager': __dict_manager}) %} + + let (mmr_meta, peaks_dict, peaks_dict_start) = validate_mmr_meta(); assert mmr_metas[mmr_meta_idx] = mmr_meta; - local n_header_proofs: felt = nondet %{ len(batch.headers) %}; + local n_header_proofs: felt = nondet %{ len(header_with_mmr.headers) %}; with mmr_meta, peaks_dict { verify_headers_with_mmr_peaks(n_header_proofs); } + %{ vm_exit_scope() %} + // Ensure the peaks dict for this batch is finalized default_dict_finalize(peaks_dict_start, peaks_dict, -1); - return (mmr_meta_idx=mmr_meta_idx + 1); + return verify_mmr_batches(idx=idx - 1, mmr_meta_idx=mmr_meta_idx + 1); } // Guard function that verifies the inclusion of headers in the MMR. @@ -48,6 +56,7 @@ func verify_headers_with_mmr_peaks{ bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*, evm_memorizer: DictAccess*, + chain_info: ChainInfo, mmr_meta: MMRMeta, peaks_dict: DictAccess*, }(idx: felt) { @@ -58,7 +67,7 @@ func verify_headers_with_mmr_peaks{ let (rlp) = alloc(); %{ - header = batch.headers[ids.idx - 1] + header = header_with_mmr.headers[ids.idx - 1] segments.write_arg(ids.rlp, [int(x, 16) for x in header.rlp]) %} @@ -76,9 +85,7 @@ func verify_headers_with_mmr_peaks{ // add to memorizer let block_number = HeaderDecoder.get_block_number(rlp); - let memorizer_key = EvmHashParams.header( - chain_id=mmr_meta.chain_id, block_number=block_number - ); + let memorizer_key = EvmHashParams.header(chain_id=chain_info.id, block_number=block_number); EvmMemorizer.add(key=memorizer_key, data=rlp); return verify_headers_with_mmr_peaks(idx=idx - 1); @@ -103,7 +110,7 @@ func verify_headers_with_mmr_peaks{ // add to memorizer let block_number = HeaderDecoder.get_block_number(rlp); - let memorizer_key = EvmHashParams.header(chain_id=mmr_meta.chain_id, block_number=block_number); + let memorizer_key = EvmHashParams.header(chain_id=chain_info.id, block_number=block_number); EvmMemorizer.add(key=memorizer_key, data=rlp); return verify_headers_with_mmr_peaks(idx=idx - 1); diff --git a/src/verifiers/evm/verify.cairo b/src/verifiers/evm/verify.cairo index 65527160..a0205776 100644 --- a/src/verifiers/evm/verify.cairo +++ b/src/verifiers/evm/verify.cairo @@ -3,11 +3,10 @@ from src.verifiers.evm.storage_item_verifier import verify_storage_items from src.verifiers.evm.header_verifier import verify_mmr_batches from src.verifiers.evm.block_tx_verifier import verify_block_tx_proofs from src.verifiers.evm.receipt_verifier import verify_block_receipt_proofs - from starkware.cairo.common.dict_access import DictAccess from starkware.cairo.common.cairo_builtins import PoseidonBuiltin, BitwiseBuiltin, KeccakBuiltin - from src.types import MMRMeta, ChainInfo +from src.utils.chain_info import fetch_chain_info func run_state_verification{ range_check_ptr, @@ -17,27 +16,27 @@ func run_state_verification{ pow2_array: felt*, evm_memorizer: DictAccess*, mmr_metas: MMRMeta*, - chain_info: ChainInfo, }(mmr_meta_idx: felt) -> (mmr_meta_idx: felt) { alloc_locals; - // Step 1: Verify MMR and headers inclusion - let chain_id = chain_info.id; - with chain_id { - let (mmr_meta_idx) = verify_mmr_batches(mmr_meta_idx); - } + let (chain_info) = fetch_chain_info(11155111); + with chain_info { + // Step 1: Verify MMR and headers inclusion + local n_proofs: felt = nondet %{ len(batch.header_with_mmr) %}; + let (mmr_meta_idx) = verify_mmr_batches(n_proofs, mmr_meta_idx); - // Step 2: Verify the accounts - verify_accounts(); + // Step 2: Verify the accounts + verify_accounts(); - // Step 3: Verify the storage items - verify_storage_items(); + // Step 3: Verify the storage items + verify_storage_items(); - // Step 4: Verify the block tx proofs - verify_block_tx_proofs(); + // Step 4: Verify the block tx proofs + verify_block_tx_proofs(); - // Step 5: Verify the block receipt proofs - verify_block_receipt_proofs(); + // Step 5: Verify the block receipt proofs + verify_block_receipt_proofs(); + } return (mmr_meta_idx=mmr_meta_idx); } diff --git a/src/verifiers/mmr_verifier.cairo b/src/verifiers/mmr_verifier.cairo index 12b2197c..df4b151b 100644 --- a/src/verifiers/mmr_verifier.cairo +++ b/src/verifiers/mmr_verifier.cairo @@ -16,9 +16,9 @@ from packages.eth_essentials.lib.mmr import ( // 2. mmr_peaks_len matches the expected value based on mmr_size // 3. mmr_peaks, mmr_size recreate the mmr_root // It writes the peaks to the dict and returns the mmr_meta. -func validate_mmr_meta{range_check_ptr, poseidon_ptr: PoseidonBuiltin*, pow2_array: felt*}( - chain_id: felt -) -> (mmr_meta: MMRMeta, dict: DictAccess*, dict_start: DictAccess*) { +func validate_mmr_meta{range_check_ptr, poseidon_ptr: PoseidonBuiltin*, pow2_array: felt*}() -> ( + mmr_meta: MMRMeta, dict: DictAccess*, dict_start: DictAccess* +) { alloc_locals; let (local dict: DictAccess*) = default_dict_new(default_value=-1); @@ -29,12 +29,11 @@ func validate_mmr_meta{range_check_ptr, poseidon_ptr: PoseidonBuiltin*, pow2_arr local peaks_len: felt; %{ - memory[ids.mmr_meta._reference_value + 0] = batch.mmr_meta.id - memory[ids.mmr_meta._reference_value + 1] = batch.mmr_meta.root - memory[ids.mmr_meta._reference_value + 2] = batch.mmr_meta.size - memory[ids.mmr_meta._reference_value + 3] = batch.mmr_meta.chain_id - ids.peaks_len = len(batch.mmr_meta.peaks) - segments.write_arg(ids.peaks, batch.mmr_meta.peaks) + memory[ids.mmr_meta._reference_value + 0] = header_with_mmr.mmr_meta.id + memory[ids.mmr_meta._reference_value + 1] = header_with_mmr.mmr_meta.root + memory[ids.mmr_meta._reference_value + 2] = header_with_mmr.mmr_meta.size + ids.peaks_len = len(header_with_mmr.mmr_meta.peaks) + segments.write_arg(ids.peaks, header_with_mmr.mmr_meta.peaks) %} assert_mmr_size_is_valid(mmr_meta.size); diff --git a/src/verifiers/starknet/header_verifier.cairo b/src/verifiers/starknet/header_verifier.cairo index f9a1ce98..fb09152c 100644 --- a/src/verifiers/starknet/header_verifier.cairo +++ b/src/verifiers/starknet/header_verifier.cairo @@ -6,7 +6,7 @@ from starkware.cairo.common.memcpy import memcpy from starkware.cairo.common.builtin_poseidon.poseidon import poseidon_hash_many from starkware.cairo.common.default_dict import default_dict_finalize from packages.eth_essentials.lib.mmr import hash_subtree_path -from src.types import MMRMeta +from src.types import MMRMeta, ChainInfo from src.memorizers.starknet.memorizer import StarknetMemorizer, StarknetHashParams from src.decoders.starknet.header_decoder import StarknetHeaderDecoder, StarknetHeaderFields from src.verifiers.mmr_verifier import validate_mmr_meta @@ -17,14 +17,14 @@ func verify_mmr_batches{ pow2_array: felt*, starknet_memorizer: DictAccess*, mmr_metas: MMRMeta*, - chain_id: felt, + chain_info: ChainInfo, }(mmr_meta_idx: felt) -> (mmr_meta_idx: felt) { alloc_locals; - let (mmr_meta, peaks_dict, peaks_dict_start) = validate_mmr_meta(chain_id); + let (mmr_meta, peaks_dict, peaks_dict_start) = validate_mmr_meta(); assert mmr_metas[mmr_meta_idx] = mmr_meta; - local n_header_proofs: felt = nondet %{ len(batch.headers) %}; + local n_header_proofs: felt = nondet %{ len(batch.header_with_mmr.headers) %}; with mmr_meta, peaks_dict { verify_headers_with_mmr_peaks(n_header_proofs); } @@ -45,6 +45,7 @@ func verify_headers_with_mmr_peaks{ range_check_ptr, poseidon_ptr: PoseidonBuiltin*, pow2_array: felt*, + chain_info: ChainInfo, mmr_meta: MMRMeta, starknet_memorizer: DictAccess*, peaks_dict: DictAccess*, @@ -56,7 +57,7 @@ func verify_headers_with_mmr_peaks{ let (fields) = alloc(); %{ - header = batch.headers[ids.idx - 1] + header = batch.header_with_mmr.headers[ids.idx - 1] segments.write_arg(ids.fields, [int(x, 16) for x in header.fields]) %} @@ -74,7 +75,7 @@ func verify_headers_with_mmr_peaks{ // add to memorizer let block_number = [fields + 1]; - let memorizer_key = StarknetHashParams.header(mmr_meta.chain_id, block_number); + let memorizer_key = StarknetHashParams.header(chain_info.id, block_number); StarknetMemorizer.add(key=memorizer_key, data=fields); return verify_headers_with_mmr_peaks(idx=idx - 1); @@ -105,7 +106,7 @@ func verify_headers_with_mmr_peaks{ let (block_number) = StarknetHeaderDecoder.get_field( length_and_fields, StarknetHeaderFields.BLOCK_NUMBER ); - let memorizer_key = StarknetHashParams.header(mmr_meta.chain_id, block_number); + let memorizer_key = StarknetHashParams.header(chain_info.id, block_number); StarknetMemorizer.add(key=memorizer_key, data=length_and_fields); return verify_headers_with_mmr_peaks(idx=idx - 1); diff --git a/src/verifiers/verify.cairo b/src/verifiers/verify.cairo index 521272c3..ce73dd72 100644 --- a/src/verifiers/verify.cairo +++ b/src/verifiers/verify.cairo @@ -26,49 +26,11 @@ func run_state_verification{ }() -> (mmr_metas_len: felt) { alloc_locals; - local batch_len: felt; - %{ ids.batch_len = len(proofs) %} - let (mmr_meta_idx) = run_state_verification_inner(batch_len, 0); + %{ vm_enter_scope({'batch': proofs, '__dict_manager': __dict_manager}) %} - return (mmr_metas_len=mmr_meta_idx); -} + let (mmr_meta_idx) = evm_run_state_verification(0); -func run_state_verification_inner{ - range_check_ptr, - pedersen_ptr: HashBuiltin*, - poseidon_ptr: PoseidonBuiltin*, - keccak_ptr: KeccakBuiltin*, - bitwise_ptr: BitwiseBuiltin*, - pow2_array: felt*, - evm_memorizer: DictAccess*, - starknet_memorizer: DictAccess*, - mmr_metas: MMRMeta*, -}(batch_len: felt, mmr_meta_idx: felt) -> (mmr_meta_idx: felt) { - alloc_locals; - if (batch_len == 0) { - return (mmr_meta_idx=mmr_meta_idx); - } - - local chain_id: felt; - %{ ids.chain_id = proofs[ids.batch_len - 1].mmr_meta.chain_id %} + %{ vm_exit_scope() %} - let (chain_info) = fetch_chain_info(chain_id); - - if (chain_info.layout == 0) { - %{ vm_enter_scope({'batch': proofs[ids.batch_len - 1], '__dict_manager': __dict_manager}) %} - with chain_info { - let (mmr_meta_idx) = evm_run_state_verification(mmr_meta_idx); - } - %{ vm_exit_scope() %} - - return run_state_verification_inner(batch_len=batch_len - 1, mmr_meta_idx=mmr_meta_idx); - } else { - %{ vm_enter_scope({'batch': proofs[ids.batch_len - 1], '__dict_manager': __dict_manager}) %} - with chain_info { - let (mmr_meta_idx) = starknet_run_state_verification(mmr_meta_idx); - } - %{ vm_exit_scope() %} - - return run_state_verification_inner(batch_len=batch_len - 1, mmr_meta_idx=mmr_meta_idx); - } + return (mmr_metas_len=mmr_meta_idx); }