Skip to content

Commit

Permalink
wrapper and relay abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
Okm165 committed Feb 4, 2025
1 parent 4522f13 commit 2f0406a
Show file tree
Hide file tree
Showing 20 changed files with 231 additions and 282 deletions.
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions crates/dry_hint_processor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod syscall_handler;

use std::{any::Any, collections::HashMap};

use ::syscall_handler::SyscallHandlerWrapper;
use cairo_lang_casm::{
hints::{Hint, StarknetHint},
operand::{BinOpOperand, DerefOrImmediate, Operation, Register, ResOperand},
Expand All @@ -25,7 +26,7 @@ use cairo_vm::{
};
use hints::{extensive_hints, hints, vars, ExtensiveHintImpl, HintImpl};
use starknet_types_core::felt::Felt;
use syscall_handler::SyscallHandlerWrapper;
use syscall_handler::{evm, starknet};
use tokio::{runtime::Handle, task};
use types::HDPDryRunInput;

Expand Down Expand Up @@ -114,7 +115,10 @@ impl HintProcessorLogic for CustomHintProcessor {
if let Some(hint) = hint_data.downcast_ref::<Hint>() {
if let Hint::Starknet(StarknetHint::SystemCall { system }) = hint {
let syscall_ptr = get_ptr_from_res_operand(vm, system)?;
let syscall_handler = exec_scopes.get_mut_ref::<SyscallHandlerWrapper>(vars::scopes::SYSCALL_HANDLER)?;
let syscall_handler = exec_scopes
.get_mut_ref::<SyscallHandlerWrapper<evm::CallContractHandler, starknet::CallContractHandler>>(
vars::scopes::SYSCALL_HANDLER,
)?;
return task::block_in_place(|| {
Handle::current().block_on(async {
syscall_handler
Expand Down
131 changes: 13 additions & 118 deletions crates/dry_hint_processor/src/syscall_handler/mod.rs
Original file line number Diff line number Diff line change
@@ -1,127 +1,16 @@
pub mod evm;
pub mod starknet;

use std::{any::Any, collections::HashMap, rc::Rc};
use std::{any::Any, collections::HashMap};

use cairo_vm::{
hint_processor::builtin_hint_processor::{builtin_hint_processor_definition::HintProcessorData, hint_utils::get_ptr_from_var_name},
types::{exec_scope::ExecutionScopes, relocatable::Relocatable},
types::exec_scope::ExecutionScopes,
vm::{errors::hint_errors::HintError, vm_core::VirtualMachine},
Felt252,
};
use evm::CallContractHandler as EvmCallContractHandler;
use hints::vars;
use serde::{Deserialize, Serialize};
use starknet::CallContractHandler as StarknetCallContractHandler;
use syscall_handler::{
call_contract::{self, any_type::AnyTypeCallContractHandler, debug::DebugCallContractHandler},
felt_from_ptr,
keccak::KeccakHandler,
run_handler, traits, SyscallExecutionError, SyscallResult, SyscallSelector, WriteResponseResult,
};
use tokio::{sync::RwLock, task};
use types::{
cairo::{
new_syscalls::{CallContractRequest, CallContractResponse},
traits::CairoType,
},
ETHEREUM_MAINNET_CHAIN_ID, ETHEREUM_TESTNET_CHAIN_ID, STARKNET_MAINNET_CHAIN_ID, STARKNET_TESTNET_CHAIN_ID,
};

#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct SyscallHandler {
#[serde(skip)]
pub syscall_ptr: Option<Relocatable>,
pub call_contract_handler: CallContractHandlerRelay,
#[serde(skip)]
pub keccak_handler: KeccakHandler,
}

/// SyscallHandler is wrapped in Rc<RefCell<_>> in order
/// to clone the reference when entering and exiting vm scopes
#[derive(Debug, Clone, Default)]
pub struct SyscallHandlerWrapper {
pub syscall_handler: Rc<RwLock<SyscallHandler>>,
}

impl SyscallHandlerWrapper {
pub fn new() -> Self {
Self {
syscall_handler: Rc::new(RwLock::new(SyscallHandler::default())),
}
}
pub fn set_syscall_ptr(&self, syscall_ptr: Relocatable) {
let mut syscall_handler = task::block_in_place(|| self.syscall_handler.blocking_write());
syscall_handler.syscall_ptr = Some(syscall_ptr);
}

pub fn syscall_ptr(&self) -> Option<Relocatable> {
let syscall_handler = task::block_in_place(|| self.syscall_handler.blocking_read());
syscall_handler.syscall_ptr
}

pub async fn execute_syscall(&mut self, vm: &mut VirtualMachine, syscall_ptr: Relocatable) -> Result<(), HintError> {
let mut syscall_handler = self.syscall_handler.write().await;
let ptr = &mut syscall_handler
.syscall_ptr
.ok_or(HintError::CustomHint(Box::from("syscall_ptr is None")))?;

assert_eq!(*ptr, syscall_ptr);

match SyscallSelector::try_from(felt_from_ptr(vm, ptr)?)? {
SyscallSelector::CallContract => run_handler(&mut syscall_handler.call_contract_handler, ptr, vm).await,
SyscallSelector::Keccak => run_handler(&mut syscall_handler.keccak_handler, ptr, vm).await,
}?;

syscall_handler.syscall_ptr = Some(*ptr);

Ok(())
}
}

#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct CallContractHandlerRelay {
pub evm_call_contract_handler: EvmCallContractHandler,
pub starknet_call_contract_handler: StarknetCallContractHandler,
#[serde(skip)]
pub debug_call_contract_handler: DebugCallContractHandler,
#[serde(skip)]
pub any_type_call_contract_handler: AnyTypeCallContractHandler,
}

impl traits::SyscallHandler for CallContractHandlerRelay {
type Request = CallContractRequest;
type Response = CallContractResponse;

fn read_request(&mut self, vm: &VirtualMachine, ptr: &mut Relocatable) -> SyscallResult<Self::Request> {
let ret = Self::Request::from_memory(vm, *ptr)?;
*ptr = (*ptr + Self::Request::cairo_size())?;
Ok(ret)
}

async fn execute(&mut self, request: Self::Request, vm: &mut VirtualMachine) -> SyscallResult<Self::Response> {
match request.contract_address {
v if v == call_contract::debug::CONTRACT_ADDRESS => self.debug_call_contract_handler.execute(request, vm).await,
v if v == call_contract::any_type::CONTRACT_ADDRESS => self.any_type_call_contract_handler.execute(request, vm).await,
_ => {
let chain_id = <Felt252 as TryInto<u128>>::try_into(*vm.get_integer((request.calldata_start + 2)?)?)
.map_err(|e| SyscallExecutionError::InternalError(e.to_string().into()))?;

match chain_id {
ETHEREUM_MAINNET_CHAIN_ID | ETHEREUM_TESTNET_CHAIN_ID => self.evm_call_contract_handler.execute(request, vm).await,
STARKNET_MAINNET_CHAIN_ID | STARKNET_TESTNET_CHAIN_ID => self.starknet_call_contract_handler.execute(request, vm).await,
_ => Err(SyscallExecutionError::InternalError(Box::from("Unknown chain id"))),
}
}
}
}

fn write_response(&mut self, response: Self::Response, vm: &mut VirtualMachine, ptr: &mut Relocatable) -> WriteResponseResult {
response.to_memory(vm, *ptr)?;
*ptr = (*ptr + Self::Response::cairo_size())?;
Ok(())
}
}
use syscall_handler::SyscallHandlerWrapper;

pub const SYSCALL_HANDLER_CREATE_MOCK: &str =
"if 'syscall_handler' not in globals():\n syscall_handler = SyscallHandler(segments=segments, dict_manager=__dict_manager)";
Expand All @@ -132,7 +21,7 @@ pub fn syscall_handler_create_mock(
_hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
exec_scopes.get::<SyscallHandlerWrapper>(vars::scopes::SYSCALL_HANDLER)?;
exec_scopes.get::<SyscallHandlerWrapper<evm::CallContractHandler, starknet::CallContractHandler>>(vars::scopes::SYSCALL_HANDLER)?;
Ok(())
}

Expand All @@ -144,7 +33,10 @@ pub fn syscall_handler_create(
_hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let syscall_handler = SyscallHandlerWrapper::new();
let syscall_handler = SyscallHandlerWrapper::<evm::CallContractHandler, starknet::CallContractHandler>::new(
evm::CallContractHandler::default(),
starknet::CallContractHandler::default(),
);
exec_scopes.insert_value(vars::scopes::SYSCALL_HANDLER, syscall_handler);

Ok(())
Expand All @@ -159,7 +51,8 @@ pub fn syscall_handler_set_syscall_ptr(
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let syscall_ptr = get_ptr_from_var_name(vars::ids::SYSCALL_PTR, vm, &hint_data.ids_data, &hint_data.ap_tracking)?;
let syscall_handler = exec_scopes.get_mut_ref::<SyscallHandlerWrapper>(vars::scopes::SYSCALL_HANDLER)?;
let syscall_handler = exec_scopes
.get_mut_ref::<SyscallHandlerWrapper<evm::CallContractHandler, starknet::CallContractHandler>>(vars::scopes::SYSCALL_HANDLER)?;
syscall_handler.set_syscall_ptr(syscall_ptr);

Ok(())
Expand All @@ -173,7 +66,9 @@ pub fn enter_scope_syscall_handler(
_hint_data: &HintProcessorData,
_constants: &HashMap<String, Felt252>,
) -> Result<(), HintError> {
let syscall_handler: Box<dyn Any> = Box::new(exec_scopes.get::<SyscallHandlerWrapper>(vars::scopes::SYSCALL_HANDLER)?);
let syscall_handler: Box<dyn Any> = Box::new(
exec_scopes.get::<SyscallHandlerWrapper<evm::CallContractHandler, starknet::CallContractHandler>>(vars::scopes::SYSCALL_HANDLER)?,
);
exec_scopes.enter_scope(HashMap::from_iter([(vars::scopes::SYSCALL_HANDLER.to_string(), syscall_handler)]));

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ use types::{
traits::CairoType,
},
keys::starknet::header::{CairoKey, Key},
RPC_URL_FEEDER_GATEWAY,
RPC_URL_FEEDER_GATEWAY, STARKNET_MAINNET_CHAIN_ID, STARKNET_TESTNET_CHAIN_ID,
};

use crate::syscall_handler::{STARKNET_MAINNET_CHAIN_ID, STARKNET_TESTNET_CHAIN_ID};

#[derive(Debug, Default)]
pub struct HeaderCallHandler;

Expand Down
1 change: 1 addition & 0 deletions crates/dry_run/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ tokio.workspace = true
tracing-subscriber.workspace = true
tracing.workspace = true
types.workspace = true
syscall_handler.workspace = true

[build-dependencies]
sha2 = "0.10.6"
7 changes: 4 additions & 3 deletions crates/dry_run/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ use cairo_vm::{
};
use clap::Parser;
use dry_hint_processor::{
syscall_handler::{SyscallHandler, SyscallHandlerWrapper},
syscall_handler::{evm, starknet},
CustomHintProcessor,
};
use hints::vars;
use syscall_handler::{SyscallHandler, SyscallHandlerWrapper};
use tracing::debug;
use types::{error::Error, HDPDryRunInput};

Expand Down Expand Up @@ -113,10 +114,10 @@ async fn main() -> Result<(), Error> {

std::fs::write(
args.program_output,
serde_json::to_vec::<SyscallHandler>(
serde_json::to_vec::<SyscallHandler<evm::CallContractHandler, starknet::CallContractHandler>>(
&cairo_runner
.exec_scopes
.get::<SyscallHandlerWrapper>(vars::scopes::SYSCALL_HANDLER)
.get::<SyscallHandlerWrapper<evm::CallContractHandler, starknet::CallContractHandler>>(vars::scopes::SYSCALL_HANDLER)
.unwrap()
.syscall_handler
.try_read()
Expand Down
1 change: 1 addition & 0 deletions crates/fetcher/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ thiserror.workspace = true
tokio.workspace = true
types.workspace = true
eth-trie-proofs.workspace = true
syscall_handler.workspace = true

[features]
default = []
Expand Down
7 changes: 5 additions & 2 deletions crates/fetcher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use std::{
};

use alloy::hex::FromHexError;
use dry_hint_processor::syscall_handler::{evm, starknet, SyscallHandler};
use dry_hint_processor::syscall_handler::{evm, starknet};
use futures::StreamExt;
use indexer::models::IndexerError;
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use proof_keys::{evm::ProofKeys as EvmProofKeys, starknet::ProofKeys as StarknetProofKeys, ProofKeys};
use starknet_types_core::felt::FromStrError;
use syscall_handler::SyscallHandler;
use thiserror::Error;
use types::proofs::{
evm::{
Expand Down Expand Up @@ -356,7 +357,9 @@ where
.collect()
}

pub fn parse_syscall_handler(syscall_handler: SyscallHandler) -> Result<ProofKeys, FetcherError> {
pub fn parse_syscall_handler(
syscall_handler: SyscallHandler<evm::CallContractHandler, starknet::CallContractHandler>,
) -> Result<ProofKeys, FetcherError> {
let mut proof_keys = ProofKeys::default();

// Process EVM keys
Expand Down
5 changes: 3 additions & 2 deletions crates/fetcher/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::{fs, path::PathBuf};

use clap::{Parser, ValueHint};
use dry_hint_processor::syscall_handler::SyscallHandler;
use dry_hint_processor::syscall_handler::{evm, starknet};
use fetcher::{parse_syscall_handler, Fetcher};
use syscall_handler::SyscallHandler;
use types::ChainProofs;

#[derive(Parser, Debug)]
Expand All @@ -19,7 +20,7 @@ async fn main() -> Result<(), fetcher::FetcherError> {
let args = Args::try_parse_from(std::env::args()).map_err(fetcher::FetcherError::Args)?;
let input_file = fs::read(&args.filename)?;

let syscall_handler: SyscallHandler = serde_json::from_slice(&input_file)?;
let syscall_handler: SyscallHandler<evm::CallContractHandler, starknet::CallContractHandler> = serde_json::from_slice(&input_file)?;
let proof_keys = parse_syscall_handler(syscall_handler)?;

let fetcher = Fetcher::new(&proof_keys);
Expand Down
1 change: 1 addition & 0 deletions crates/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ tracing-subscriber.workspace = true
types.workspace = true
utoipa.workspace = true
utoipa-swagger-ui.workspace = true
syscall_handler.workspace = true

[dev-dependencies]
http-body-util.workspace = true
Expand Down
9 changes: 6 additions & 3 deletions crates/server/src/dry_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ use cairo_vm::{
};
use dry_hint_processor::{
CustomHintProcessor,
syscall_handler::{SyscallHandler, SyscallHandlerWrapper},
syscall_handler::{evm, starknet},
};
use hints::vars;
use serde::Deserialize;
use syscall_handler::{SyscallHandler, SyscallHandlerWrapper};
use types::{HDPDryRunInput, error::Error};

use crate::error::AppError;
Expand All @@ -27,7 +28,9 @@ pub struct DryRunRequest {
path = "/dry_run",
request_body = ref("DryRunRequest") // TODO implement ToSchema (big and tedious task impl when explicitly needed)
)]
pub async fn root(Json(value): Json<DryRunRequest>) -> Result<Json<SyscallHandler>, AppError> {
pub async fn root(
Json(value): Json<DryRunRequest>,
) -> Result<Json<SyscallHandler<evm::CallContractHandler, starknet::CallContractHandler>>, AppError> {
// Init CairoRunConfig
let cairo_run_config = cairo_run::CairoRunConfig {
trace_enabled: false,
Expand Down Expand Up @@ -55,7 +58,7 @@ pub async fn root(Json(value): Json<DryRunRequest>) -> Result<Json<SyscallHandle
Ok(Json(
cairo_runner
.exec_scopes
.get::<SyscallHandlerWrapper>(vars::scopes::SYSCALL_HANDLER)?
.get::<SyscallHandlerWrapper<evm::CallContractHandler, starknet::CallContractHandler>>(vars::scopes::SYSCALL_HANDLER)?
.syscall_handler
.try_read()?
.clone(),
Expand Down
Loading

0 comments on commit 2f0406a

Please sign in to comment.