From 28b1e911a3ef32e0ab61649d53ebf8ead9cd3062 Mon Sep 17 00:00:00 2001 From: juanbono Date: Tue, 2 Jan 2024 19:32:29 -0300 Subject: [PATCH 1/3] add get_storage_at implementation --- Cargo.toml | 2 +- src/rpc/starknet_backend.rs | 47 +++++++++++++++++++++++++++---------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8e1f46f97..2fc02ba15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,4 @@ cairo-felt = "0.8.0" serde_with = "3.0.0" starknet-core = "0.8.0" tokio = { version = "1.5.0", features = ["sync", "rt", "macros"] } - +starknet_in_rust = { git = "https://github.com/lambdaclass/starknet_in_rust" } diff --git a/src/rpc/starknet_backend.rs b/src/rpc/starknet_backend.rs index c594568c1..311c37183 100644 --- a/src/rpc/starknet_backend.rs +++ b/src/rpc/starknet_backend.rs @@ -3,24 +3,38 @@ use crate::rpc::{ BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction, ContractClass, DeclareTransactionResult, DeployAccountTransactionResult, EventFilterWithPage, EventsPage, FeeEstimate, FunctionCall, InvokeTransactionResult, MaybePendingBlockWithTxHashes, - MaybePendingBlockWithTxs, MaybePendingTransactionReceipt, StateUpdate, - SyncStatusType, Transaction, + MaybePendingBlockWithTxs, MaybePendingTransactionReceipt, StateUpdate, SyncStatusType, + Transaction, }; use cairo_felt::Felt252; -use jsonrpsee:: - core::{async_trait, RpcResult}; -use starknet_core::types::{TransactionStatus, SimulatedTransaction, SimulationFlag}; +use jsonrpsee::{ + core::{async_trait, RpcResult}, + types::{error::ErrorCode, ErrorObject}, +}; +use starknet_core::types::{SimulatedTransaction, SimulationFlag, TransactionStatus}; +use starknet_in_rust::{ + state::{ + cached_state::CachedState, contract_class_cache::PermanentContractClassCache, + in_memory_state_reader::InMemoryStateReader, state_api::StateReader, + }, + utils::Address, +}; use super::StarknetRpcApiServer; +type StarknetState = CachedState; + pub struct StarknetBackend { // mempool_handler: Mempool, // store: Store, + state: StarknetState, } impl StarknetBackend { pub fn new() -> StarknetBackend { - StarknetBackend {} + StarknetBackend { + state: Default::default(), + } } } @@ -35,7 +49,6 @@ impl StarknetRpcApiServer for StarknetBackend { unimplemented!() } - /// Returns the execution trace of a transaction by simulating it in the runtime. async fn simulate_transactions( &self, @@ -75,9 +88,12 @@ impl StarknetRpcApiServer for StarknetBackend { &self, contract_address: FeltParam, key: FeltParam, - block_id: BlockId, + _block_id: BlockId, ) -> RpcResult { - unimplemented!(); + let address = Address(contract_address.0); + self.state + .get_storage_at(&(address, key.0.to_be_bytes())) + .map_err(|_| ErrorObject::from(ErrorCode::InternalError)) } fn call(&self, request: FunctionCall, block_id: BlockId) -> RpcResult> { @@ -87,10 +103,17 @@ impl StarknetRpcApiServer for StarknetBackend { /// Get the contract class at a given contract address for a given block id fn get_class_at( &self, - block_id: BlockId, + _block_id: BlockId, contract_address: FeltParam, ) -> RpcResult { - unimplemented!(); + let address = Address(contract_address.0); + let classhash = self + .state + .get_class_hash_at(&address) + .map_err(|_| ErrorObject::from(ErrorCode::InternalError))?; + self.state + .get_contract_class(&classhash) + .map_err(|_| ErrorObject::from(ErrorCode::InternalError)) } /// Get the contract class hash in the given block for the contract deployed at the given @@ -182,7 +205,7 @@ impl StarknetRpcApiServer for StarknetBackend { async fn get_events(&self, filter: EventFilterWithPage) -> RpcResult { unimplemented!(); } -/// Add an Invoke Transaction to invoke a contract function + /// Add an Invoke Transaction to invoke a contract function /// /// # Arguments /// From d4fd8111933ddd9738cf6edd29ad89015d7ba1e5 Mon Sep 17 00:00:00 2001 From: juanbono Date: Wed, 3 Jan 2024 12:37:29 -0300 Subject: [PATCH 2/3] match contract classes --- src/rpc/starknet_backend.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/rpc/starknet_backend.rs b/src/rpc/starknet_backend.rs index 311c37183..de61e4397 100644 --- a/src/rpc/starknet_backend.rs +++ b/src/rpc/starknet_backend.rs @@ -13,6 +13,7 @@ use jsonrpsee::{ }; use starknet_core::types::{SimulatedTransaction, SimulationFlag, TransactionStatus}; use starknet_in_rust::{ + services::api::contract_classes::compiled_class::CompiledClass, state::{ cached_state::CachedState, contract_class_cache::PermanentContractClassCache, in_memory_state_reader::InMemoryStateReader, state_api::StateReader, @@ -111,9 +112,18 @@ impl StarknetRpcApiServer for StarknetBackend { .state .get_class_hash_at(&address) .map_err(|_| ErrorObject::from(ErrorCode::InternalError))?; - self.state + let contract_class = self + .state .get_contract_class(&classhash) - .map_err(|_| ErrorObject::from(ErrorCode::InternalError)) + .map_err(|_| ErrorObject::from(ErrorCode::InternalError))?; + + match contract_class { + CompiledClass::Deprecated(_) => { + todo!() + } + CompiledClass::Casm(_) => todo!(), + CompiledClass::Sierra(_) => todo!(), + } } /// Get the contract class hash in the given block for the contract deployed at the given From bab8b03b69c6517d22c8340a055c76dbeea3514d Mon Sep 17 00:00:00 2001 From: Gaston Date: Tue, 30 Jan 2024 11:09:35 -0300 Subject: [PATCH 3/3] Convert RPC transactions to starknet_in_rust transactions --- src/rpc/mod.rs | 1 + src/rpc/transactions.rs | 90 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/rpc/transactions.rs diff --git a/src/rpc/mod.rs b/src/rpc/mod.rs index 8322e39c8..8fcdc1413 100644 --- a/src/rpc/mod.rs +++ b/src/rpc/mod.rs @@ -20,6 +20,7 @@ use starknet_core::types::{ // pub struct Felt(#[serde_as(as = "UfeHex")] pub Felt252); pub mod serializable_types; pub mod starknet_backend; +pub mod transactions; use self::serializable_types::FeltParam; diff --git a/src/rpc/transactions.rs b/src/rpc/transactions.rs new file mode 100644 index 000000000..055c0d0a0 --- /dev/null +++ b/src/rpc/transactions.rs @@ -0,0 +1,90 @@ +use crate::rpc::{BroadcastedTransaction, BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction}; +use starknet_in_rust::{ + transaction::{DeployAccount, InvokeFunction, Transaction, Declare, DeclareV2}, + utils::{Address, ClassHash}, + Felt252, +}; + +// This must be removed when merged to "Added primitive store" PR +use starknet_core::types::FieldElement; + +pub fn to_felt252(field_element: FieldElement) -> Felt252 { + Felt252::from_bytes_be(&field_element.to_bytes_be()) +} + +fn convert_to_invoke_transaction(invoke: BroadcastedInvokeTransaction) -> Transaction { + Transaction::InvokeFunction(InvokeFunction::new( + Address(to_felt252(invoke.calldata + .first() + .expect("Invoke does not contain contract address") + .clone())), + to_felt252(invoke.calldata + .get(1) + .expect("Invoke does not contain function selector") + .clone()), + invoke.max_fee.try_into().unwrap(), + Felt252::ZERO, + invoke.calldata[2..] + .iter() + .map(|&e| to_felt252(e)) + .collect::>(), + invoke.signature.iter().map(|&e| to_felt252(e)).collect::>(), + Felt252::ZERO, + Some(to_felt252(invoke.nonce)), + ) + .unwrap()) +} + +fn convert_deploy_transaction(deploy: BroadcastedDeployAccountTransaction) -> Transaction { + Transaction::DeployAccount(DeployAccount::new( + ClassHash::from(to_felt252(deploy.class_hash)), + deploy.max_fee.try_into().unwrap(), + Felt252::ZERO, + to_felt252(deploy.nonce), + deploy.constructor_calldata + .iter() + .map(|&e| to_felt252(e)) + .collect::>(), + deploy.signature.iter().map(|&e| to_felt252(e)).collect::>(), + to_felt252(deploy.contract_address_salt), + Felt252::ZERO, + ) + .unwrap()) +} + +fn convert_declare_transaction(declare: BroadcastedDeclareTransaction) -> Transaction { + match declare { + BroadcastedDeclareTransaction::V1(declare) => Transaction::Declare(Declare::new( + declare.contract_class, + Felt252::ZERO, + Address(to_felt252(declare.sender_address)), + declare.max_fee.try_into().unwrap(), + Felt252::ONE, + declare.signature.iter().map(|&e| to_felt252(e)).collect::>(), + to_felt252(declare.nonce), + ) + .unwrap()), + BroadcastedDeclareTransaction::V2(declare) => Transaction::DeclareV2(Box::new( + DeclareV2::new( + declare.contract_class, + casm_contract_class, + to_felt252(declare.compiled_class_hash), + Felt252::ZERO, + Address(to_felt252(declare.sender_address)), + declare.max_fee.try_into().unwrap(), + Felt252::TWO, + declare.signature.iter().map(|&e| to_felt252(e)).collect::>(), + to_felt252(declare.nonce), + ) + .unwrap(), + )), + } +} + +pub fn convert_to_transaction(broadcasted_tx: BroadcastedTransaction) -> Transaction { + match broadcasted_tx { + BroadcastedTransaction::Invoke(invoke) => convert_to_invoke_transaction(invoke), + BroadcastedTransaction::DeployAccount(deploy) => convert_deploy_transaction(deploy), + BroadcastedTransaction::Declare(declare) => convert_declare_transaction(declare), + } +}