Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
cea1b2f
fix UtxoTxBuilder::build() tx fee calculation to include change output;
Jan 8, 2025
455403c
Merge branch 'dev' into fix-utxo-tx-fee-for-change
Jan 8, 2025
8d2fe79
fix qrc20 gas fee calc in trade preimage
Jan 9, 2025
bc69a42
revert qtum gas_fee calc in trade preimage,
Jan 9, 2025
40cfbda
fix: err if change < dust (was <=)
Jan 23, 2025
50a38f8
refactor (onur-ozkan): use refs instead of clone in add_tx_inputs
Jan 23, 2025
615ff3e
refactor (mariocynicys): fix return_err_if macro to check if cond is …
Jan 23, 2025
3f709fc
refactor: rename vars to use always 'fee rate' root word
Jan 23, 2025
459a379
fix (mariocynicys): recalc kmd interest when tx inputs reselected and…
Feb 24, 2025
534006e
Merge branch 'dev' into fix-utxo-tx-fee-for-change
Feb 24, 2025
ad0699e
fix after merge
Feb 24, 2025
1b2c538
refactor (mariocynicys) removed unnecessary checks
Feb 24, 2025
110a236
fix fee_amount in AdditionalTxData, get rid of unused_change, add reu…
Feb 25, 2025
b5994e6
add extra test to check tx builder calc with many inputs
Feb 25, 2025
ae8c3ee
remove unused_change in utxo tx builder (var not used any more)
Mar 4, 2025
9126c49
fix utxo tx builder test: add randomizer, catch overpay
Mar 6, 2025
997dcee
Merge remote-tracking branch 'origin/dev' into fix-utxo-tx-fee-for-ch…
shamardy Mar 24, 2025
7ca03f4
review (mariocynicys): improve calc kmd interest performance with get…
May 2, 2025
850f7b3
Merge remote-tracking branch 'origin/dev' into fix-utxo-tx-fee-for-ch…
shamardy May 6, 2025
eab8902
fix after merge: rename the 2 different `is_kmd` methods to a more de…
shamardy May 6, 2025
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: 2 additions & 2 deletions mm2src/coins/qrc20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ impl Qrc20Coin {
/// `gas_fee` should be calculated by: gas_limit * gas_price * (count of contract calls),
/// or should be sum of gas fee of all contract calls.
pub async fn get_qrc20_tx_fee(&self, gas_fee: u64) -> Result<u64, String> {
match try_s!(self.get_tx_fee().await) {
match try_s!(self.get_fee_per_kb().await) {
ActualTxFee::Dynamic(amount) | ActualTxFee::FixedPerKb(amount) => Ok(amount + gas_fee),
}
}
Expand Down Expand Up @@ -613,7 +613,7 @@ impl UtxoTxBroadcastOps for Qrc20Coin {
#[cfg_attr(test, mockable)]
impl UtxoTxGenerationOps for Qrc20Coin {
/// Get only QTUM transaction fee.
async fn get_tx_fee(&self) -> UtxoRpcResult<ActualTxFee> { utxo_common::get_tx_fee(&self.utxo).await }
async fn get_fee_per_kb(&self) -> UtxoRpcResult<ActualTxFee> { utxo_common::get_fee_per_kb(&self.utxo).await }

async fn calc_interest_if_required(
&self,
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/qrc20/qrc20_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub fn qrc20_coin_for_test(priv_key: [u8; 32], fallback_swap: Option<&str>) -> (
}

fn check_tx_fee(coin: &Qrc20Coin, expected_tx_fee: ActualTxFee) {
let actual_tx_fee = block_on(coin.get_tx_fee()).unwrap();
let actual_tx_fee = block_on(coin.get_fee_per_kb()).unwrap();
assert_eq!(actual_tx_fee, expected_tx_fee);
}

Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/rpc_command/lightning/open_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ pub async fn open_channel(ctx: MmArc, req: OpenChannelRequest) -> OpenChannelRes
.with_fee_policy(fee_policy);

let fee = platform_coin
.get_tx_fee()
.get_fee_per_kb()
.await
.map_err(|e| OpenChannelError::RpcError(e.to_string()))?;
tx_builder = tx_builder.with_fee(fee);
Expand Down
37 changes: 34 additions & 3 deletions mm2src/coins/utxo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,43 @@ pub enum TxFee {
pub enum ActualTxFee {
/// fee amount per Kbyte received from coin RPC
Dynamic(u64),
/// Use specified amount per each 1 kb of transaction and also per each output less than amount.
/// Use specified fee amount per each 1 kb of transaction and also per each output less than the fee amount.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you explain more about this fee scheme. the per each output part isn't really clear (understood it as 1 fee_rate per 1 output, which i doubt is a correct understanding).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, actually I have the same question:
this fee calc is not fully clear to me. The comment refers to DOGE, I took a look at its daemon code but did not find where this logic is.

/// Used by DOGE, but more coins might support it too.
FixedPerKb(u64),
}

impl ActualTxFee {
fn get_tx_fee(&self, tx_size: u64) -> u64 {
match self {
ActualTxFee::Dynamic(fee_per_kb) => (fee_per_kb * tx_size) / KILO_BYTE,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couldn't this wrongfully floor to zero?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it could.
If it goes too low we would use min relay fee (if this is set though)

// return fee_per_kb here as swap spend transaction size is always less than 1 kb
ActualTxFee::FixedPerKb(fee_per_kb) => {
let tx_size_kb = if tx_size % KILO_BYTE == 0 {
tx_size / KILO_BYTE
} else {
tx_size / KILO_BYTE + 1
};
fee_per_kb * tx_size_kb
},
}
}

/// Return extra tx fee for the change output as p2pkh
fn get_tx_fee_for_change(&self, tx_size: Option<u64>) -> u64 {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that tx_size can be used as u64 (see the other suggestions)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed Option from get_tx_fee_for_change in 3f709fc

match self {
ActualTxFee::Dynamic(fee_per_kb) => (*fee_per_kb * P2PKH_OUTPUT_LEN) / KILO_BYTE,
ActualTxFee::FixedPerKb(fee_per_kb) => {
// take into account the change output if tx_size_kb(tx with change) > tx_size_kb(tx without change)
if tx_size.unwrap_or_default() % KILO_BYTE + P2PKH_OUTPUT_LEN > KILO_BYTE {
*fee_per_kb
} else {
0
}
},
}
}
}

/// Fee policy applied on transaction creation
pub enum FeePolicy {
/// Send the exact amount specified in output(s), fee is added to spent input amount
Expand Down Expand Up @@ -840,7 +872,7 @@ pub trait UtxoTxBroadcastOps {
#[async_trait]
#[cfg_attr(test, mockable)]
pub trait UtxoTxGenerationOps {
async fn get_tx_fee(&self) -> UtxoRpcResult<ActualTxFee>;
async fn get_fee_per_kb(&self) -> UtxoRpcResult<ActualTxFee>;

/// Calculates interest if the coin is KMD
/// Adds the value to existing output to my_script_pub or creates additional interest output
Expand Down Expand Up @@ -1741,7 +1773,6 @@ where
{
let my_address = try_tx_s!(coin.as_ref().derivation_method.single_addr_or_err().await);
let key_pair = try_tx_s!(coin.as_ref().priv_key_policy.activated_key_or_err());

let mut builder = UtxoTxBuilder::new(coin)
.await
.add_available_inputs(unspents)
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/utxo/bch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ impl UtxoTxBroadcastOps for BchCoin {
#[async_trait]
#[cfg_attr(test, mockable)]
impl UtxoTxGenerationOps for BchCoin {
async fn get_tx_fee(&self) -> UtxoRpcResult<ActualTxFee> { utxo_common::get_tx_fee(&self.utxo_arc).await }
async fn get_fee_per_kb(&self) -> UtxoRpcResult<ActualTxFee> { utxo_common::get_fee_per_kb(&self.utxo_arc).await }

async fn calc_interest_if_required(
&self,
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/utxo/qtum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ impl UtxoTxBroadcastOps for QtumCoin {
#[async_trait]
#[cfg_attr(test, mockable)]
impl UtxoTxGenerationOps for QtumCoin {
async fn get_tx_fee(&self) -> UtxoRpcResult<ActualTxFee> { utxo_common::get_tx_fee(&self.utxo_arc).await }
async fn get_fee_per_kb(&self) -> UtxoRpcResult<ActualTxFee> { utxo_common::get_fee_per_kb(&self.utxo_arc).await }

async fn calc_interest_if_required(
&self,
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/utxo/slp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,7 @@ impl UtxoTxBroadcastOps for SlpToken {

#[async_trait]
impl UtxoTxGenerationOps for SlpToken {
async fn get_tx_fee(&self) -> UtxoRpcResult<ActualTxFee> { self.platform_coin.get_tx_fee().await }
async fn get_fee_per_kb(&self) -> UtxoRpcResult<ActualTxFee> { self.platform_coin.get_fee_per_kb().await }

async fn calc_interest_if_required(
&self,
Expand Down
Loading
Loading