Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 45 additions & 20 deletions vm/rust/src/jsonrpc.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
use blockifier;
use blockifier::execution::entry_point::CallType;
use blockifier::execution::call_info::OrderedL2ToL1Message;
use cairo_vm::vm::runners::builtin_runner::{
BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME,
POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, KECCAK_BUILTIN_NAME,
SEGMENT_ARENA_BUILTIN_NAME,
};
use blockifier::execution::entry_point::CallType;
use blockifier::state::cached_state::TransactionalState;
use blockifier::state::errors::StateError;
use blockifier::state::state_api::{State, StateReader};
use cairo_vm::vm::runners::builtin_runner::{
BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, KECCAK_BUILTIN_NAME,
POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, SEGMENT_ARENA_BUILTIN_NAME,
SIGNATURE_BUILTIN_NAME,
};
use serde::Serialize;
use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, PatriciaKey, EthAddress};
use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, EthAddress, PatriciaKey};
use starknet_api::deprecated_contract_class::EntryPointType;
use starknet_api::hash::StarkFelt;
use starknet_api::transaction::{Calldata, EventContent, L2ToL1Payload};
use starknet_api::transaction::{DeclareTransaction, Transaction as StarknetApiTransaction};

use crate::juno_state_reader::JunoStateReader;

#[derive(Serialize, Default)]
#[serde(rename_all = "UPPERCASE")]
pub enum TransactionType {
// dummy type for implementing Default trait
#[default] Unknown,
#[default]
Unknown,
Invoke,
Declare,
#[serde(rename = "DEPLOY_ACCOUNT")]
Expand Down Expand Up @@ -124,7 +123,7 @@ type BlockifierTxInfo = blockifier::transaction::objects::TransactionExecutionIn
pub fn new_transaction_trace(
tx: &StarknetApiTransaction,
info: BlockifierTxInfo,
state: &mut TransactionalState<JunoStateReader>,
state: &mut TransactionalState<MemState>,
) -> Result<TransactionTrace, StateError> {
let mut trace = TransactionTrace::default();
let mut deprecated_declared_class: Option<ClassHash> = None;
Expand Down Expand Up @@ -225,14 +224,38 @@ impl From<VmExecutionResources> for ExecutionResources {
} else {
None
},
range_check_builtin_applications: val.builtin_instance_counter.get(RANGE_CHECK_BUILTIN_NAME).cloned(),
pedersen_builtin_applications: val.builtin_instance_counter.get(HASH_BUILTIN_NAME).cloned(),
poseidon_builtin_applications: val.builtin_instance_counter.get(POSEIDON_BUILTIN_NAME).cloned(),
ec_op_builtin_applications: val.builtin_instance_counter.get(EC_OP_BUILTIN_NAME).cloned(),
ecdsa_builtin_applications: val.builtin_instance_counter.get(SIGNATURE_BUILTIN_NAME).cloned(),
bitwise_builtin_applications: val.builtin_instance_counter.get(BITWISE_BUILTIN_NAME).cloned(),
keccak_builtin_applications: val.builtin_instance_counter.get(KECCAK_BUILTIN_NAME).cloned(),
segment_arena_builtin: val.builtin_instance_counter.get(SEGMENT_ARENA_BUILTIN_NAME).cloned(),
range_check_builtin_applications: val
.builtin_instance_counter
.get(RANGE_CHECK_BUILTIN_NAME)
.cloned(),
pedersen_builtin_applications: val
.builtin_instance_counter
.get(HASH_BUILTIN_NAME)
.cloned(),
poseidon_builtin_applications: val
.builtin_instance_counter
.get(POSEIDON_BUILTIN_NAME)
.cloned(),
ec_op_builtin_applications: val
.builtin_instance_counter
.get(EC_OP_BUILTIN_NAME)
.cloned(),
ecdsa_builtin_applications: val
.builtin_instance_counter
.get(SIGNATURE_BUILTIN_NAME)
.cloned(),
bitwise_builtin_applications: val
.builtin_instance_counter
.get(BITWISE_BUILTIN_NAME)
.cloned(),
keccak_builtin_applications: val
.builtin_instance_counter
.get(KECCAK_BUILTIN_NAME)
.cloned(),
segment_arena_builtin: val
.builtin_instance_counter
.get(SEGMENT_ARENA_BUILTIN_NAME)
.cloned(),
}
}
}
Expand Down Expand Up @@ -262,7 +285,9 @@ impl FunctionInvocation {
}
}

use crate::MemState;
use blockifier::execution::call_info::CallInfo as BlockifierCallInfo;

impl From<BlockifierCallInfo> for FunctionInvocation {
fn from(val: BlockifierCallInfo) -> Self {
FunctionInvocation {
Expand Down Expand Up @@ -327,7 +352,7 @@ impl From<OrderedL2ToL1Message> for OrderedMessage {
pub struct Retdata(pub Vec<StarkFelt>);

fn make_state_diff(
state: &mut TransactionalState<JunoStateReader>,
state: &mut TransactionalState<MemState>,
deprecated_declared_class: Option<ClassHash>,
) -> Result<StateDiff, StateError> {
let diff = state.to_state_diff();
Expand Down
5 changes: 4 additions & 1 deletion vm/rust/src/juno_state_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,9 @@ pub fn contract_class_from_json_str(raw_json: &str) -> Result<ContractClass, Str
if let Ok(class) = v1_class {
Ok(class.into())
} else {
Err(format!("not a valid contract class: {}", v1_class.err().unwrap()))
Err(format!(
"not a valid contract class: {}",
v1_class.err().unwrap()
))
}
}
76 changes: 47 additions & 29 deletions vm/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
pub mod jsonrpc;
mod juno_state_reader;
mod mem_state;

use crate::juno_state_reader::{ptr_to_felt, JunoStateReader};
use crate::juno_state_reader::ptr_to_felt;
use std::{
collections::HashMap,
ffi::{c_char, c_uchar, c_ulonglong, c_void, c_longlong, CStr, CString},
ffi::{c_char, c_longlong, c_uchar, c_ulonglong, c_void, CStr, CString},
slice,
};

use blockifier::{
abi::constants::{INITIAL_GAS_COST, N_STEPS_RESOURCE, MAX_STEPS_PER_TX, MAX_VALIDATE_STEPS_PER_TX},
block_context::{BlockContext, GasPrices, FeeTokenAddresses},
abi::constants::{
INITIAL_GAS_COST, MAX_STEPS_PER_TX, MAX_VALIDATE_STEPS_PER_TX, N_STEPS_RESOURCE,
},
block_context::{BlockContext, FeeTokenAddresses, GasPrices},
execution::{
common_hints::ExecutionMode,
contract_class::ContractClass,
Expand All @@ -19,14 +22,14 @@ use blockifier::{
fee::fee_utils::calculate_tx_fee,
state::cached_state::{CachedState, GlobalContractCache},
transaction::{
objects::{AccountTransactionContext, DeprecatedAccountTransactionContext, HasRelatedFeeType},
transaction_execution::Transaction,
transactions::ExecutableTransaction,
errors::TransactionExecutionError::{
ContractConstructorExecutionFailed,
ExecutionError,
ValidateTransactionError,
ContractConstructorExecutionFailed, ExecutionError, ValidateTransactionError,
},
objects::{
AccountTransactionContext, DeprecatedAccountTransactionContext, HasRelatedFeeType,
},
transaction_execution::Transaction,
transactions::ExecutableTransaction,
},
};
use cairo_vm::vm::runners::builtin_runner::{
Expand All @@ -35,6 +38,7 @@ use cairo_vm::vm::runners::builtin_runner::{
SEGMENT_ARENA_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME,
};
use juno_state_reader::{contract_class_from_json_str, felt_to_byte_array};
use mem_state::MemState;
use serde::Deserialize;
use starknet_api::transaction::{Calldata, Transaction as StarknetApiTransaction, TransactionHash};
use starknet_api::{
Expand Down Expand Up @@ -70,7 +74,7 @@ pub extern "C" fn cairoVMCall(
chain_id: *const c_char,
max_steps: c_ulonglong,
) {
let reader = JunoStateReader::new(reader_handle, block_number);
let mem_state = MemState::new(block_number);
let contract_addr_felt = ptr_to_felt(contract_address);
let class_hash = if class_hash.is_null() {
None
Expand Down Expand Up @@ -105,7 +109,7 @@ pub extern "C" fn cairoVMCall(
eth_l1_gas_price: 1,
strk_l1_gas_price: 1,
};
let mut state = CachedState::new(reader, GlobalContractCache::default());
let mut state = CachedState::new(mem_state, GlobalContractCache::default());
let mut resources = ExecutionResources::default();
let context = EntryPointExecutionContext::new(
&build_block_context(
Expand Down Expand Up @@ -160,7 +164,7 @@ pub extern "C" fn cairoVMExecute(
gas_price_strk: *const c_uchar,
legacy_json: c_uchar,
) {
let reader = JunoStateReader::new(reader_handle, block_number);
let mem_state = MemState::new(block_number);
let chain_id_str = unsafe { CStr::from_ptr(chain_id) }.to_str().unwrap();
let txn_json_str = unsafe { CStr::from_ptr(txns_json) }.to_str().unwrap();
let txns_and_query_bits: Result<Vec<TxnAndQueryBit>, serde_json::Error> =
Expand Down Expand Up @@ -206,9 +210,9 @@ pub extern "C" fn cairoVMExecute(
eth_l1_gas_price: felt_to_u128(gas_price_wei_felt),
strk_l1_gas_price: felt_to_u128(gas_price_strk_felt),
},
None
None,
);
let mut state = CachedState::new(reader, GlobalContractCache::default());
let mut state = CachedState::new(mem_state, GlobalContractCache::default());
let charge_fee = skip_charge_fee == 0;
let validate = skip_validate == 0;

Expand Down Expand Up @@ -273,36 +277,35 @@ pub extern "C" fn cairoVMExecute(
Err(error) => {
let err_string = match &error {
ContractConstructorExecutionFailed(e)
| ExecutionError(e)
| ValidateTransactionError(e) => format!("{error} {e}"),
other => other.to_string()
| ExecutionError(e)
| ValidateTransactionError(e) => format!("{error} {e}"),
other => other.to_string(),
};
report_error(
reader_handle,
format!(
"failed txn {} reason: {}",
txn_and_query_bit.txn_hash,
err_string,
txn_and_query_bit.txn_hash, err_string,
)
.as_str(),
txn_index as i64
txn_index as i64,
);
return;
}
Ok(mut t) => {
if t.is_reverted() && err_on_revert != 0 {
report_error(
reader_handle,
format!("reverted: {}", t.revert_error.unwrap())
.as_str(),
txn_index as i64
format!("reverted: {}", t.revert_error.unwrap()).as_str(),
txn_index as i64,
);
return;
}

// we are estimating fee, override actual fee calculation
if !charge_fee {
t.actual_fee = calculate_tx_fee(&t.actual_resources, &block_context, &fee_type).unwrap();
t.actual_fee =
calculate_tx_fee(&t.actual_resources, &block_context, &fee_type).unwrap();
}

let actual_fee = t.actual_fee.0.into();
Expand All @@ -316,7 +319,7 @@ pub extern "C" fn cairoVMExecute(
trace.err().unwrap()
)
.as_str(),
txn_index as i64
txn_index as i64,
);
return;
}
Expand Down Expand Up @@ -410,8 +413,20 @@ fn build_block_context(
// https://github.com/starknet-io/starknet-addresses/blob/df19b17d2c83f11c30e65e2373e8a0c65446f17c/bridged_tokens/mainnet.json
fee_token_addresses: FeeTokenAddresses {
// both addresses are the same for all networks
eth_fee_token_address: ContractAddress::try_from(StarkHash::try_from("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").unwrap()).unwrap(),
strk_fee_token_address: ContractAddress::try_from(StarkHash::try_from("0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d").unwrap()).unwrap(),
eth_fee_token_address: ContractAddress::try_from(
StarkHash::try_from(
"0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
)
.unwrap(),
)
.unwrap(),
strk_fee_token_address: ContractAddress::try_from(
StarkHash::try_from(
"0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
)
.unwrap(),
)
.unwrap(),
},
gas_prices, // fixed gas price, so that we can return "consumed gas" to Go side
vm_resource_fee_cost: HashMap::from([
Expand All @@ -436,7 +451,10 @@ fn build_block_context(
(KECCAK_BUILTIN_NAME.to_string(), N_STEPS_FEE_WEIGHT * 2048.0),
])
.into(),
invoke_tx_max_n_steps: max_steps.unwrap_or(MAX_STEPS_PER_TX as u64).try_into().unwrap(),
invoke_tx_max_n_steps: max_steps
.unwrap_or(MAX_STEPS_PER_TX as u64)
.try_into()
.unwrap(),
validate_max_n_steps: MAX_VALIDATE_STEPS_PER_TX as u32,
max_recursion_depth: 50,
}
Expand Down
Loading