Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
kariy committed Feb 26, 2025
1 parent aafa666 commit 2f2e544
Show file tree
Hide file tree
Showing 21 changed files with 1,281 additions and 578 deletions.
1,032 changes: 723 additions & 309 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,6 @@ walkdir = "2.5.0"
ipfs-api-backend-hyper = { git = "https://github.com/ferristseng/rust-ipfs-api", rev = "af2c17f7b19ef5b9898f458d97a90055c3605633", features = [ "with-hyper-rustls", "with-send-sync" ] }
mime_guess = "2.0"


# server
hyper = "0.14.27"
warp = "0.3"
Expand Down
2 changes: 1 addition & 1 deletion crates/katana/cairo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ cairo-lang-starknet = "2.7.0"
cairo-lang-starknet-classes = "2.7.0"
cairo-lang-utils = "2.7.0"
cairo-vm = "1.0.1"
starknet_api = { git = "https://github.com/dojoengine/sequencer", rev = "d860f498" }
starknet_api = { git = "https://github.com/dojoengine/sequencer", rev = "1010caec" }

[features]
# Some types that we used from cairo-vm implements the `Arbitrary` trait,
Expand Down
7 changes: 4 additions & 3 deletions crates/katana/cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,10 @@ impl NodeArgs {
}

fn init_logging(&self) -> Result<()> {
const DEFAULT_LOG_FILTER: &str =
"pipeline=debug,stage=debug,info,tasks=debug,executor=trace,forking::backend=trace,\
blockifier=off,jsonrpsee_server=off,hyper=off,messaging=debug,node=error";
const DEFAULT_LOG_FILTER: &str = "cairo_native::compiler=off,pipeline=debug,stage=debug,\
info,tasks=debug,executor=trace,forking::backend=trace,\
blockifier=off,jsonrpsee_server=off,hyper=off,\
messaging=debug,node=error";

let filter = if self.development.dev {
&format!("{DEFAULT_LOG_FILTER},server=debug")
Expand Down
39 changes: 36 additions & 3 deletions crates/katana/executor/.env.cairo-native
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
export MLIR_SYS_170_PREFIX=/opt/homebrew/opt/llvm@17
export LLVM_SYS_170_PREFIX=/opt/homebrew/opt/llvm@17
export TABLEGEN_170_PREFIX=/opt/homebrew/opt/llvm@17
#!/bin/sh

# Taken from `lambdaclass/cairo_native`.
#
# It sets the LLVM environment variables.
#
# You can copy this file to .envrc/.env and adapt it for your environment.

case $(uname) in
Darwin)
# If installed with brew
LIBRARY_PATH=/opt/homebrew/lib
MLIR_SYS_190_PREFIX="$(brew --prefix llvm@19)"
LLVM_SYS_191_PREFIX="$(brew --prefix llvm@19)"
TABLEGEN_190_PREFIX="$(brew --prefix llvm@19)"
CAIRO_NATIVE_RUNTIME_LIBRARY="$(pwd)/target/release/libcairo_native_runtime.a"

export LIBRARY_PATH
export MLIR_SYS_190_PREFIX
export LLVM_SYS_191_PREFIX
export TABLEGEN_190_PREFIX
export CAIRO_NATIVE_RUNTIME_LIBRARY
;;
Linux)
# If installed from Debian/Ubuntu repository:
MLIR_SYS_190_PREFIX=/usr/lib/llvm-19
LLVM_SYS_191_PREFIX=/usr/lib/llvm-19
TABLEGEN_190_PREFIX=/usr/lib/llvm-19
CAIRO_NATIVE_RUNTIME_LIBRARY="$(pwd)/target/release/libcairo_native_runtime.a"

export MLIR_SYS_190_PREFIX
export LLVM_SYS_191_PREFIX
export TABLEGEN_190_PREFIX
export CAIRO_NATIVE_RUNTIME_LIBRARY
;;
esac
6 changes: 5 additions & 1 deletion crates/katana/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ katana-provider.workspace = true
thiserror.workspace = true
tracing.workspace = true

blockifier = { git = "https://github.com/dojoengine/sequencer", rev = "d860f498", features = [ "testing" ], optional = true }
blockifier = { git = "https://github.com/dojoengine/sequencer", rev = "1010caec", features = [ "testing" ], optional = true }
cairo-native = "0.2.4"
parking_lot = { workspace = true, optional = true }
quick_cache = "0.6.10"
rayon.workspace = true
starknet = { workspace = true, optional = true }

[dev-dependencies]
Expand Down Expand Up @@ -45,6 +48,7 @@ blockifier = [
"dep:parking_lot",
"dep:starknet",
]
cairo-native = [ "blockifier/cairo_native" ]
default = [ "blockifier" ]

[[bench]]
Expand Down
112 changes: 112 additions & 0 deletions crates/katana/executor/src/implementation/blockifier/cache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use std::collections::HashMap;
use std::str::FromStr;
use std::sync::{Arc, LazyLock};

use blockifier::execution::contract_class::{CompiledClassV1, RunnableCompiledClass};
use blockifier::execution::native::contract_class::NativeCompiledClassV1;
use cairo_native::executor::AotContractExecutor;
use cairo_native::OptLevel;
use katana_cairo::starknet_api::contract_class::SierraVersion;
use katana_primitives::class::{ClassHash, CompiledClass, ContractClass};
use parking_lot::Mutex;
use quick_cache::sync::Cache;
use rayon::ThreadPoolBuilder;
use tracing::trace;

use super::utils::to_class;

pub static COMPILED_CLASS_CACHE: LazyLock<ClassCache> =
LazyLock::new(|| ClassCache::new().unwrap());

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[cfg(feature = "cairo-native")]
#[error(transparent)]
FailedToCreateThreadPool(#[from] rayon::ThreadPoolBuildError),
}

#[derive(Debug, Clone)]
pub struct ClassCache {
inner: Arc<Inner>,
}

#[derive(Debug)]
struct Inner {
#[cfg(feature = "cairo-native")]
pool: rayon::ThreadPool,
cache: Cache<ClassHash, RunnableCompiledClass>,
}

impl ClassCache {
pub fn new() -> Result<Self, Error> {
const CACHE_SIZE: usize = 100;
let cache = Cache::new(CACHE_SIZE);

#[cfg(feature = "cairo-native")]
let pool = ThreadPoolBuilder::new()
.num_threads(3)
.thread_name(|i| format!("cache-native-compiler-{i}"))
.build()?;

Ok(Self {
inner: Arc::new(Inner {
cache,
#[cfg(feature = "cairo-native")]
pool,
}),
})
}

pub fn get(&self, hash: &ClassHash) -> Option<RunnableCompiledClass> {
self.inner.cache.get(hash)
}

pub fn insert(&self, hash: ClassHash, class: ContractClass) -> RunnableCompiledClass {
match class {
ContractClass::Legacy(..) => {
let class = class.compile().unwrap();
let class = to_class(class).unwrap();
self.inner.cache.insert(hash, class.clone());
class
}

ContractClass::Class(ref sierra) => {
#[cfg(feature = "cairo-native")]
let program = sierra.extract_sierra_program().unwrap();
#[cfg(feature = "cairo-native")]
let entry_points = sierra.entry_points_by_type.clone();

let CompiledClass::Class(casm) = class.compile().unwrap() else {
unreachable!("cant be legacy")
};

let version = SierraVersion::from_str(&casm.compiler_version).unwrap();
let compiled = CompiledClassV1::try_from((casm, version)).unwrap();

#[cfg(feature = "cairo-native")]
let inner = self.inner.clone();
#[cfg(feature = "cairo-native")]
let compiled_clone = compiled.clone();

#[cfg(feature = "cairo-native")]
self.inner.pool.spawn(move || {
trace!(target: "class_cache", class = format!("{hash:#x}"), "Compiling native class");

let executor =
AotContractExecutor::new(&program, &entry_points, OptLevel::Default)
.unwrap();

let native = NativeCompiledClassV1::new(executor, compiled_clone);
inner.cache.insert(hash, RunnableCompiledClass::V1Native(native));

trace!(target: "class_cache", class = format!("{hash:#x}"), "Native class compiled")
});

let class = RunnableCompiledClass::V1(compiled);
self.inner.cache.insert(hash, class.clone());

class
}
}
}
}
29 changes: 17 additions & 12 deletions crates/katana/executor/src/implementation/blockifier/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ use std::sync::Arc;
use blockifier::context::{BlockContext, TransactionContext};
use blockifier::execution::call_info::CallInfo;
use blockifier::execution::entry_point::{
CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult,
CallEntryPoint, EntryPointExecutionContext, EntryPointExecutionResult, SierraGasRevertTracker,
};
use blockifier::state::cached_state::CachedState;
use blockifier::state::state_api::StateReader;
use blockifier::transaction::objects::{DeprecatedTransactionInfo, TransactionInfo};
use katana_cairo::cairo_vm::vm::runners::cairo_runner::{ExecutionResources, RunResources};
use katana_cairo::cairo_vm::vm::runners::cairo_runner::RunResources;
use katana_cairo::starknet_api::core::EntryPointSelector;
use katana_cairo::starknet_api::transaction::Calldata;
use katana_cairo::starknet_api::execution_resources::GasAmount;
use katana_cairo::starknet_api::transaction::fields::Calldata;
use katana_primitives::Felt;

use super::utils::to_blk_address;
Expand Down Expand Up @@ -54,20 +55,24 @@ fn execute_call_inner<S: StateReader>(
// The values for these parameters are essentially useless as we manually set the run resources
// later anyway.
let limit_steps_by_resources = true;
let tx_info = DeprecatedTransactionInfo::default();

let tx_context = Arc::new(TransactionContext {
block_context: block_context.clone(),
tx_info: TransactionInfo::Deprecated(DeprecatedTransactionInfo::default()),
});

let sierra_revert_tracker = SierraGasRevertTracker::new(GasAmount(max_gas));
let mut ctx = EntryPointExecutionContext::new_invoke(
Arc::new(TransactionContext {
block_context: block_context.clone(),
tx_info: TransactionInfo::Deprecated(tx_info),
}),
tx_context,
limit_steps_by_resources,
)
.unwrap();
sierra_revert_tracker,
);

// manually override the run resources
ctx.vm_run_resources = RunResources::new(max_gas as usize);
call.execute(state, &mut ExecutionResources::default(), &mut ctx)
// If `initial_gas` can't fit in a usize, use the maximum.
ctx.vm_run_resources = RunResources::new(max_gas.try_into().unwrap_or(usize::MAX));
let mut remaining_gas = call.initial_gas;
call.execute(state, &mut ctx, &mut remaining_gas)
}

#[cfg(test)]
Expand Down
6 changes: 3 additions & 3 deletions crates/katana/executor/src/implementation/blockifier/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use blockifier::blockifier::transaction_executor::TransactionExecutorError;
use blockifier::execution::errors::{EntryPointExecutionError, PreExecutionError};
use blockifier::execution::execution_utils::format_panic_data;
use blockifier::state::errors::StateError;
use blockifier::transaction::errors::{
TransactionExecutionError, TransactionFeeError, TransactionPreValidationError,
Expand Down Expand Up @@ -33,8 +32,8 @@ impl From<TransactionExecutionError> for ExecutionError {
impl From<EntryPointExecutionError> for ExecutionError {
fn from(error: EntryPointExecutionError) -> Self {
match error {
EntryPointExecutionError::ExecutionFailed { error_data } => {
Self::ExecutionFailed { reason: format_panic_data(&error_data) }
EntryPointExecutionError::ExecutionFailed { error_trace } => {
Self::ExecutionFailed { reason: error_trace.to_string() }
}
EntryPointExecutionError::InvalidExecutionInput { input_descriptor, info } => {
Self::InvalidInput { input_descriptor, info }
Expand Down Expand Up @@ -107,6 +106,7 @@ impl From<TransactionExecutorError> for ExecutorError {
match value {
TransactionExecutorError::BlockFull => Self::LimitsExhausted,
TransactionExecutorError::StateError(e) => Self::Other(e.into()),
TransactionExecutorError::CompressionError(e) => Self::Other(e.into()),
TransactionExecutorError::TransactionExecutionError(e) => Self::Other(e.into()),
}
}
Expand Down
Loading

0 comments on commit 2f2e544

Please sign in to comment.