Skip to content

Commit

Permalink
dev(sozo): use TransationOption instead of FeeOption (#1927)
Browse files Browse the repository at this point in the history
* use TransactionOption instead of FeeOption

* clean up

* print more info about error

* implement TransactionExt for AccountDeployment
  • Loading branch information
lambda-0x authored May 14, 2024
1 parent ce172db commit a095ccf
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 176 deletions.
20 changes: 12 additions & 8 deletions bin/sozo/src/commands/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use starknet::signers::LocalWallet;
use starknet_crypto::FieldElement;
use tracing::trace;

use super::options::fee::FeeOptions;
use super::options::signer::SignerOptions;
use super::options::starknet::StarknetOptions;
use super::options::transaction::TransactionOptions;
use crate::utils;

#[derive(Debug, Args)]
Expand Down Expand Up @@ -43,11 +43,15 @@ pub enum AccountCommand {
signer: SignerOptions,

#[clap(flatten)]
fee: FeeOptions,
transaction: TransactionOptions,

#[clap(long, help = "Simulate the transaction only")]
simulate: bool,

#[clap(long, help = "Only estimate transaction fee without sending transaction")]
#[arg(global = true)]
estimate_only: bool,

#[clap(long, help = "Provide transaction nonce manually")]
nonce: Option<FieldElement>,

Expand Down Expand Up @@ -97,20 +101,21 @@ impl AccountArgs {
AccountCommand::Deploy {
starknet,
signer,
fee,
transaction,
simulate,
estimate_only,
nonce,
poll_interval,
file,
no_confirmation,
} => {
let provider = starknet.provider(env_metadata.as_ref())?;
let signer: LocalWallet = signer.signer(env_metadata.as_ref(), false)?;
let fee_setting = fee.into_setting()?;
let signer = signer.signer(env_metadata.as_ref(), false)?;
let txn_action = transaction.to_txn_action(simulate, estimate_only)?;
trace!(
?starknet,
?signer,
?fee_setting,
?txn_action,
simulate,
?nonce,
poll_interval,
Expand All @@ -121,8 +126,7 @@ impl AccountArgs {
account::deploy(
provider,
signer,
fee_setting,
simulate,
txn_action,
nonce,
poll_interval,
file,
Expand Down
103 changes: 0 additions & 103 deletions bin/sozo/src/commands/options/fee.rs

This file was deleted.

1 change: 0 additions & 1 deletion bin/sozo/src/commands/options/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pub mod account;
pub mod fee;
pub mod signer;
pub mod starknet;
pub mod transaction;
Expand Down
21 changes: 20 additions & 1 deletion bin/sozo/src/commands/options/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::{bail, Result};
use clap::Args;
use dojo_world::migration::TxnConfig;
use dojo_world::migration::{TxnAction, TxnConfig};
use starknet::core::types::FieldElement;
use tracing::trace;

Expand Down Expand Up @@ -38,6 +39,24 @@ pub struct TransactionOptions {
pub receipt: bool,
}

impl TransactionOptions {
pub fn to_txn_action(&self, simulate: bool, estimate_only: bool) -> Result<TxnAction> {
match (estimate_only, simulate) {
(true, true) => {
bail!("Both `--estimate-only` and `--simulate` cannot be used at same time.")
}
(true, false) => Ok(TxnAction::Estimate),
(false, true) => Ok(TxnAction::Simulate),
(false, false) => Ok(TxnAction::Send {
wait: self.wait,
receipt: self.receipt,
max_fee_raw: self.max_fee_raw,
fee_estimate_multiplier: self.fee_estimate_multiplier,
}),
}
}
}

impl From<TransactionOptions> for TxnConfig {
fn from(value: TransactionOptions) -> Self {
trace!(
Expand Down
3 changes: 2 additions & 1 deletion bin/sozo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ fn main() {
let ui = Ui::new(args.ui_verbosity(), OutputFormat::Text);

if let Err(err) = cli_main(args) {
ui.anyhow(&err);
ui.error(format!("{err}"));
err.chain().skip(1).for_each(|clause| eprintln!("reason: {:?}", clause));
exit(1);
}
}
Expand Down
14 changes: 14 additions & 0 deletions crates/dojo-world/src/migration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,20 @@ pub struct TxnConfig {
pub max_fee_raw: Option<FieldElement>,
}

#[derive(Debug, Copy, Clone)]
pub enum TxnAction {
Send {
wait: bool,
receipt: bool,
max_fee_raw: Option<FieldElement>,
/// The multiplier for how much the actual transaction max fee should be relative to the
/// estimated fee. If `None` is provided, the multiplier is set to `1.1`.
fee_estimate_multiplier: Option<f64>,
},
Estimate,
Simulate,
}

impl TxnConfig {
pub fn init_wait() -> Self {
Self { wait: true, ..Default::default() }
Expand Down
47 changes: 35 additions & 12 deletions crates/dojo-world/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ use std::task::{Context, Poll};
use std::time::Duration;

use futures::FutureExt;
use starknet::accounts::{AccountError, ConnectedAccount, Declaration, Execution};
use starknet::accounts::{
AccountDeployment, AccountError, AccountFactory, AccountFactoryError, ConnectedAccount,
Declaration, Execution,
};
use starknet::core::types::{
DeclareTransactionResult, ExecutionResult, FieldElement, InvokeTransactionResult,
MaybePendingTransactionReceipt, PendingTransactionReceipt, StarknetError,
TransactionFinalityStatus, TransactionReceipt, TransactionStatus,
DeclareTransactionResult, DeployAccountTransactionResult, ExecutionResult, FieldElement,
InvokeTransactionResult, MaybePendingTransactionReceipt, PendingTransactionReceipt,
StarknetError, TransactionFinalityStatus, TransactionReceipt, TransactionStatus,
};
use starknet::providers::{Provider, ProviderError};
use tokio::time::{Instant, Interval};
Expand Down Expand Up @@ -335,27 +338,23 @@ pub fn block_number_from_receipt(receipt: &TransactionReceipt) -> u64 {
/// Helper trait to abstract away setting `TxnConfig` configurations before sending a transaction
/// Implemented by types from `starknet-accounts` like `Execution`, `Declaration`, etc...
#[allow(async_fn_in_trait)]
pub trait TransactionExt<T>
where
T: ConnectedAccount + Sync,
{
pub trait TransactionExt<T> {
type R;
type U;

/// Sets `fee_estimate_multiplier` and `max_fee_raw` from `TxnConfig` if its present before
/// calling `send` method on the respective type.
/// NOTE: If both are specified `max_fee_raw` will take precedence and `fee_estimate_multiplier`
/// will be ignored by `starknet-rs`
async fn send_with_cfg(
self,
txn_config: &TxnConfig,
) -> Result<Self::R, AccountError<T::SignError>>;
async fn send_with_cfg(self, txn_config: &TxnConfig) -> Result<Self::R, Self::U>;
}

impl<T> TransactionExt<T> for Execution<'_, T>
where
T: ConnectedAccount + Sync,
{
type R = InvokeTransactionResult;
type U = AccountError<T::SignError>;

async fn send_with_cfg(
mut self,
Expand All @@ -378,6 +377,7 @@ where
T: ConnectedAccount + Sync,
{
type R = DeclareTransactionResult;
type U = AccountError<T::SignError>;

async fn send_with_cfg(
mut self,
Expand All @@ -395,6 +395,29 @@ where
}
}

impl<T> TransactionExt<T> for AccountDeployment<'_, T>
where
T: AccountFactory + Sync,
{
type R = DeployAccountTransactionResult;
type U = AccountFactoryError<T::SignError>;

async fn send_with_cfg(
mut self,
txn_config: &TxnConfig,
) -> Result<Self::R, AccountFactoryError<<T>::SignError>> {
if let TxnConfig { fee_estimate_multiplier: Some(fee_est_mul), .. } = txn_config {
self = self.fee_estimate_multiplier(*fee_est_mul);
}

if let TxnConfig { max_fee_raw: Some(max_raw_f), .. } = txn_config {
self = self.max_fee(*max_raw_f);
}

self.send().await
}
}

#[cfg(test)]
mod tests {
use assert_matches::assert_matches;
Expand Down
Loading

0 comments on commit a095ccf

Please sign in to comment.