Skip to content

Commit

Permalink
fix deploy account
Browse files Browse the repository at this point in the history
  • Loading branch information
kariy committed Jul 14, 2023
1 parent 1d655c7 commit 4479d89
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 105 deletions.
104 changes: 21 additions & 83 deletions crates/katana/core/src/sequencer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ use blockifier::execution::contract_class::ContractClass;
use blockifier::state::state_api::{State, StateReader};
use blockifier::transaction::account_transaction::AccountTransaction;
use blockifier::transaction::transaction_execution::Transaction;
use blockifier::transaction::transactions::{DeclareTransaction, ExecutableTransaction};
use blockifier::transaction::transactions::DeclareTransaction;
use starknet::core::types::{
BlockId, BlockTag, FeeEstimate, FlattenedSierraClass, StateUpdate, TransactionStatus,
};
use starknet_api::block::{BlockHash, BlockNumber};
use starknet_api::core::{calculate_contract_address, ChainId, ClassHash, ContractAddress, Nonce};
use starknet_api::core::{ChainId, ClassHash, ContractAddress, Nonce};
use starknet_api::hash::StarkFelt;
use starknet_api::stark_felt;
use starknet_api::state::StorageKey;
use starknet_api::transaction::{
Calldata, ContractAddressSalt, DeployAccountTransaction, Fee, InvokeTransaction,
Transaction as StarknetApiTransaction, TransactionHash, TransactionSignature,
DeployAccountTransaction, InvokeTransaction, Transaction as StarknetApiTransaction,
TransactionHash,
};
use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use tokio::time;
Expand All @@ -32,7 +32,6 @@ use crate::backend::state::{MemDb, StateExt};
use crate::backend::transaction::ExternalFunctionCall;
use crate::backend::StarknetWrapper;
use crate::sequencer_error::SequencerError;
use crate::util::starkfelt_to_u128;

type SequencerResult<T> = Result<T, SequencerError>;

Expand Down Expand Up @@ -70,19 +69,11 @@ impl KatanaSequencer {

pub async fn drip_and_deploy_account(
&self,
class_hash: ClassHash,
contract_address_salt: ContractAddressSalt,
constructor_calldata: Calldata,
signature: TransactionSignature,
transaction: DeployAccountTransaction,
balance: u64,
) -> SequencerResult<(TransactionHash, ContractAddress)> {
let contract_address = calculate_contract_address(
contract_address_salt,
class_hash,
&constructor_calldata,
ContractAddress::default(),
)
.map_err(SequencerError::StarknetApi)?;
let (transaction_hash, contract_address) =
self.add_deploy_account_transaction(transaction).await;

let deployed_account_balance_key =
get_storage_var_address("ERC20_balances", &[*contract_address.0.key()])
Expand All @@ -94,8 +85,7 @@ impl KatanaSequencer {
stark_felt!(balance),
);

self.deploy_account(class_hash, contract_address_salt, constructor_calldata, signature)
.await
Ok((transaction_hash, contract_address))
}

pub async fn block_number_from_block_id(&self, block_id: &BlockId) -> Option<BlockNumber> {
Expand Down Expand Up @@ -156,63 +146,18 @@ impl Sequencer for KatanaSequencer {
}
}

async fn deploy_account(
async fn add_deploy_account_transaction(
&self,
class_hash: ClassHash,
contract_address_salt: ContractAddressSalt,
constructor_calldata: Calldata,
signature: TransactionSignature,
) -> SequencerResult<(TransactionHash, ContractAddress)> {
let contract_address = calculate_contract_address(
contract_address_salt,
class_hash,
&constructor_calldata,
ContractAddress::default(),
)
.map_err(SequencerError::StarknetApi)?;

let account_balance_key =
get_storage_var_address("ERC20_balances", &[*contract_address.0.key()])
.map_err(SequencerError::StarknetApi)?;

let max_fee = {
self.starknet
.write()
.await
.state
.get_storage_at(
self.starknet.read().await.block_context.fee_token_address,
account_balance_key,
)
.map_err(SequencerError::State)?
};
// TODO: Compute txn hash
let tx_hash = TransactionHash::default();
let tx = AccountTransaction::DeployAccount(DeployAccountTransaction {
class_hash,
contract_address,
contract_address_salt,
constructor_calldata,
version: Default::default(),
nonce: Nonce(stark_felt!(0_u8)),
signature,
transaction_hash: tx_hash,
max_fee: Fee(starkfelt_to_u128(max_fee).map_err(|e| {
SequencerError::ConversionError {
message: e.to_string(),
to: "u128".to_string(),
from: "StarkFelt".to_string(),
}
})?),
});
transaction: DeployAccountTransaction,
) -> (TransactionHash, ContractAddress) {
let transaction_hash = transaction.transaction_hash;
let contract_address = transaction.contract_address;

tx.execute(
&mut self.starknet.write().await.pending_cached_state,
&self.starknet.read().await.block_context,
)
.map_err(SequencerError::TransactionExecution)?;
self.starknet.write().await.handle_transaction(Transaction::AccountTransaction(
AccountTransaction::DeployAccount(transaction),
));

Ok((tx_hash, contract_address))
(transaction_hash, contract_address)
}

async fn add_declare_transaction(
Expand Down Expand Up @@ -252,16 +197,12 @@ impl Sequencer for KatanaSequencer {
return Err(SequencerError::BlockNotFound(block_id));
}

let sender = match &account_transaction {
match &account_transaction {
AccountTransaction::Invoke(tx) => tx.sender_address(),
AccountTransaction::Declare(tx) => tx.tx().sender_address(),
AccountTransaction::DeployAccount(tx) => tx.contract_address,
};

if !self.verify_contract_exists(&sender).await {
return Err(SequencerError::ContractNotFound(sender));
}

let state = self.state(&block_id).await?;

self.starknet
Expand Down Expand Up @@ -579,13 +520,10 @@ pub trait Sequencer {
block_id: BlockId,
) -> SequencerResult<StarkFelt>;

async fn deploy_account(
async fn add_deploy_account_transaction(
&self,
class_hash: ClassHash,
contract_address_salt: ContractAddressSalt,
constructor_calldata: Calldata,
signature: TransactionSignature,
) -> SequencerResult<(TransactionHash, ContractAddress)>;
transaction: DeployAccountTransaction,
) -> (TransactionHash, ContractAddress);

async fn add_declare_transaction(
&self,
Expand Down
117 changes: 95 additions & 22 deletions crates/katana/rpc/src/starknet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use blockifier::state::errors::StateError;
use blockifier::transaction::account_transaction::AccountTransaction;
use blockifier::transaction::transactions::DeclareTransaction;
use jsonrpsee::core::{async_trait, Error};
use jsonrpsee::types::error::CallError;
use katana_core::backend::contract::StarknetContract;
use katana_core::backend::transaction::ExternalFunctionCall;
use katana_core::constants::SEQUENCER_ADDRESS;
Expand All @@ -24,17 +23,19 @@ use starknet::core::types::{
PendingDeployAccountTransactionReceipt, PendingInvokeTransactionReceipt,
PendingTransactionReceipt, StateUpdate, Transaction, TransactionReceipt, TransactionStatus,
};
use starknet::core::utils::get_contract_address;
use starknet_api::core::{
ClassHash, CompiledClassHash, ContractAddress, EntryPointSelector, Nonce, PatriciaKey,
};
use starknet_api::hash::{StarkFelt, StarkHash};
use starknet_api::patricia_key;
use starknet_api::state::StorageKey;
use starknet_api::transaction::{
Calldata, ContractAddressSalt, DeclareTransactionV0V1, DeclareTransactionV2, Fee,
InvokeTransaction, InvokeTransactionV1, Transaction as InnerTransaction, TransactionHash,
TransactionOutput, TransactionSignature,
Calldata, ContractAddressSalt, DeclareTransactionV0V1, DeclareTransactionV2,
DeployAccountTransaction, Fee, InvokeTransaction, InvokeTransactionV1,
Transaction as InnerTransaction, TransactionHash, TransactionOutput, TransactionSignature,
TransactionVersion,
};
use starknet_api::{patricia_key, stark_felt};
use utils::transaction::{
compute_declare_v1_transaction_hash, compute_declare_v2_transaction_hash,
compute_invoke_v1_transaction_hash, convert_inner_to_rpc_tx,
Expand All @@ -45,6 +46,7 @@ use crate::utils;
use crate::utils::contract::{
legacy_inner_to_rpc_class, legacy_rpc_to_inner_class, rpc_to_inner_class,
};
use crate::utils::transaction::compute_deploy_account_v1_transaction_hash;

pub struct StarknetApi<S> {
sequencer: S,
Expand Down Expand Up @@ -702,29 +704,53 @@ where
&self,
deploy_account_transaction: BroadcastedDeployAccountTransaction,
) -> Result<DeployAccountTransactionResult, Error> {
let chain_id = FieldElement::from_hex_be(&self.sequencer.chain_id().await.as_hex())
.map_err(|_| Error::from(StarknetApiError::InternalServerError))?;

let BroadcastedDeployAccountTransaction {
class_hash,
constructor_calldata,
contract_address_salt,
max_fee,
nonce,
signature,
} = deploy_account_transaction;

let contract_address = get_contract_address(
contract_address_salt,
constructor_calldata,
class_hash,
..
} = deploy_account_transaction;
&constructor_calldata,
FieldElement::ZERO,
);

let (transaction_hash, contract_address) = self
.sequencer
.deploy_account(
ClassHash(StarkFelt::from(class_hash)),
ContractAddressSalt(StarkFelt::from(contract_address_salt)),
Calldata(Arc::new(constructor_calldata.into_iter().map(StarkFelt::from).collect())),
TransactionSignature(signature.into_iter().map(StarkFelt::from).collect()),
)
.await
.map_err(|e| Error::Call(CallError::Failed(anyhow::anyhow!(e.to_string()))))?;
let transaction_hash = compute_deploy_account_v1_transaction_hash(
contract_address,
&constructor_calldata,
class_hash,
contract_address_salt,
max_fee,
chain_id,
nonce,
);

let transaction = DeployAccountTransaction {
signature: TransactionSignature(signature.into_iter().map(|s| s.into()).collect()),
contract_address_salt: ContractAddressSalt(StarkFelt::from(contract_address_salt)),
constructor_calldata: Calldata(Arc::new(
constructor_calldata.into_iter().map(|d| d.into()).collect(),
)),
class_hash: ClassHash(class_hash.into()),
contract_address: ContractAddress(patricia_key!(contract_address)),
max_fee: Fee(starkfelt_to_u128(max_fee.into())
.map_err(|_| Error::from(StarknetApiError::InternalServerError))?),
nonce: Nonce(nonce.into()),
transaction_hash: TransactionHash(transaction_hash.into()),
version: TransactionVersion(stark_felt!(1_u32)),
};

Ok(DeployAccountTransactionResult {
transaction_hash: FieldElement::from(transaction_hash.0),
contract_address: FieldElement::from(*contract_address.0.key()),
})
self.sequencer.add_deploy_account_transaction(transaction).await;

Ok(DeployAccountTransactionResult { transaction_hash, contract_address })
}

async fn estimate_fee(
Expand Down Expand Up @@ -831,6 +857,53 @@ where
AccountTransaction::Invoke(InvokeTransaction::V1(transaction))
}

BroadcastedTransaction::DeployAccount(BroadcastedDeployAccountTransaction {
max_fee,
signature,
nonce,
contract_address_salt,
constructor_calldata,
class_hash,
}) => {
let contract_address = get_contract_address(
contract_address_salt,
class_hash,
&constructor_calldata,
FieldElement::ZERO,
);

let transaction_hash = compute_deploy_account_v1_transaction_hash(
contract_address,
&constructor_calldata,
class_hash,
contract_address_salt,
max_fee,
chain_id,
nonce,
);

let transaction = DeployAccountTransaction {
signature: TransactionSignature(
signature.into_iter().map(|s| s.into()).collect(),
),
contract_address_salt: ContractAddressSalt(StarkFelt::from(
contract_address_salt,
)),
constructor_calldata: Calldata(Arc::new(
constructor_calldata.into_iter().map(|d| d.into()).collect(),
)),
class_hash: ClassHash(class_hash.into()),
contract_address: ContractAddress(patricia_key!(contract_address)),
max_fee: Fee(starkfelt_to_u128(max_fee.into())
.map_err(|_| Error::from(StarknetApiError::InternalServerError))?),
nonce: Nonce(nonce.into()),
transaction_hash: TransactionHash(transaction_hash.into()),
version: TransactionVersion(stark_felt!(1_u32)),
};

AccountTransaction::DeployAccount(transaction)
}

_ => return Err(Error::from(StarknetApiError::UnsupportedTransactionVersion)),
};

Expand Down
Loading

0 comments on commit 4479d89

Please sign in to comment.