Skip to content
This repository has been archived by the owner on Aug 2, 2024. It is now read-only.

feat: Declare V0 RPC call #1617

Merged
merged 30 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
aa8745c
feat : added declare v0
May 26, 2024
ecf3596
feat : added declare common function
May 27, 2024
8a05ffd
feat : fixed mismatch types
May 28, 2024
d77d90a
feat : added declare v0 deps and testing done
May 31, 2024
9342f36
removed setup dir
May 31, 2024
69f2ee0
feat : removed uneccessary logs
May 31, 2024
2a7f977
added pr title in changelog
May 31, 2024
a6c9126
fix : fixed prettier issues
May 31, 2024
0d1185f
feat : added requested changes
May 31, 2024
205151f
feat : added requested changes 2
Jun 1, 2024
73a0f05
feat : added requested changes 2
Jun 1, 2024
e848d97
Merge branch 'main' into main
ocdbytes Jun 1, 2024
3c2f7ef
lint test fix
Jun 1, 2024
d8df267
lint test fix
Jun 1, 2024
3767dbb
feat : added new requested changes : formatting and redundant code re…
Jun 3, 2024
6b9615f
Merge pull request #1 from ocdbytes/declareV0/feat
ocdbytes Jun 3, 2024
840f38b
lint issue fixed
Jun 3, 2024
62b6cd9
feat : rpc test fix & declare v0 rpc test added
Jun 3, 2024
bd5dec7
feat : fixed lint issues
Jun 3, 2024
90951ee
fix declare V0 test
Jun 3, 2024
e73623e
feat : fix lint issues
Jun 3, 2024
90c7620
feat : fix lint issues
Jun 3, 2024
f7d0f59
fix : added rpc test fixes
Jun 3, 2024
96c529c
feat : refactoring and comments added
Jun 17, 2024
f68fd03
Merge branch 'main' into main
ocdbytes Jun 17, 2024
0fb2574
refactor : changed program_vec to program_bytes
Jun 19, 2024
c0e504a
add_declare_transaction_v0 e2e
tdelabro Jun 19, 2024
ee50d2d
Merge pull request #2 from tdelabro/add-declare-transaction-v0
ocdbytes Jun 19, 2024
ea34185
fix : lint
Jun 19, 2024
54033cf
feat : refactor and removed unused deps
Jun 20, 2024
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ cairo_venv

# solidity cache
tmp/

# Setup deps
setup_and_launch.sh
./setup_dir
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Next release

- feat: Declare V0 RPC call
- feat: actual estimate_fee added, brought back l1 messages and refactored
simulate tx
- dev: impl get_state_updates using get_transaction_re_execution_state_diff
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion configs/genesis-assets/genesis.json
Original file line number Diff line number Diff line change
Expand Up @@ -386,4 +386,4 @@
"eth_fee_token_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
"strk_fee_token_address": "0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
"chain_id": "MADARA"
}
}
2 changes: 1 addition & 1 deletion configs/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
{
"name": "genesis.json",
"sha3_256": "bca50369e627d1101e4d693fa6fac9bee6cce2889b324dee3204179a3960ef5e"
"sha3_256": "7068787425ff1948e8cd08f136e3db99230751ffb31c4bf7b9384c171a49574f"
},
{
"name": "NoValidateAccount.casm.json",
Expand Down
2 changes: 2 additions & 0 deletions crates/client/l1-gas-price/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ async fn update_gas_price(
.json()
.await?;

// log::info!(">>>>>> gas_prices : {:?}", fee_history);
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved

// The RPC responds with 301 elements for some reason. It's also just safer to manually
// take the last 300. We choose 300 to get average gas caprice for last one hour (300 * 12 sec block
// time).
Expand Down
44 changes: 38 additions & 6 deletions crates/client/rpc-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@
#[cfg(test)]
mod tests;

use jsonrpsee::core::RpcResult;
use blockifier::transaction::transactions::DeclareTransaction;
use indexmap::IndexMap;
use jsonrpsee::core::{async_trait, RpcResult};
use jsonrpsee::proc_macros::rpc;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use starknet_api::core::ClassHash;
use starknet_api::deprecated_contract_class::{EntryPoint, EntryPointType};
use starknet_api::transaction::{DeclareTransactionV0V1, TransactionHash};

pub mod utils;

Expand All @@ -19,11 +24,11 @@ use pallet_starknet::genesis_loader::PredeployedAccount;
use starknet_core::serde::unsigned_field_element::UfeHex;
use starknet_core::types::{
BlockHashAndNumber, BlockId, BroadcastedDeclareTransaction, BroadcastedDeployAccountTransaction,
BroadcastedInvokeTransaction, BroadcastedTransaction, ContractClass, DeclareTransactionResult,
DeployAccountTransactionResult, EventFilterWithPage, EventsPage, FeeEstimate, FieldElement, FunctionCall,
InvokeTransactionResult, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate,
MaybePendingTransactionReceipt, MsgFromL1, SimulatedTransaction, SimulationFlag, SimulationFlagForEstimateFee,
SyncStatusType, Transaction, TransactionTrace, TransactionTraceWithHash,
BroadcastedInvokeTransaction, BroadcastedTransaction, ContractClass,
DeclareTransactionResult, DeployAccountTransactionResult, EventFilterWithPage, EventsPage, FeeEstimate,
FieldElement, FunctionCall, InvokeTransactionResult, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs,
MaybePendingStateUpdate, MaybePendingTransactionReceipt, MsgFromL1, SimulatedTransaction, SimulationFlag,
SimulationFlagForEstimateFee, SyncStatusType, Transaction, TransactionTrace, TransactionTraceWithHash,
};

#[serde_as]
Expand All @@ -36,11 +41,25 @@ pub struct PredeployedAccountWithBalance {
pub balance: FieldElement,
}

#[derive(Serialize, Deserialize)]
pub struct DeclareV0Result {
pub class_hash: ClassHash,
}

/// Madara rpc interface for additional features.
#[rpc(server, namespace = "madara")]
pub trait MadaraRpcApi: StarknetReadRpcApi {
#[method(name = "predeployedAccounts")]
fn predeployed_accounts(&self) -> RpcResult<Vec<PredeployedAccountWithBalance>>;

#[method(name = "declarev0")]
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved
async fn declare_v0_contract(
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved
&self,
declare_transaction: DeclareTransactionV0V1,
program_vec: Vec<u8>,
entrypoints: IndexMap<EntryPointType, Vec<EntryPoint>>,
abi_length: usize,
) -> RpcResult<DeclareV0Result>;
}

/// Starknet write rpc interface.
Expand Down Expand Up @@ -189,3 +208,16 @@ pub trait StarknetTraceRpcApi {
/// Returns the execution trace of a transaction
async fn trace_transaction(&self, transaction_hash: FieldElement) -> RpcResult<TransactionTrace>;
}

pub enum DeclareTransactionCommonInput {
V0(DeclareTransactionV0V1, Vec<u8>, IndexMap<EntryPointType, Vec<EntryPoint>>, usize),
V1(DeclareTransaction),
}

#[async_trait]
pub trait StarknetRpcApiCommonFuncs {
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved
async fn declare_txn_common(
&self,
transaction_inputs: DeclareTransactionCommonInput,
) -> Option<(TransactionHash, ClassHash)>;
}
1 change: 1 addition & 0 deletions crates/client/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ starknet-core = { workspace = true }
starknet-ff = { workspace = true }
starknet_api = { workspace = true }
thiserror = { workspace = true }
indexmap = { workspace = true }

[dev-dependencies]
rstest = { workspace = true }
Expand Down
163 changes: 131 additions & 32 deletions crates/client/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ use std::collections::HashMap;
use std::marker::PhantomData;
use std::sync::Arc;

use blockifier::execution::contract_class::{ClassInfo, ContractClassV0, ContractClassV0Inner};
use blockifier::transaction::account_transaction::AccountTransaction;
use blockifier::transaction::objects::{ResourcesMapping, TransactionExecutionInfo};
use blockifier::transaction::transactions::L1HandlerTransaction;
use blockifier::transaction::transactions::{DeclareTransaction, L1HandlerTransaction};
use cairo_vm::types::program::Program;
use indexmap::IndexMap;
use errors::StarknetRpcApiError;
use jsonrpsee::core::{async_trait, RpcResult};
use log::error;
use mc_genesis_data_provider::GenesisProvider;
pub use mc_rpc_core::utils::*;
use mc_rpc_core::{DeclareTransactionCommonInput, DeclareV0Result, StarknetRpcApiCommonFuncs};
pub use mc_rpc_core::{
Felt, MadaraRpcApiServer, PredeployedAccountWithBalance, StarknetReadRpcApiServer, StarknetTraceRpcApiServer,
StarknetWriteRpcApiServer,
Expand Down Expand Up @@ -50,23 +54,25 @@ use sp_api::ProvideRuntimeApi;
use sp_arithmetic::traits::UniqueSaturatedInto;
use sp_blockchain::HeaderBackend;
use sp_core::H256;
use sp_runtime::codec::{DecodeAll};
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
use sp_runtime::transaction_validity::InvalidTransaction;
use starknet_api::core::Nonce;
use starknet_api::hash::StarkFelt;
use starknet_api::transaction::{Calldata, Fee, TransactionHash, TransactionVersion};
use starknet_api::core::{ClassHash, Nonce};
use starknet_api::deprecated_contract_class::{EntryPoint, EntryPointType};
use starknet_api::hash::{StarkFelt, StarkHash};
use starknet_api::transaction::{Calldata, DeclareTransactionV0V1, Fee, TransactionHash, TransactionVersion};
use starknet_core::types::{
BlockHashAndNumber, BlockId, BlockStatus, BlockTag, BlockWithTxHashes, BlockWithTxs, BroadcastedDeclareTransaction,
BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction, ContractClass,
DeclareTransactionReceipt, DeclareTransactionResult, DeployAccountTransactionReceipt,
DeployAccountTransactionResult, EventFilterWithPage, EventsPage, ExecutionResources, ExecutionResult, FeeEstimate,
FeePayment, FieldElement, FunctionCall, Hash256, InvokeTransactionReceipt, InvokeTransactionResult,
L1HandlerTransactionReceipt, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs, MaybePendingStateUpdate,
MaybePendingTransactionReceipt, MsgFromL1, PendingBlockWithTxHashes, PendingBlockWithTxs,
PendingDeclareTransactionReceipt, PendingDeployAccountTransactionReceipt, PendingInvokeTransactionReceipt,
PendingL1HandlerTransactionReceipt, PendingStateUpdate, PendingTransactionReceipt, PriceUnit, ResourcePrice,
SimulationFlagForEstimateFee, StateDiff, StateUpdate, SyncStatus, SyncStatusType, Transaction,
TransactionExecutionStatus, TransactionFinalityStatus, TransactionReceipt,
BroadcastedDeployAccountTransaction, BroadcastedInvokeTransaction, BroadcastedTransaction, ContractClass, DeclareTransactionReceipt, DeclareTransactionResult,
DeployAccountTransactionReceipt, DeployAccountTransactionResult, EventFilterWithPage, EventsPage,
ExecutionResources, ExecutionResult, FeeEstimate, FeePayment, FieldElement, FunctionCall, Hash256,
InvokeTransactionReceipt, InvokeTransactionResult, L1HandlerTransactionReceipt, MaybePendingBlockWithTxHashes,
MaybePendingBlockWithTxs, MaybePendingStateUpdate, MaybePendingTransactionReceipt, MsgFromL1,
PendingBlockWithTxHashes, PendingBlockWithTxs, PendingDeclareTransactionReceipt,
PendingDeployAccountTransactionReceipt, PendingInvokeTransactionReceipt, PendingL1HandlerTransactionReceipt,
PendingStateUpdate, PendingTransactionReceipt, PriceUnit, ResourcePrice, SimulationFlagForEstimateFee, StateDiff,
StateUpdate, SyncStatus, SyncStatusType, Transaction, TransactionExecutionStatus, TransactionFinalityStatus,
TransactionReceipt,
};
use starknet_core::utils::get_selector_from_name;
use trace_api::get_previous_block_substrate_hash;
Expand Down Expand Up @@ -220,9 +226,101 @@ where
}
}

#[async_trait]
impl<A, B, BE, G, C, P, H> StarknetRpcApiCommonFuncs for Starknet<A, B, BE, G, C, P, H>
where
A: ChainApi<Block = B> + 'static,
B: BlockT,
P: TransactionPool<Block = B> + 'static,
BE: Backend<B> + 'static,
C: HeaderBackend<B> + BlockBackend<B> + StorageProvider<B, BE> + 'static,
C: ProvideRuntimeApi<B>,
C::Api: StarknetRuntimeApi<B> + ConvertTransactionRuntimeApi<B>,
G: GenesisProvider + Send + Sync + 'static,
H: HasherT + Send + Sync + 'static,
{
async fn declare_txn_common(
&self,
transaction_inputs: DeclareTransactionCommonInput,
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved
) -> Option<(TransactionHash, ClassHash)> {
let best_block_hash = self.get_best_block_hash();

match transaction_inputs {
tdelabro marked this conversation as resolved.
Show resolved Hide resolved
DeclareTransactionCommonInput::V1(transaction) => {
let (class_hash, tx_hash) = (transaction.class_hash(), transaction.tx_hash());

let current_block_hash = self.get_best_block_hash();
let contract_class = self
.overrides
.for_block_hash(self.client.as_ref(), current_block_hash)
.contract_class_by_class_hash(current_block_hash, class_hash);

if let Some(contract_class) = contract_class {
error!("Contract class already exists: {:?}", contract_class);
// return Err(StarknetRpcApiError::ClassAlreadyDeclared.into());
}

let extrinsic =
self.convert_tx_to_extrinsic(best_block_hash, AccountTransaction::Declare(transaction)).unwrap();

submit_extrinsic(self.pool.clone(), best_block_hash, extrinsic).await.ok()?;

Some((tx_hash, class_hash))
}
DeclareTransactionCommonInput::V0(declare_txn, program_vec, entrypoints, abi_length) => {
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved
let txn_hash: TransactionHash = TransactionHash(StarkHash { 0: FieldElement::ONE.to_bytes_be() });
tdelabro marked this conversation as resolved.
Show resolved Hide resolved

let program_decoded = Program::decode_all(&mut &*program_vec).unwrap();
tdelabro marked this conversation as resolved.
Show resolved Hide resolved

let class_info = ClassInfo::new(
&blockifier::execution::contract_class::ContractClass::V0(ContractClassV0(Arc::from(
ContractClassV0Inner {
program: program_decoded,
entry_points_by_type: entrypoints,
},
))),
0,
abi_length,
)
.unwrap();
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved

let declare_transaction = DeclareTransaction::new(
starknet_api::transaction::DeclareTransaction::V0(declare_txn),
txn_hash,
class_info,
)
.unwrap();

let current_block_hash = self.get_best_block_hash();
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved
let contract_class = self
.overrides
.for_block_hash(self.client.as_ref(), current_block_hash)
.contract_class_by_class_hash(current_block_hash, declare_transaction.class_hash());

if let Some(contract_class) = contract_class {
error!("Contract class already exists: {:?}", contract_class);
// return Err(StarknetRpcApiError::ClassAlreadyDeclared.into());
}

let extrinsic = self
.convert_tx_to_extrinsic(best_block_hash, AccountTransaction::Declare(declare_transaction.clone()))
.unwrap();

let res = submit_extrinsic(self.pool.clone(), best_block_hash, extrinsic).await.unwrap();

log::info!(">>>>> extrinsic res : {:?}", res);
log::info!(">>>>> class hash declared: {:?} ✅ | txn hash : {:?}", declare_transaction.class_hash(), declare_transaction.tx_hash);
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved

Some((declare_transaction.tx_hash, declare_transaction.class_hash()))
}
}
}
}

/// Taken from https://github.com/paritytech/substrate/blob/master/client/rpc/src/author/mod.rs#L78
const TX_SOURCE: TransactionSource = TransactionSource::External;

#[async_trait]
impl<A, B, BE, G, C, P, H> MadaraRpcApiServer for Starknet<A, B, BE, G, C, P, H>
where
A: ChainApi<Block = B> + 'static,
Expand Down Expand Up @@ -262,6 +360,20 @@ where
})
.collect::<Vec<_>>())
}

async fn declare_v0_contract(
&self,
declare_transaction: DeclareTransactionV0V1,
program_vec: Vec<u8>,
entrypoints: IndexMap<EntryPointType, Vec<EntryPoint>>,
abi_length: usize
) -> RpcResult<DeclareV0Result> {
let (_txn_hash, class_hash) = self.declare_txn_common(DeclareTransactionCommonInput::V0(declare_transaction, program_vec, entrypoints, abi_length))
apoorvsadana marked this conversation as resolved.
Show resolved Hide resolved
.await
.ok_or("Error in declaring the v0 using the given transaction !!!").expect("ERROR : Error in declaring the v0 using the given transaction !!!");

Ok(DeclareV0Result { class_hash })
}
}

#[async_trait]
Expand Down Expand Up @@ -290,8 +402,6 @@ where
&self,
declare_transaction: BroadcastedDeclareTransaction,
) -> RpcResult<DeclareTransactionResult> {
let best_block_hash = self.get_best_block_hash();

let opt_sierra_contract_class = if let BroadcastedDeclareTransaction::V2(ref tx) = declare_transaction {
Some(flattened_sierra_to_sierra_contract_class(tx.contract_class.clone()))
} else {
Expand All @@ -304,22 +414,9 @@ where
error!("Failed to convert BroadcastedDeclareTransaction to DeclareTransaction, error: {e}");
StarknetRpcApiError::InternalServerError
})?;
let (class_hash, tx_hash) = (transaction.class_hash(), transaction.tx_hash());

let current_block_hash = self.get_best_block_hash();
let contract_class = self
.overrides
.for_block_hash(self.client.as_ref(), current_block_hash)
.contract_class_by_class_hash(current_block_hash, class_hash);

if let Some(contract_class) = contract_class {
error!("Contract class already exists: {:?}", contract_class);
return Err(StarknetRpcApiError::ClassAlreadyDeclared.into());
}

let extrinsic = self.convert_tx_to_extrinsic(best_block_hash, AccountTransaction::Declare(transaction))?;

submit_extrinsic(self.pool.clone(), best_block_hash, extrinsic).await?;
let (tx_hash, class_hash) =
self.declare_txn_common(DeclareTransactionCommonInput::V1(transaction)).await.unwrap();

if let Some(sierra_contract_class) = opt_sierra_contract_class {
if let Some(e) = self.backend.sierra_classes().store_sierra_class(class_hash, sierra_contract_class).err() {
Expand Down Expand Up @@ -1697,7 +1794,9 @@ where
pool.submit_one(best_block_hash, TX_SOURCE, extrinsic).await.map_err(|e| {
error!("Failed to submit extrinsic: {:?}", e);
match e.into_pool_error() {
Ok(PoolError::InvalidTransaction(InvalidTransaction::BadProof)) => StarknetRpcApiError::ValidationFailure,
Ok(PoolError::InvalidTransaction(InvalidTransaction::BadProof)) => {
StarknetRpcApiError::ValidationFailure
},
_ => StarknetRpcApiError::InternalServerError,
}
})
Expand Down
Loading
Loading