Skip to content

Commit

Permalink
fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
kariy committed Apr 23, 2024
1 parent 54eb048 commit 9eeb610
Showing 1 changed file with 224 additions and 62 deletions.
286 changes: 224 additions & 62 deletions crates/katana/executor/src/implementation/blockifier/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use std::collections::{BTreeMap, HashMap};
use std::sync::Arc;

use blockifier::block_context::{BlockContext, BlockInfo, ChainInfo, FeeTokenAddresses, GasPrices};
use blockifier::execution::call_info::CallInfo;
use blockifier::execution::call_info::{
CallExecution, CallInfo, OrderedEvent, OrderedL2ToL1Message,
};
use blockifier::execution::common_hints::ExecutionMode;
use blockifier::execution::contract_class::{ContractClass, ContractClassV0, ContractClassV1};
use blockifier::execution::entry_point::{
Expand All @@ -29,7 +31,7 @@ use katana_primitives::trace::TxExecInfo;
use katana_primitives::transaction::{
DeclareTx, DeployAccountTx, ExecutableTx, ExecutableTxWithHash, InvokeTx,
};
use katana_primitives::FieldElement;
use katana_primitives::{event, message, trace, FieldElement};
use katana_provider::traits::contract::ContractClassProvider;
use starknet::core::types::PriceUnit;
use starknet::core::utils::parse_cairo_short_string;
Expand Down Expand Up @@ -525,73 +527,95 @@ pub fn to_exec_info(exec_info: TransactionExecutionInfo) -> TxExecInfo {
}
}

fn to_call_info(call_info: CallInfo) -> katana_primitives::trace::CallInfo {
katana_primitives::trace::CallInfo {
contract_address: to_address(call_info.call.storage_address),
caller_address: to_address(call_info.call.caller_address),
call_type: match call_info.call.call_type {
CallType::Call => katana_primitives::trace::CallType::Call,
CallType::Delegate => katana_primitives::trace::CallType::Delegate,
},
code_address: call_info.call.code_address.map(to_address),
class_hash: call_info.call.class_hash.map(|a| a.0.into()),
entry_point_selector: call_info.call.entry_point_selector.0.into(),
entry_point_type: match call_info.call.entry_point_type {
EntryPointType::External => katana_primitives::trace::EntryPointType::External,
EntryPointType::L1Handler => katana_primitives::trace::EntryPointType::L1Handler,
EntryPointType::Constructor => katana_primitives::trace::EntryPointType::Constructor,
},
calldata: call_info.call.calldata.0.iter().map(|f| (*f).into()).collect(),
retdata: call_info.execution.retdata.0.iter().map(|f| (*f).into()).collect(),
execution_resources: katana_primitives::trace::ExecutionResources {
n_steps: call_info.vm_resources.n_steps as u64,
n_memory_holes: call_info.vm_resources.n_memory_holes as u64,
builtin_instance_counter: call_info
.vm_resources
.builtin_instance_counter
.into_iter()
.map(|(k, v)| (k, v as u64))
.collect(),
},
events: call_info
.execution
.events
.iter()
.map(|e| katana_primitives::event::OrderedEvent {
order: e.order as u64,
keys: e.event.keys.iter().map(|f| f.0.into()).collect(),
data: e.event.data.0.iter().map(|f| (*f).into()).collect(),
})
.collect(),
l2_to_l1_messages: call_info
.execution
.l2_to_l1_messages
.iter()
.map(|m| katana_primitives::message::OrderedL2ToL1Message {
order: m.order as u64,
from_address: to_address(call_info.call.storage_address),
to_address: starknet_api_ethaddr_to_felt(m.message.to_address),
payload: m.message.payload.0.iter().map(|f| (*f).into()).collect(),
})
.collect(),
storage_read_values: call_info.storage_read_values.into_iter().map(|f| f.into()).collect(),
accessed_storage_keys: call_info
.accessed_storage_keys
.into_iter()
.map(|sk| (*sk.0.key()).into())
.collect(),
inner_calls: call_info.inner_calls.iter().map(|c| to_call_info(c.clone())).collect(),
gas_consumed: call_info.execution.gas_consumed as u128,
failed: call_info.execution.failed,
fn to_call_info(call: CallInfo) -> trace::CallInfo {
let contract_address = to_address(call.call.storage_address);
let caller_address = to_address(call.call.caller_address);
let code_address = call.call.code_address.map(to_address);
let class_hash = call.call.class_hash.map(|a| a.0.into());
let entry_point_selector = call.call.entry_point_selector.0.into();
let calldata = call.call.calldata.0.iter().map(|f| (*f).into()).collect();
let retdata = call.execution.retdata.0.into_iter().map(|f| f.into()).collect();

let builtin_counter = call.vm_resources.builtin_instance_counter;
let execution_resources = trace::ExecutionResources {
n_steps: call.vm_resources.n_steps as u64,
n_memory_holes: call.vm_resources.n_memory_holes as u64,
builtin_instance_counter: builtin_counter.into_iter().map(|(k, v)| (k, v as u64)).collect(),
};

let CallExecution { events, l2_to_l1_messages, .. } = call.execution;

let events = events.into_iter().map(to_ordered_event).collect();
let l1_msg =
l2_to_l1_messages.into_iter().map(|m| to_l2_l1_messages(m, contract_address)).collect();

let call_type = match call.call.call_type {
CallType::Call => trace::CallType::Call,
CallType::Delegate => trace::CallType::Delegate,
};

let entry_point_type = match call.call.entry_point_type {
EntryPointType::External => trace::EntryPointType::External,
EntryPointType::L1Handler => trace::EntryPointType::L1Handler,
EntryPointType::Constructor => trace::EntryPointType::Constructor,
};

let storage_read_values = call.storage_read_values.into_iter().map(|f| f.into()).collect();
let storg_keys = call.accessed_storage_keys.into_iter().map(|k| (*k.0.key()).into()).collect();
let inner_calls = call.inner_calls.into_iter().map(to_call_info).collect();

trace::CallInfo {
contract_address,
caller_address,
call_type,
code_address,
class_hash,
entry_point_selector,
entry_point_type,
calldata,
retdata,
execution_resources,
events,
l2_to_l1_messages: l1_msg,
storage_read_values,
accessed_storage_keys: storg_keys,
inner_calls,
gas_consumed: call.execution.gas_consumed as u128,
failed: call.execution.failed,
}
}

fn to_ordered_event(e: OrderedEvent) -> event::OrderedEvent {
event::OrderedEvent {
order: e.order as u64,
keys: e.event.keys.into_iter().map(|f| f.0.into()).collect(),
data: e.event.data.0.into_iter().map(FieldElement::from).collect(),
}
}

fn to_l2_l1_messages(
m: OrderedL2ToL1Message,
from_address: katana_primitives::contract::ContractAddress,
) -> message::OrderedL2ToL1Message {
let order = m.order as u64;
let to_address = starknet_api_ethaddr_to_felt(m.message.to_address);
let payload = m.message.payload.0.into_iter().map(FieldElement::from).collect();
message::OrderedL2ToL1Message { order, from_address, to_address, payload }
}

#[cfg(test)]
mod tests {

use std::collections::HashSet;

use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
use katana_primitives::chain::{ChainId, NamedChainId};
use starknet::core::utils::parse_cairo_short_string;
use starknet_api::core::EntryPointSelector;
use starknet_api::hash::StarkFelt;
use starknet_api::stark_felt;
use starknet_api::transaction::{EventContent, EventData, EventKey};

use crate::implementation::blockifier::utils::to_blk_chain_id;
use super::*;

#[test]
fn convert_chain_id() {
Expand All @@ -603,4 +627,142 @@ mod tests {
assert_eq!(goerli.0, parse_cairo_short_string(&NamedChainId::Goerli.id()).unwrap());
assert_eq!(sepolia.0, parse_cairo_short_string(&NamedChainId::Sepolia.id()).unwrap());
}

fn create_blockifier_call_info() -> CallInfo {
let top_events = vec![OrderedEvent {
order: 0,
event: EventContent {
data: EventData(vec![888u128.into()]),
keys: vec![EventKey(999u128.into())],
},
}];
let nested_events = vec![
OrderedEvent {
order: 1,
event: EventContent {
data: EventData(vec![889u128.into()]),
keys: vec![EventKey(990u128.into())],
},
},
OrderedEvent {
order: 2,
event: EventContent {
data: EventData(vec![0u128.into()]),
keys: vec![EventKey(9u128.into())],
},
},
];

let nested_call = CallInfo {
execution: CallExecution { events: nested_events, ..Default::default() },
..Default::default()
};

CallInfo {
call: CallEntryPoint {
class_hash: None,
initial_gas: 77,
call_type: CallType::Call,
caller_address: 200u128.into(),
storage_address: 100u128.into(),
code_address: Some(100u128.into()),
entry_point_type: EntryPointType::External,
calldata: Calldata(Arc::new(vec![stark_felt!(1_u8)])),
entry_point_selector: EntryPointSelector(stark_felt!(999_u32)),
},
execution: CallExecution {
failed: true,
gas_consumed: 12345,
events: top_events,
..Default::default()
},
storage_read_values: vec![stark_felt!(1_u8), stark_felt!(2_u8)],
accessed_storage_keys: HashSet::from([3u128.into(), 4u128.into(), 5u128.into()]),
vm_resources: ExecutionResources {
n_steps: 1_000_000,
n_memory_holes: 9_000,
builtin_instance_counter: HashMap::from([
("ecdsa_builtin".into(), 50),
("pedersen_builtin".into(), 9),
]),
},
inner_calls: vec![nested_call],
}
}

#[test]
fn convert_call_info() {
// setup expected values
let call = create_blockifier_call_info();

let expected_contract_address = to_address(call.call.storage_address);
let expected_caller_address = to_address(call.call.caller_address);
let expected_code_address = call.call.code_address.map(to_address);
let expected_class_hash = call.call.class_hash.map(|a| a.0.into());
let expected_entry_point_selector = call.call.entry_point_selector.0.into();
let expected_calldata: Vec<FieldElement> =
call.call.calldata.0.iter().map(|f| (*f).into()).collect();
let expected_retdata: Vec<FieldElement> =
call.execution.retdata.0.iter().map(|f| (*f).into()).collect();

let builtin_counter = call.vm_resources.builtin_instance_counter.clone();
let expected_execution_resources = trace::ExecutionResources {
n_steps: call.vm_resources.n_steps as u64,
n_memory_holes: call.vm_resources.n_memory_holes as u64,
builtin_instance_counter: builtin_counter
.into_iter()
.map(|(k, v)| (k, v as u64))
.collect(),
};

let CallExecution { events, l2_to_l1_messages, .. } = call.execution.clone();
let expected_events: Vec<_> = events.into_iter().map(to_ordered_event).collect();
let expected_l2_to_l1_msg: Vec<_> = l2_to_l1_messages
.into_iter()
.map(|m| to_l2_l1_messages(m, expected_contract_address))
.collect();

let expected_call_type = match call.call.call_type {
CallType::Call => trace::CallType::Call,
CallType::Delegate => trace::CallType::Delegate,
};

let expected_entry_point_type = match call.call.entry_point_type {
EntryPointType::External => trace::EntryPointType::External,
EntryPointType::L1Handler => trace::EntryPointType::L1Handler,
EntryPointType::Constructor => trace::EntryPointType::Constructor,
};

let expected_storage_read_values: Vec<FieldElement> =
call.storage_read_values.iter().map(|f| (*f).into()).collect();
let expected_storage_keys: HashSet<FieldElement> =
call.accessed_storage_keys.iter().map(|k| (*k.0.key()).into()).collect();
let expected_inner_calls: Vec<_> =
call.inner_calls.clone().into_iter().map(to_call_info).collect();

let expected_gas_consumed = call.execution.gas_consumed as u128;
let expected_failed = call.execution.failed;

// convert to call info
let call = to_call_info(call.clone());

// assert actual values
assert_eq!(call.contract_address, expected_contract_address);
assert_eq!(call.caller_address, expected_caller_address);
assert_eq!(call.code_address, expected_code_address);
assert_eq!(call.class_hash, expected_class_hash);
assert_eq!(call.entry_point_selector, expected_entry_point_selector);
assert_eq!(call.calldata, expected_calldata);
assert_eq!(call.retdata, expected_retdata);
assert_eq!(call.execution_resources, expected_execution_resources);
assert_eq!(call.events, expected_events);
assert_eq!(call.l2_to_l1_messages, expected_l2_to_l1_msg);
assert_eq!(call.call_type, expected_call_type);
assert_eq!(call.entry_point_type, expected_entry_point_type);
assert_eq!(call.storage_read_values, expected_storage_read_values);
assert_eq!(call.accessed_storage_keys, expected_storage_keys);
assert_eq!(call.inner_calls, expected_inner_calls);
assert_eq!(call.gas_consumed, expected_gas_consumed);
assert_eq!(call.failed, expected_failed);
}
}

0 comments on commit 9eeb610

Please sign in to comment.