Skip to content

Commit

Permalink
orderbook and trade_preimage RPC improvements #859 #872 (#883)
Browse files Browse the repository at this point in the history
* WIP.

* WIP.

* WIP.

* WIP and fix clippy.

* Refactor and fix clippy.

* WIP. Adding the UTXO fee to spend other payment to trade_preimage.

* WIP. Refactor tests.

* Finalize trade_preimage changes and refactor tests.

* Add paid_from_trading_vol to SavedTradeFee and refactor.

* Fix WASM tests compilation.

* Add separate TotalTradeFee struct for total_fees.

* Set QTUM/QRC20 mature_confirmations to 2000.
  • Loading branch information
artemii235 authored Mar 31, 2021
1 parent c1c8a53 commit 5c864f5
Show file tree
Hide file tree
Showing 24 changed files with 833 additions and 440 deletions.
4 changes: 4 additions & 0 deletions mm2src/coins/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2488,6 +2488,7 @@ impl MmCoin for EthCoin {
Ok(TradeFee {
coin: fee_coin.into(),
amount: try_s!(u256_to_big_decimal(fee, 18)).into(),
paid_from_trading_vol: false,
})
}))
}
Expand Down Expand Up @@ -2535,6 +2536,7 @@ impl MmCoin for EthCoin {
Ok(TradeFee {
coin: fee_coin.into(),
amount: amount.into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
Expand All @@ -2557,6 +2559,7 @@ impl MmCoin for EthCoin {
Ok(TradeFee {
coin: fee_coin.into(),
amount: amount.into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
Expand Down Expand Up @@ -2613,6 +2616,7 @@ impl MmCoin for EthCoin {
Ok(TradeFee {
coin: fee_coin.into(),
amount: amount.into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
Expand Down
4 changes: 4 additions & 0 deletions mm2src/coins/eth/eth_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ fn get_sender_trade_preimage() {
TradeFee {
coin: "ETH".to_owned(),
amount: amount.into(),
paid_from_trading_vol: false,
}
}

Expand Down Expand Up @@ -739,6 +740,7 @@ fn get_erc20_sender_trade_preimage() {
TradeFee {
coin: "ETH".to_owned(),
amount: amount.into(),
paid_from_trading_vol: false,
}
}

Expand Down Expand Up @@ -806,6 +808,7 @@ fn get_receiver_trade_preimage() {
let expected_fee = TradeFee {
coin: "ETH".to_owned(),
amount: amount.into(),
paid_from_trading_vol: false,
};

let actual = coin
Expand All @@ -829,6 +832,7 @@ fn test_get_fee_to_send_taker_fee() {
let expected_fee = TradeFee {
coin: "ETH".to_owned(),
amount: amount.into(),
paid_from_trading_vol: false,
};

let dex_fee_amount = u256_to_big_decimal(DEX_FEE_AMOUNT.into(), 18).expect("!u256_to_big_decimal");
Expand Down
1 change: 1 addition & 0 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ impl TransactionDetails {
pub struct TradeFee {
pub coin: String,
pub amount: MmNumber,
pub paid_from_trading_vol: bool,
}

#[derive(Clone, Debug, PartialEq, PartialOrd)]
Expand Down
4 changes: 4 additions & 0 deletions mm2src/coins/qrc20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,7 @@ impl MmCoin for Qrc20Coin {
Ok(TradeFee {
coin: selfi.platform.clone(),
amount: big_decimal_from_sat(fee as i64, selfi.utxo.decimals).into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
Expand Down Expand Up @@ -1016,6 +1017,7 @@ impl MmCoin for Qrc20Coin {
Ok(TradeFee {
coin: selfi.platform.clone(),
amount: total_fee.into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
Expand Down Expand Up @@ -1046,6 +1048,7 @@ impl MmCoin for Qrc20Coin {
Ok(TradeFee {
coin: selfi.platform.clone(),
amount: total_fee.into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
Expand Down Expand Up @@ -1077,6 +1080,7 @@ impl MmCoin for Qrc20Coin {
Ok(TradeFee {
coin: selfi.platform.clone(),
amount: total_fee.into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
Expand Down
10 changes: 8 additions & 2 deletions mm2src/coins/qrc20/qrc20_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub fn qrc20_coin_for_test(priv_key: &[u8]) -> (MmArc, Qrc20Coin) {
"wiftype":128,
"segwit":true,
"mm2":1,
"mature_confirmations":500,
"mature_confirmations":2000,
});
let req = json!({
"method": "electrum",
Expand Down Expand Up @@ -602,6 +602,7 @@ fn test_get_trade_fee() {
let expected = TradeFee {
coin: "QTUM".into(),
amount: expected_trade_fee_amount.into(),
paid_from_trading_vol: false,
};
assert_eq!(actual_trade_fee, expected);
}
Expand Down Expand Up @@ -635,6 +636,7 @@ fn test_sender_trade_preimage_zero_allowance() {
let expected = TradeFee {
coin: "QTUM".to_owned(),
amount: (erc20_payment_fee_with_one_approve + sender_refund_fee).into(),
paid_from_trading_vol: false,
};
assert_eq!(actual, expected);
}
Expand Down Expand Up @@ -671,6 +673,7 @@ fn test_sender_trade_preimage_with_allowance() {
let expected = TradeFee {
coin: "QTUM".to_owned(),
amount: (erc20_payment_fee_without_approve + sender_refund_fee.clone()).into(),
paid_from_trading_vol: false,
};
assert_eq!(actual, expected);

Expand All @@ -682,6 +685,7 @@ fn test_sender_trade_preimage_with_allowance() {
let expected = TradeFee {
coin: "QTUM".to_owned(),
amount: (erc20_payment_fee_with_two_approves + sender_refund_fee).into(),
paid_from_trading_vol: false,
};
assert_eq!(actual, expected);
}
Expand All @@ -708,6 +712,7 @@ fn test_receiver_trade_preimage() {
let expected = TradeFee {
coin: "QTUM".to_owned(),
amount: expected_receiver_fee.into(),
paid_from_trading_vol: false,
};
assert_eq!(actual, expected);
}
Expand Down Expand Up @@ -740,6 +745,7 @@ fn test_taker_fee_tx_fee() {
let expected = TradeFee {
coin: "QTUM".to_owned(),
amount: expected_receiver_fee.into(),
paid_from_trading_vol: false,
};
assert_eq!(actual, expected);
}
Expand All @@ -759,7 +765,7 @@ fn test_coin_from_conf_without_decimals() {
"wiftype":128,
"segwit":true,
"mm2":1,
"mature_confirmations":500,
"mature_confirmations":2000,
});
let req = json!({
"method": "electrum",
Expand Down
14 changes: 12 additions & 2 deletions mm2src/coins/test_coin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,22 @@ use serde_json::Value as Json;
/// Dummy coin struct used in tests which functions are unimplemented but then mocked
/// in specific test to emulate the required behaviour
#[derive(Clone, Debug)]
pub struct TestCoin {}
pub struct TestCoin {
ticker: String,
}

impl Default for TestCoin {
fn default() -> Self { TestCoin { ticker: "test".into() } }
}

impl TestCoin {
pub fn new(ticker: &str) -> TestCoin { TestCoin { ticker: ticker.into() } }
}

#[mockable]
#[allow(clippy::forget_ref, clippy::forget_copy, clippy::cast_ref_to_mut)]
impl MarketCoinOps for TestCoin {
fn ticker(&self) -> &str { "test" }
fn ticker(&self) -> &str { &self.ticker }

fn my_address(&self) -> Result<String, String> { unimplemented!() }

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 @@ -531,7 +531,7 @@ impl MmCoin for QtumCoin {
&self,
_stage: FeeApproxStage,
) -> Box<dyn Future<Item = TradeFee, Error = TradePreimageError> + Send> {
utxo_common::get_receiver_trade_fee(self)
utxo_common::get_receiver_trade_fee(self.clone())
}

fn get_fee_to_send_taker_fee(
Expand Down
27 changes: 19 additions & 8 deletions mm2src/coins/utxo/utxo_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1852,6 +1852,7 @@ where
Ok(TradeFee {
coin: ticker,
amount: big_decimal_from_sat(amount as i64, decimals).into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
Expand Down Expand Up @@ -1972,22 +1973,27 @@ where
Ok(TradeFee {
coin: coin.as_ref().conf.ticker.clone(),
amount: fee_amount.into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
}

/// Payment sender should not pay fee for sending Maker Payment.
/// Even if refund will be required the fee will be deducted from P2SH input.
pub fn get_receiver_trade_fee<T>(coin: &T) -> Box<dyn Future<Item = TradeFee, Error = TradePreimageError> + Send>
/// The fee to spend (receive) other payment is deducted from the trading amount so we should display it
pub fn get_receiver_trade_fee<T>(coin: T) -> Box<dyn Future<Item = TradeFee, Error = TradePreimageError> + Send>
where
T: AsRef<UtxoCoinFields>,
T: AsRef<UtxoCoinFields> + UtxoCommonOps + Send + Sync + 'static,
{
let trade_fee = TradeFee {
coin: coin.as_ref().conf.ticker.clone(),
amount: 0.into(),
let fut = async move {
let amount_sat = try_map!(get_htlc_spend_fee(&coin).await, TradePreimageError::Other);
let amount = big_decimal_from_sat_unsigned(amount_sat, coin.as_ref().decimals).into();
Ok(TradeFee {
coin: coin.as_ref().conf.ticker.clone(),
amount,
paid_from_trading_vol: true,
})
};
Box::new(futures01::future::ok(trade_fee))
Box::new(fut.boxed().compat())
}

pub fn get_fee_to_send_taker_fee<T>(
Expand Down Expand Up @@ -2016,6 +2022,7 @@ where
Ok(TradeFee {
coin: coin.ticker().to_owned(),
amount: fee_amount.into(),
paid_from_trading_vol: false,
})
};
Box::new(fut.boxed().compat())
Expand Down Expand Up @@ -2229,6 +2236,10 @@ pub fn big_decimal_from_sat(satoshis: i64, decimals: u8) -> BigDecimal {
BigDecimal::from(satoshis) / BigDecimal::from(10u64.pow(decimals as u32))
}

pub fn big_decimal_from_sat_unsigned(satoshis: u64, decimals: u8) -> BigDecimal {
BigDecimal::from(satoshis) / BigDecimal::from(10u64.pow(decimals as u32))
}

pub fn address_from_raw_pubkey(
pub_key: &[u8],
prefix: u8,
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/utxo/utxo_standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ impl MmCoin for UtxoStandardCoin {
&self,
_stage: FeeApproxStage,
) -> Box<dyn Future<Item = TradeFee, Error = TradePreimageError> + Send> {
utxo_common::get_receiver_trade_fee(&self)
utxo_common::get_receiver_trade_fee(self.clone())
}

fn get_fee_to_send_taker_fee(
Expand Down
2 changes: 1 addition & 1 deletion mm2src/coins/utxo/utxo_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2160,7 +2160,7 @@ fn test_qtum_is_unspent_mature() {

#[test]
#[ignore]
// TODO it fails in certain cases of the tx fee, need to investigate
// TODO it fails at least when fee is 2055837 sat per kbyte, need to investigate
fn test_get_sender_trade_fee_dynamic_tx_fee() {
let rpc_client = electrum_client_for_test(&["95.217.83.126:10001"]);
let mut coin_fields = utxo_coin_fields_for_test(
Expand Down
2 changes: 1 addition & 1 deletion mm2src/common/big_int_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;

/// BigInt wrapper de/serializable from/to string representation
#[derive(Clone)]
#[derive(Clone, Eq, PartialEq)]
pub struct BigIntStr(BigInt);

impl fmt::Debug for BigIntStr {
Expand Down
6 changes: 5 additions & 1 deletion mm2src/common/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,11 @@ fn root() -> PathBuf {
/// Absolute path taken from SuperNET's root + `path`.
fn rabs(rrel: &str) -> PathBuf { root().join(rrel) }

fn path2s(path: PathBuf) -> String { path.to_str().expect(&format!("Non-stringy path {:?}", path)).into() }
fn path2s(path: PathBuf) -> String {
path.to_str()
.unwrap_or_else(|| panic!("Non-stringy path {:?}", path))
.into()
}

/// Loads the `path`, runs `update` on it and saves back the result if it differs.
fn _in_place(path: &dyn AsRef<Path>, update: &mut dyn FnMut(Vec<u8>) -> Vec<u8>) {
Expand Down
22 changes: 18 additions & 4 deletions mm2src/common/mm_number.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::big_int_str::BigIntStr;
use bigdecimal::BigDecimal;
use core::ops::{Add, Div, Mul, Sub};
use core::ops::{Add, AddAssign, Div, Mul, Sub};
use num_rational::BigRational;
use num_traits::{Pow, Zero};
use serde::{de, Deserialize, Deserializer, Serialize};
use serde_json::value::RawValue;
use std::str::FromStr;

pub use num_bigint::{BigInt, Sign};
pub use paste::paste;

/// Construct a `$name` detailed number that have decimal, fraction and rational representations.
Expand Down Expand Up @@ -45,18 +46,23 @@ macro_rules! construct_detailed {
}
}
}

#[allow(dead_code)]
impl $name {
pub fn as_ratio(&self) -> &BigRational {
&self.[<$base_field _rat>]
}
}
}
};
}

pub use num_bigint::{BigInt, Sign};

#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize)]
pub struct MmNumber(BigRational);

/// Rational number representation de/serializable in human readable form
/// Should simplify the visual perception and parsing in code
#[derive(Clone, Debug, Serialize)]
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Fraction {
/// Numerator
numer: BigIntStr,
Expand Down Expand Up @@ -209,6 +215,14 @@ impl Add for MmNumber {
fn add(self, rhs: Self) -> Self::Output { (self.0 + rhs.0).into() }
}

impl AddAssign for MmNumber {
fn add_assign(&mut self, rhs: Self) { self.0 += rhs.0; }
}

impl AddAssign<&MmNumber> for MmNumber {
fn add_assign(&mut self, rhs: &Self) { self.0 += &rhs.0; }
}

impl Add for &MmNumber {
type Output = MmNumber;

Expand Down
Loading

0 comments on commit 5c864f5

Please sign in to comment.