Skip to content

Commit

Permalink
use get_sender_trade_fee for non-htlc TXs
Browse files Browse the repository at this point in the history
there is no calculatable tx_size for other tx (non-htlc) (like funding and maker payment txs). their fees depend really on the utxos we have and whether they are segwit or not.
used get_sender_trade_fee for now, though I think this method needs reviewing since its doc comment doesn't make a lot of sense
  • Loading branch information
mariocynicys committed Jul 29, 2024
1 parent 638d90e commit 12e1b66
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 85 deletions.
10 changes: 5 additions & 5 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1681,10 +1681,10 @@ pub trait MakerCoinSwapOpsV2: ParseCoinAssocTypes + Send + Sync + 'static {
async fn spend_maker_payment_v2(&self, args: SpendMakerPaymentArgs<'_, Self>) -> Result<Self::Tx, TransactionErr>;

/// Get the fee to be paid for the processing of the maker payment transaction.
async fn get_maker_payment_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee>;
async fn get_maker_payment_fee(&self, value: TradePreimageValue) -> TradePreimageResult<TradeFee>;

/// Get the fee to be paid for the processing of the maker payment spend transaction aka the claiming transaction.
async fn get_maker_payment_spend_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee>;
async fn get_maker_payment_spend_fee(&self) -> TradePreimageResult<TradeFee>;
}

#[async_trait]
Expand Down Expand Up @@ -1890,13 +1890,13 @@ pub trait TakerCoinSwapOpsV2: ParseCoinAssocTypes + Send + Sync + 'static {
/// Txs in success case (no refund) go as follows:
/// Chain A: funding -> taker payment -> taker payment spend (aka preimage) (to the maker & dex)
/// Chain B: maker payment -> maker payment spend (aka claiming) (to the taker)
async fn get_funding_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee>;
async fn get_funding_fee(&self, value: TradePreimageValue) -> TradePreimageResult<TradeFee>;

/// Get the fee to be paid for the processing of the taker payment transaction.
async fn get_taker_payment_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee>;
async fn get_taker_payment_fee(&self) -> TradePreimageResult<TradeFee>;

/// Get the fee to be paid for the processing of the taker payment spend transaction aka the preimage transaction.
async fn get_taker_payment_spend_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee>;
async fn get_taker_payment_spend_fee(&self) -> TradePreimageResult<TradeFee>;
}

/// Operations that coins have independently from the MarketMaker.
Expand Down
6 changes: 3 additions & 3 deletions mm2src/coins/test_coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,9 +558,9 @@ impl TakerCoinSwapOpsV2 for TestCoin {

fn derive_htlc_pubkey_v2(&self, swap_unique_data: &[u8]) -> Self::Pubkey { todo!() }

async fn get_funding_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee> { todo!() }
async fn get_funding_fee(&self, value: TradePreimageValue) -> TradePreimageResult<TradeFee> { todo!() }

async fn get_taker_payment_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee> { todo!() }
async fn get_taker_payment_fee(&self) -> TradePreimageResult<TradeFee> { todo!() }

async fn get_taker_payment_spend_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee> { todo!() }
async fn get_taker_payment_spend_fee(&self) -> TradePreimageResult<TradeFee> { todo!() }
}
31 changes: 4 additions & 27 deletions mm2src/coins/utxo/utxo_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -884,26 +884,8 @@ enum FundingSpendFeeSetting {
pub mod tx_sizes {
use super::*;

/// Returns the taker funding transaction size in vbytes.
pub async fn get_funding_tx_size(_coin: &impl UtxoCommonOps) -> usize {
// This depends on what coins being spent so might be a bit clumsy.
// Since this is the first tx anyway, we won't need a utxo locking mechanism
// to prevent certain utxos from being spent in other swaps happening in parallel.
// We just need to make sure that we deliver the correct trading volume and not less.

// FIXME: Inspect `get_sender_trade_fee`, but I don't think it nails it correctly.
todo!()
}

/// Returns the maker payment transaction size in vbytes.
pub async fn get_maker_payment_tx_size(coin: &impl UtxoCommonOps) -> usize {
// Maker payment is similar to funding tx in that it spends coins directly from the user's
// wallet and sends them to P2SH address.
get_funding_tx_size(coin).await
}

/// Returns the taker payment transaction size in vbytes.
pub async fn get_taker_payment_tx_size(coin: &impl UtxoCommonOps) -> usize {
pub fn get_taker_payment_tx_size(coin: &impl UtxoCommonOps) -> usize {
let preimage = TransactionInputSigner {
lock_time: 0,
version: coin.as_ref().conf.tx_version,
Expand Down Expand Up @@ -961,7 +943,7 @@ pub mod tx_sizes {
}

/// Returns the taker payment spend transaction size in vbytes.
pub async fn get_taker_payment_spend_tx_size(coin: &impl UtxoCommonOps) -> usize {
pub fn get_taker_payment_spend_tx_size(coin: &impl UtxoCommonOps) -> usize {
let preimage = TransactionInputSigner {
lock_time: 0,
version: coin.as_ref().conf.tx_version,
Expand Down Expand Up @@ -1022,7 +1004,7 @@ pub mod tx_sizes {
}

/// Returns the maker payment spend transaction size in vbytes.
pub async fn get_maker_payment_spend_tx_size(coin: &impl UtxoCommonOps) -> usize {
pub fn get_maker_payment_spend_tx_size(coin: &impl UtxoCommonOps) -> usize {
let preimage = TransactionInputSigner {
lock_time: 0,
version: coin.as_ref().conf.tx_version,
Expand Down Expand Up @@ -1213,12 +1195,7 @@ where

let fee = match fee {
FundingSpendFeeSetting::GetFromCoin => {
let calculated_fee = coin
.get_taker_payment_fee(&FeeApproxStage::WithoutApprox)
.await
.unwrap()
.amount
.to_decimal();
let calculated_fee = coin.get_taker_payment_fee().await.unwrap().amount.to_decimal();
let calculated_fee = sat_from_big_decimal(&calculated_fee, coin.as_ref().decimals).mm_err(|e| e.into())?;
let taker_instructed_fee =
sat_from_big_decimal(&args.taker_payment_fee, coin.as_ref().decimals).mm_err(|e| e.into())?;
Expand Down
46 changes: 19 additions & 27 deletions mm2src/coins/utxo/utxo_standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -651,21 +651,16 @@ impl MakerCoinSwapOpsV2 for UtxoStandardCoin {
utxo_common::spend_maker_payment_v2(self, args).await
}

async fn get_maker_payment_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee> {
let maker_payment_tx_size = utxo_common::tx_sizes::get_maker_payment_tx_size(self).await;
let fee_sat = self.get_htlc_spend_fee(maker_payment_tx_size as u64, stage).await?;
let amount = big_decimal_from_sat_unsigned(fee_sat, self.as_ref().decimals).into();
Ok(TradeFee {
coin: self.as_ref().conf.ticker.clone(),
amount,
paid_from_trading_vol: true,
})
async fn get_maker_payment_fee(&self, value: TradePreimageValue) -> TradePreimageResult<TradeFee> {
let mut fee = utxo_common::get_sender_trade_fee(self, value, FeeApproxStage::StartSwap).await?;
fee.paid_from_trading_vol = true;
Ok(fee)
}

async fn get_maker_payment_spend_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee> {
let maker_payment_spend_tx_size = utxo_common::tx_sizes::get_maker_payment_spend_tx_size(self).await;
async fn get_maker_payment_spend_fee(&self) -> TradePreimageResult<TradeFee> {
let maker_payment_spend_tx_size = utxo_common::tx_sizes::get_maker_payment_spend_tx_size(self);
let fee_sat = self
.get_htlc_spend_fee(maker_payment_spend_tx_size as u64, stage)
.get_htlc_spend_fee(maker_payment_spend_tx_size as u64, &FeeApproxStage::TradePreimage)
.await?;
let amount = big_decimal_from_sat_unsigned(fee_sat, self.as_ref().decimals).into();
Ok(TradeFee {
Expand Down Expand Up @@ -852,20 +847,17 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin {
*self.derive_htlc_key_pair(swap_unique_data).public()
}

async fn get_funding_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee> {
let funding_tx_size = utxo_common::tx_sizes::get_funding_tx_size(self).await;
let fee_sat = self.get_htlc_spend_fee(funding_tx_size as u64, stage).await?;
let amount = big_decimal_from_sat_unsigned(fee_sat, self.as_ref().decimals).into();
Ok(TradeFee {
coin: self.as_ref().conf.ticker.clone(),
amount,
paid_from_trading_vol: true,
})
async fn get_funding_fee(&self, value: TradePreimageValue) -> TradePreimageResult<TradeFee> {
let mut fee = utxo_common::get_sender_trade_fee(self, value, FeeApproxStage::StartSwap).await?;
fee.paid_from_trading_vol = true;
Ok(fee)
}

async fn get_taker_payment_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee> {
let taker_payment_tx_size = utxo_common::tx_sizes::get_taker_payment_tx_size(self).await;
let fee_sat = self.get_htlc_spend_fee(taker_payment_tx_size as u64, stage).await?;
async fn get_taker_payment_fee(&self) -> TradePreimageResult<TradeFee> {
let taker_payment_tx_size = utxo_common::tx_sizes::get_taker_payment_tx_size(self);
let fee_sat = self
.get_htlc_spend_fee(taker_payment_tx_size as u64, &FeeApproxStage::TradePreimage)
.await?;
let amount = big_decimal_from_sat_unsigned(fee_sat, self.as_ref().decimals).into();
Ok(TradeFee {
coin: self.as_ref().conf.ticker.clone(),
Expand All @@ -874,10 +866,10 @@ impl TakerCoinSwapOpsV2 for UtxoStandardCoin {
})
}

async fn get_taker_payment_spend_fee(&self, stage: &FeeApproxStage) -> TradePreimageResult<TradeFee> {
let taker_payment_spend_tx_size = utxo_common::tx_sizes::get_taker_payment_spend_tx_size(self).await;
async fn get_taker_payment_spend_fee(&self) -> TradePreimageResult<TradeFee> {
let taker_payment_spend_tx_size = utxo_common::tx_sizes::get_taker_payment_spend_tx_size(self);
let fee_sat = self
.get_htlc_spend_fee(taker_payment_spend_tx_size as u64, stage)
.get_htlc_spend_fee(taker_payment_spend_tx_size as u64, &FeeApproxStage::TradePreimage)
.await?;
let amount = big_decimal_from_sat_unsigned(fee_sat, self.as_ref().decimals).into();
Ok(TradeFee {
Expand Down
17 changes: 6 additions & 11 deletions mm2src/mm2_main/src/lp_swap/maker_swap_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use super::{swap_v2_topic, LockedAmount, LockedAmountInfo, SavedTradeFee, SwapsC
NEGOTIATION_TIMEOUT_SEC};
use crate::mm2::lp_swap::maker_swap::MakerSwapPreparedParams;
use crate::mm2::lp_swap::swap_lock::SwapLock;
use crate::mm2::lp_swap::swap_v2_pb::*;
use crate::mm2::lp_swap::{broadcast_swap_v2_msg_every, check_balance_for_maker_swap, recv_swap_v2_msg, SecretHashAlgo,
SwapConfirmationsSettings, TransactionIdentifier, MAKER_SWAP_V2_TYPE, MAX_STARTED_AT_DIFF};
use crate::mm2::lp_swap::{swap_v2_pb::*, NO_REFUND_FEE};
use async_trait::async_trait;
use bitcrypto::{dhash160, sha256};
use coins::utxo::utxo_common::big_decimal_from_sat_unsigned;
Expand Down Expand Up @@ -799,23 +799,18 @@ impl<MakerCoin: MmCoin + MakerCoinSwapOpsV2, TakerCoin: MmCoin + TakerCoinSwapOp
};

let preimage_value = TradePreimageValue::Exact(state_machine.maker_volume.to_decimal());
let stage = FeeApproxStage::StartSwap;
let maker_payment_fee = match state_machine
.maker_coin
.get_sender_trade_fee(preimage_value, stage, NO_REFUND_FEE)
.await
{
let maker_payment_fee = match state_machine.maker_coin.get_maker_payment_fee(preimage_value).await {
Ok(fee) => fee,
Err(e) => {
let reason = AbortReason::FailedToGetMakerPaymentFee(e.to_string());
return Self::change_state(Aborted::new(reason), state_machine).await;
},
};

let taker_payment_fee = match state_machine.taker_coin.get_taker_payment_fee(&stage).await {
let taker_payment_fee = match state_machine.taker_coin.get_taker_payment_fee().await {
Ok(fee) => fee,
Err(e) => {
let reason = AbortReason::FailedToGetTakerPaymentSpendFee(e.to_string());
let reason = AbortReason::FailedToGetTakerPaymentFee(e.to_string());
return Self::change_state(Aborted::new(reason), state_machine).await;
},
};
Expand All @@ -832,7 +827,7 @@ impl<MakerCoin: MmCoin + MakerCoinSwapOpsV2, TakerCoin: MmCoin + TakerCoinSwapOp
state_machine.maker_volume.clone(),
Some(&state_machine.uuid),
Some(prepared_params),
FeeApproxStage::StartSwap,
FeeApproxStage::StartSwap, // Not used since prepared params are provided.
)
.await
{
Expand Down Expand Up @@ -1813,7 +1808,7 @@ pub enum AbortReason {
TakerPaymentSpentFeeTooLow(BigDecimal),
MakerPaymentRefundFailed(String),
FailedToGetMakerPaymentFee(String),
FailedToGetTakerPaymentSpendFee(String),
FailedToGetTakerPaymentFee(String),
}

struct Aborted<MakerCoin, TakerCoin> {
Expand Down
18 changes: 6 additions & 12 deletions mm2src/mm2_main/src/lp_swap/taker_swap_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ use super::swap_v2_common::*;
use super::{LockedAmount, LockedAmountInfo, SavedTradeFee, SwapsContext, TakerSwapPreparedParams,
NEGOTIATE_SEND_INTERVAL, NEGOTIATION_TIMEOUT_SEC};
use crate::mm2::lp_swap::swap_lock::SwapLock;
use crate::mm2::lp_swap::swap_v2_pb::*;
use crate::mm2::lp_swap::{broadcast_swap_v2_msg_every, check_balance_for_taker_swap, recv_swap_v2_msg, swap_v2_topic,
SecretHashAlgo, SwapConfirmationsSettings, TransactionIdentifier, MAX_STARTED_AT_DIFF,
TAKER_SWAP_V2_TYPE};
use crate::mm2::lp_swap::{swap_v2_pb::*, NO_REFUND_FEE};
use async_trait::async_trait;
use bitcrypto::{dhash160, sha256};
use coins::utxo::sat_from_big_decimal;
Expand Down Expand Up @@ -940,36 +940,30 @@ impl<MakerCoin: MmCoin + MakerCoinSwapOpsV2, TakerCoin: MmCoin + TakerCoinSwapOp
},
};

let stage = FeeApproxStage::StartSwap;

// The fee for the taker payment, accounted for in the total payment value.
// This is so the maker doesn't have to pay it from the trading volume.
let taker_payment_fee = match state_machine.taker_coin.get_taker_payment_fee(&stage).await {
let taker_payment_fee = match state_machine.taker_coin.get_taker_payment_fee().await {
Ok(fee) => fee,
Err(e) => {
let reason = AbortReason::FailedToGetTakerPaymentSpendFee(e.to_string());
return Self::change_state(Aborted::new(reason), state_machine).await;
},
};

// TODO: Add the price of maker payment fee (in taker coin) + preimage fee to the total payment value.
// TODO: Add the price of maker_payment fee (in taker coin) + taker_payment_spend fee to the total payment value.
let total_payment_value = &(&state_machine.taker_volume + &state_machine.dex_fee.total_spend_amount())
+ &(&state_machine.taker_premium + &taker_payment_fee.amount);
let preimage_value = TradePreimageValue::Exact(total_payment_value.to_decimal());

let funding_fee = match state_machine
.taker_coin
.get_sender_trade_fee(preimage_value, stage, NO_REFUND_FEE)
.await
{
let funding_fee = match state_machine.taker_coin.get_funding_fee(preimage_value).await {
Ok(fee) => fee,
Err(e) => {
let reason = AbortReason::FailedToGetTakerPaymentFee(e.to_string());
return Self::change_state(Aborted::new(reason), state_machine).await;
},
};

let maker_payment_spend_fee = match state_machine.maker_coin.get_maker_payment_spend_fee(&stage).await {
let maker_payment_spend_fee = match state_machine.maker_coin.get_maker_payment_spend_fee().await {
Ok(fee) => fee,
Err(e) => {
let reason = AbortReason::FailedToGetMakerPaymentSpendFee(e.to_string());
Expand Down Expand Up @@ -999,7 +993,7 @@ impl<MakerCoin: MmCoin + MakerCoinSwapOpsV2, TakerCoin: MmCoin + TakerCoinSwapOp
total_payment_value,
Some(&state_machine.uuid),
Some(prepared_params),
stage,
FeeApproxStage::StartSwap, // Not used since prepared params are provided.
)
.await
{
Expand Down

0 comments on commit 12e1b66

Please sign in to comment.