Skip to content

Commit

Permalink
feat: bump deps (#533)
Browse files Browse the repository at this point in the history
* dump deps

* update error enums + is_query

* update katana storage update

* tracing for debug

* wip dump katana

* add comments + wait_for_tx

* bump deps

* add transaction waiter

* refactor test helpers to use tx waiter

* add waiter to kakarot contract

* fix linting

* bump katana

* update comment

* fix nonce + unwrap

* replace expect by unwrap_or_else

* comments

* fix comments
  • Loading branch information
greged93 authored Sep 11, 2023
1 parent e34134f commit 51803e6
Show file tree
Hide file tree
Showing 18 changed files with 759 additions and 578 deletions.
871 changes: 480 additions & 391 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ license = "MIT"

[workspace.dependencies]
# Starknet dependencies
starknet = "0.4.0"
starknet = "0.5.0"
starknet-crypto = "0.5.1"
starknet_api = { git = "https://github.com/starkware-libs/starknet-api", rev = "ecc9b6946ef13003da202838e4124a9ad2efabb0" }

# Ethereum dependencies
ethers = "2.0"
ethers-solc = "2.0"
ethers = "2.0.9"
ethers-solc = "2.0.9"
reth-rpc-api = { git = "https://github.com/paradigmxyz/reth.git", tag = "v0.1.0-alpha.7" }
reth-rpc-types = { git = "https://github.com/paradigmxyz/reth.git", tag = "v0.1.0-alpha.7" }
reth-rlp = { git = "https://github.com/paradigmxyz/reth.git", tag = "v0.1.0-alpha.7" }
reth-primitives = { git = "https://github.com/paradigmxyz/reth.git", tag = "v0.1.0-alpha.7" }
jsonrpsee = { version = "0.18.2", features = ["full"] }

# Serde
serde = { version = "1.0.147", features = ["derive"] }
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0"
serde_with = "2.2.0"

Expand All @@ -50,13 +50,13 @@ ruint = "1.9.0"
url = "2.3.1"
tokio = { version = "1.21.2", features = ["macros"] }
rstest = "0.18.1"
git2 = "0.17.2"
git2 = "0.18.0"

# In order to use dojo-test-utils, we need to explicitly declare the same patches as them in our Cargo.toml
# Otherwise, underlying dependencies of dojo will not be patched and we will get a compilation error
# see https://github.com/dojoengine/dojo/issues/563
katana-core = { git = 'https://github.com/dojoengine/dojo', rev = "7893eed" }
dojo-test-utils = { git = 'https://github.com/dojoengine/dojo', rev = "7893eed" }
katana-core = { git = 'https://github.com/dojoengine/dojo', rev = "1c15335" }
dojo-test-utils = { git = 'https://github.com/dojoengine/dojo', rev = "1c15335" }
cargo-husky = { version = "1.5.0", default-features = false, features = [
"precommit-hook",
"run-for-all",
Expand Down
8 changes: 4 additions & 4 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ dotenv = { workspace = true }
ethers = { workspace = true }
ethers-solc = { workspace = true }
foundry-config = { git = "https://github.com/foundry-rs/foundry", branch = "master" }
walkdir = "2.3.3"
rstest = { workspace = true }
walkdir = "2.3.3"

[dev-dependencies]
cargo-husky = { workspace = true }
ctor = "0.2.4"
dojo-test-utils = { workspace = true }
starknet-crypto = { workspace = true }
toml = "0.7.5"
tracing-subscriber = "0.3.17"
tracing = "0.1.37"
ctor = "0.2.4"
cargo-husky = { workspace = true }
tracing-subscriber = "0.3.17"

[features]
dump = ["git2"]
Expand Down
6 changes: 1 addition & 5 deletions crates/core/src/client/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,5 @@ pub trait KakarotStarknetApi<P: Provider + Send + Sync>: Send + Sync {

async fn deploy_eoa(&self, ethereum_address: Address) -> Result<FieldElement, EthApiError<P::Error>>;

async fn wait_for_confirmation_on_l2(
&self,
transaction_hash: FieldElement,
max_retries: u64,
) -> Result<bool, EthApiError<P::Error>>;
async fn wait_for_confirmation_on_l2(&self, transaction_hash: FieldElement) -> Result<(), EthApiError<P::Error>>;
}
4 changes: 2 additions & 2 deletions crates/core/src/client/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ pub mod gas {
/// This minimum of 21,000 (see https://ethereum.stackexchange.com/questions/34674/where-does-the-number-21000-come-from-for-the-base-gas-consumption-in-ethereum/34675#34675)
/// is used if the returned fee estimate is lower, otherwise wallets such as Metamask will not
/// allow the transaction to be sent.
pub const MINIMUM_GAS_FEE: u64 = 21000;
pub const MINIMUM_GAS_FEE: u64 = 21_000;
}

/// This module contains error messages related to Kakarot.
Expand Down Expand Up @@ -125,5 +125,5 @@ lazy_static! {

// This module contains constants to be used for deployment of Kakarot System
lazy_static! {
pub static ref DEPLOY_FEE: FieldElement = FieldElement::from(100000_u64);
pub static ref DEPLOY_FEE: FieldElement = FieldElement::from(100_000_u64);
}
46 changes: 26 additions & 20 deletions crates/core/src/client/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use jsonrpsee::types::ErrorObject;
use starknet::core::types::{FromByteSliceError, StarknetError};
use starknet::providers::ProviderError;
use starknet::providers::{MaybeUnknownErrorCode, ProviderError};
use thiserror::Error;

use super::helpers::DataDecodingError;
Expand All @@ -11,6 +11,7 @@ use crate::models::ConversionError;
#[derive(Debug, Copy, PartialEq, Eq, Clone)]
pub enum EthRpcErrorCode {
/// Custom geth error code, <https://github.com/vapory-legacy/wiki/blob/master/JSON-RPC-Error-Codes-Improvement-Proposal.md>
Unknown,
ExecutionError = 3,
ParseError = -32700,
InvalidRequest = -32600,
Expand Down Expand Up @@ -91,25 +92,30 @@ impl<E: std::error::Error> From<EthApiError<E>> for ErrorObject<'static> {
fn from(error: EthApiError<E>) -> Self {
match error {
EthApiError::RequestError(err_provider) => match err_provider {
ProviderError::StarknetError(err) => match err {
StarknetError::BlockNotFound
| StarknetError::ClassHashNotFound
| StarknetError::ContractNotFound
| StarknetError::NoBlocks
| StarknetError::TransactionHashNotFound => {
rpc_err(EthRpcErrorCode::ResourceNotFound, err_provider.to_string())
}
StarknetError::ContractError => rpc_err(EthRpcErrorCode::ExecutionError, err_provider.to_string()),
StarknetError::InvalidContractClass
| StarknetError::InvalidContinuationToken
| StarknetError::InvalidTransactionIndex
| StarknetError::PageSizeTooBig
| StarknetError::TooManyKeysInFilter
| StarknetError::ClassAlreadyDeclared => {
rpc_err(EthRpcErrorCode::InvalidInput, err_provider.to_string())
}
StarknetError::FailedToReceiveTransaction => {
rpc_err(EthRpcErrorCode::TransactionRejected, err_provider.to_string())
ProviderError::StarknetError(err) => match err.code {
MaybeUnknownErrorCode::Known(err) => match err {
StarknetError::BlockNotFound
| StarknetError::ClassHashNotFound
| StarknetError::ContractNotFound
| StarknetError::NoBlocks
| StarknetError::TransactionHashNotFound => {
rpc_err(EthRpcErrorCode::ResourceNotFound, err.to_string())
}
StarknetError::ContractError => rpc_err(EthRpcErrorCode::ExecutionError, err.to_string()),
StarknetError::InvalidContractClass
| StarknetError::InvalidContinuationToken
| StarknetError::InvalidTransactionIndex
| StarknetError::PageSizeTooBig
| StarknetError::TooManyKeysInFilter
| StarknetError::ClassAlreadyDeclared => {
rpc_err(EthRpcErrorCode::InvalidInput, err.to_string())
}
StarknetError::FailedToReceiveTransaction => {
rpc_err(EthRpcErrorCode::TransactionRejected, err.to_string())
}
},
MaybeUnknownErrorCode::Unknown(code) => {
rpc_err(EthRpcErrorCode::Unknown, format!("got code {} with: {}", code, err.message))
}
},
ProviderError::ArrayLengthMismatch => rpc_err(EthRpcErrorCode::InvalidParams, err_provider.to_string()),
Expand Down
106 changes: 38 additions & 68 deletions crates/core/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod errors;
pub mod helpers;
#[cfg(test)]
pub mod tests;
pub mod waiter;

use std::sync::Arc;

Expand All @@ -26,12 +27,11 @@ use starknet::core::types::{
BlockId as StarknetBlockId, BlockTag, BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV1, EmittedEvent,
Event, EventFilterWithPage, EventsPage, FieldElement, MaybePendingBlockWithTxHashes, MaybePendingBlockWithTxs,
MaybePendingTransactionReceipt, ResultPageRequest, StarknetError, SyncStatusType, Transaction as TransactionType,
TransactionReceipt as StarknetTransactionReceipt, TransactionStatus as StarknetTransactionStatus,
TransactionReceipt as StarknetTransactionReceipt,
};
use starknet::providers::sequencer::models::{FeeEstimate, FeeUnit, TransactionSimulationInfo, TransactionTrace};
use starknet::providers::{Provider, ProviderError};
use starknet::providers::{MaybeUnknownErrorCode, Provider, ProviderError, StarknetErrorWithMessage};
use starknet::signers::LocalWallet;
use tokio::time::{sleep, Duration};

use self::api::{KakarotEthApi, KakarotStarknetApi};
use self::config::{Network, StarknetConfig};
Expand All @@ -42,6 +42,7 @@ use self::constants::{
};
use self::errors::EthApiError;
use self::helpers::{bytes_to_felt_vec, raw_kakarot_calldata, DataDecodingError};
use self::waiter::TransactionWaiter;
use crate::contracts::account::{Account, KakarotAccount};
use crate::contracts::contract_account::ContractAccount;
use crate::contracts::erc20::ethereum_erc20::EthereumErc20;
Expand Down Expand Up @@ -335,7 +336,10 @@ impl<P: Provider + Send + Sync + 'static> KakarotEthApi<P> for KakarotClient<P>
nonce.into()
})
.or_else(|err| match err {
ProviderError::StarknetError(StarknetError::ContractNotFound) => Ok(U256::from(0)),
ProviderError::StarknetError(StarknetErrorWithMessage {
code: MaybeUnknownErrorCode::Known(StarknetError::ContractNotFound),
..
}) => Ok(U256::from(0)),
_ => Err(EthApiError::from(err)),
})
}
Expand Down Expand Up @@ -418,7 +422,7 @@ impl<P: Provider + Send + Sync + 'static> KakarotEthApi<P> for KakarotClient<P>
if !account_exists {
let starknet_transaction_hash: FieldElement =
Felt252Wrapper::from(self.deploy_eoa(evm_address).await?).into();
let _ = self.wait_for_confirmation_on_l2(starknet_transaction_hash, 10).await?;
self.wait_for_confirmation_on_l2(starknet_transaction_hash).await?;
}

let starknet_address = self.compute_starknet_address(evm_address, &starknet_block_id).await?;
Expand All @@ -428,12 +432,20 @@ impl<P: Provider + Send + Sync + 'static> KakarotEthApi<P> for KakarotClient<P>
let calldata = raw_kakarot_calldata(self.kakarot_address(), bytes_to_felt_vec(&bytes));

// Get estimated_fee from Starknet
// TODO right now this is set to 0 in order to avoid failure on max fee for
// Katana.
let max_fee = *MAX_FEE;

let signature = vec![];

let request =
BroadcastedInvokeTransactionV1 { max_fee, signature, nonce, sender_address: starknet_address, calldata };
let request = BroadcastedInvokeTransactionV1 {
max_fee,
signature,
nonce,
sender_address: starknet_address,
calldata,
is_query: false,
};

let starknet_transaction_hash = self.submit_starknet_transaction(request).await?;

Expand Down Expand Up @@ -542,6 +554,7 @@ impl<P: Provider + Send + Sync + 'static> KakarotEthApi<P> for KakarotClient<P>
sender_address,
nonce: nonce.into(),
calldata,
is_query: false,
};

let fee_estimate = self.simulate_transaction(tx, block_number, true).await?.fee_estimation;
Expand Down Expand Up @@ -571,6 +584,7 @@ impl<P: Provider + Send + Sync + 'static> KakarotEthApi<P> for KakarotClient<P>
sender_address: *DUMMY_ARGENT_GAS_PRICE_ACCOUNT_ADDRESS,
nonce,
calldata: raw_calldata,
is_query: true,
};

let block_number = self.block_number().await?.as_u64();
Expand Down Expand Up @@ -611,7 +625,11 @@ impl<P: Provider + Send + Sync + 'static> KakarotStarknetApi<P> for KakarotClien
let block = self.starknet_provider.get_block_with_tx_hashes(block_id).await?;
match block {
MaybePendingBlockWithTxHashes::Block(block_with_tx_hashes) => Ok(block_with_tx_hashes.block_number),
_ => Err(ProviderError::StarknetError(StarknetError::BlockNotFound).into()),
_ => Err(ProviderError::StarknetError(StarknetErrorWithMessage {
code: MaybeUnknownErrorCode::Known(StarknetError::BlockNotFound),
message: "".to_string(),
})
.into()),
}
}
}
Expand All @@ -635,6 +653,9 @@ impl<P: Provider + Send + Sync + 'static> KakarotStarknetApi<P> for KakarotClien
) -> Result<H256, EthApiError<P::Error>> {
let transaction_result =
self.starknet_provider.add_invoke_transaction(&BroadcastedInvokeTransaction::V1(request)).await?;
let waiter =
TransactionWaiter::new(self.starknet_provider(), transaction_result.transaction_hash, 1000, 15_000);
waiter.poll().await?;

Ok(H256::from(transaction_result.transaction_hash.to_bytes_be()))
}
Expand Down Expand Up @@ -798,7 +819,10 @@ impl<P: Provider + Send + Sync + 'static> KakarotStarknetApi<P> for KakarotClien
Err(error) => match error {
EthApiError::RequestError(error) => match error {
ProviderError::StarknetError(error) => match error {
StarknetError::ContractNotFound => Ok(false),
StarknetErrorWithMessage {
code: MaybeUnknownErrorCode::Known(StarknetError::ContractNotFound),
..
} => Ok(false),
_ => Err(EthApiError::from(ProviderError::StarknetError(error))),
},
_ => Err(EthApiError::from(error)),
Expand All @@ -815,64 +839,10 @@ impl<P: Provider + Send + Sync + 'static> KakarotStarknetApi<P> for KakarotClien
self.kakarot_contract.deploy_externally_owned_account(ethereum_address, &self.deployer_account).await
}

/// given a transaction hash, waits for it to be confirmed on L2
/// each retry is every 1 second, tries for max_retries*1s and then timeouts after that
/// returns a boolean indicating whether the transaction was accepted or not L2, it will always
/// be true, otherwise should return error
async fn wait_for_confirmation_on_l2(
&self,
transaction_hash: FieldElement,
max_retries: u64,
) -> Result<bool, EthApiError<P::Error>> {
let mut idx = 0;

loop {
if idx >= max_retries {
return Err(EthApiError::Other(anyhow::format_err!(
"timeout: max retries: {max_retries} attempted for polling the transaction receipt"
)));
}

let receipt = self.starknet_provider.get_transaction_receipt(transaction_hash).await;

match receipt {
Ok(receipt) => match receipt {
MaybePendingTransactionReceipt::Receipt(receipt) => match receipt {
StarknetTransactionReceipt::Invoke(receipt) => match receipt.status {
StarknetTransactionStatus::AcceptedOnL2 | StarknetTransactionStatus::AcceptedOnL1 => {
return Ok(true);
}
StarknetTransactionStatus::Rejected => {
return Err(EthApiError::Other(anyhow::anyhow!(
"Pooling Failed: the transaction {transaction_hash} has been rejected"
)));
}
_ => (),
},
_ => {
return Err(EthApiError::Other(anyhow::anyhow!(
"Pooling Failed: expected an invoke receipt, found {receipt:#?}"
)));
}
},
MaybePendingTransactionReceipt::PendingReceipt(_) => (),
},
Err(error) => {
match error {
ProviderError::StarknetError(StarknetError::TransactionHashNotFound) => {
// do nothing because to comply with json-rpc spec, even in case of
// TransactionStatus::Received an error will be returned, so we should
// continue polling see: https://github.com/xJonathanLEI/starknet-rs/blob/832c6cdc36e5899cf2c82f8391a4dd409650eed1/starknet-providers/src/sequencer/provider.rs#L134C1-L134C1
}
_ => {
return Err(error.into());
}
}
}
};

idx += 1;
sleep(Duration::from_secs(1)).await;
}
/// Given a transaction hash, waits for it to be confirmed on L2
async fn wait_for_confirmation_on_l2(&self, transaction_hash: FieldElement) -> Result<(), EthApiError<P::Error>> {
let waiter = TransactionWaiter::new(self.starknet_provider(), transaction_hash, 1000, 15_000);
waiter.poll().await?;
Ok(())
}
}
1 change: 1 addition & 0 deletions crates/core/src/client/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ async fn test_simulate_transaction() {
max_fee: FieldElement::ZERO,
nonce,
signature: vec![],
is_query: true,
};

// When
Expand Down
Loading

0 comments on commit 51803e6

Please sign in to comment.