From daeafc80c01d1ab6aa1914f9a019500b42688fa7 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Tue, 5 Apr 2022 14:04:12 +0300 Subject: [PATCH 01/48] send p2p transaction message to `txhlp/$coin.ticker` topic Signed-off-by: ozkanonur --- mm2src/lp_swap.rs | 15 +++++++++++++++ mm2src/lp_swap/maker_swap.rs | 16 ++++++++++++++++ mm2src/lp_swap/taker_swap.rs | 15 +++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/mm2src/lp_swap.rs b/mm2src/lp_swap.rs index 7924bbcdd3..3ddac913ac 100644 --- a/mm2src/lp_swap.rs +++ b/mm2src/lp_swap.rs @@ -114,6 +114,8 @@ pub use trade_preimage::trade_preimage_rpc; pub const SWAP_PREFIX: TopicPrefix = "swap"; +pub const TX_HELPER_PREFIX: TopicPrefix = "txhlp"; + cfg_wasm32! { use common::indexed_db::{ConstructibleDb, DbLocked}; use swap_wasm_db::{InitDbResult, SwapDb}; @@ -129,6 +131,7 @@ pub enum SwapMsg { TakerFee(Vec), MakerPayment(Vec), TakerPayment(Vec), + Transaction(Vec), } #[derive(Debug, Default)] @@ -139,6 +142,7 @@ pub struct SwapMsgStore { taker_fee: Option>, maker_payment: Option>, taker_payment: Option>, + transaction: Option>, accept_only_from: bits256, } @@ -226,6 +230,7 @@ pub async fn process_msg(ctx: MmArc, topic: &str, msg: &[u8]) { SwapMsg::TakerFee(taker_fee) => msg_store.taker_fee = Some(taker_fee), SwapMsg::MakerPayment(maker_payment) => msg_store.maker_payment = Some(maker_payment), SwapMsg::TakerPayment(taker_payment) => msg_store.taker_payment = Some(taker_payment), + SwapMsg::Transaction(transaction) => msg_store.transaction = Some(transaction), } } else { warn!("Received message from unexpected sender for swap {}", uuid); @@ -235,6 +240,16 @@ pub async fn process_msg(ctx: MmArc, topic: &str, msg: &[u8]) { pub fn swap_topic(uuid: &Uuid) -> String { pub_sub_topic(SWAP_PREFIX, &uuid.to_string()) } +/// Formats and returns a topic format for `txhlp`. +/// +/// # Usage +/// ```ignore +/// let topic = tx_helper_topic("BTC"); +/// // Returns topic format `txhlp/BTC` as String type. +/// ``` +#[inline(always)] +pub fn tx_helper_topic(coin: &str) -> String { pub_sub_topic(TX_HELPER_PREFIX, coin) } + async fn recv_swap_msg( ctx: MmArc, mut getter: impl FnMut(&mut SwapMsgStore) -> Option, diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index 72b9f8769e..2bdceaddd9 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -11,6 +11,7 @@ use super::{broadcast_my_swap_status, broadcast_swap_message_every, check_other_ use crate::mm2::lp_dispatcher::{DispatcherContext, LpEvents}; use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{MakerOrderBuilder, OrderConfirmationsSettings}; +use crate::mm2::lp_swap::{broadcast_swap_message, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use bitcrypto::dhash160; @@ -853,6 +854,13 @@ impl MakerSwap { }, }; + broadcast_swap_message( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + SwapMsg::Transaction(transaction.tx_hex()), + &self.p2p_privkey, + ); + let tx_hash = transaction.tx_hash(); log!({ "Taker payment spend tx {:02x}", tx_hash }); let tx_ident = TransactionIdentifier { @@ -925,6 +933,14 @@ impl MakerSwap { ])) }, }; + + broadcast_swap_message( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + SwapMsg::Transaction(transaction.tx_hex()), + &self.p2p_privkey, + ); + let tx_hash = transaction.tx_hash(); log!({ "Maker payment refund tx {:02x}", tx_hash }); let tx_ident = TransactionIdentifier { diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index 57aa0e5b38..749395054e 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -10,6 +10,7 @@ use super::{broadcast_my_swap_status, broadcast_swap_message_every, check_other_ SwapConfirmationsSettings, SwapError, SwapMsg, SwapsContext, TransactionIdentifier, WAIT_CONFIRM_INTERVAL}; use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{MatchBy, OrderConfirmationsSettings, TakerAction, TakerOrderBuilder}; +use crate::mm2::lp_swap::{broadcast_swap_message, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use coins::{lp_coinfind, CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, @@ -1287,6 +1288,13 @@ impl TakerSwap { }, }; + broadcast_swap_message( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + SwapMsg::Transaction(transaction.tx_hex()), + &self.p2p_privkey, + ); + let tx_hash = transaction.tx_hash(); log!({"Maker payment spend tx {:02x}", tx_hash }); let tx_ident = TransactionIdentifier { @@ -1330,6 +1338,13 @@ impl TakerSwap { }, }; + broadcast_swap_message( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + SwapMsg::Transaction(transaction.tx_hex()), + &self.p2p_privkey, + ); + let tx_hash = transaction.tx_hash(); log!({"Taker refund tx hash {:02x}", tx_hash }); let tx_ident = TransactionIdentifier { From 860163caf788347d4bf15767338c01e3bbe5d42f Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Tue, 5 Apr 2022 15:37:26 +0300 Subject: [PATCH 02/48] propogate the message if coin inside of the topic is activated Signed-off-by: ozkanonur --- mm2src/lp_network.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mm2src/lp_network.rs b/mm2src/lp_network.rs index 9bc098210e..cce17cb082 100644 --- a/mm2src/lp_network.rs +++ b/mm2src/lp_network.rs @@ -1,3 +1,4 @@ +use coins::lp_coinfind; /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -137,6 +138,13 @@ async fn process_p2p_message( lp_swap::process_msg(ctx.clone(), split.next().unwrap_or_default(), &message.data).await; to_propagate = true; }, + Some(lp_swap::TX_HELPER_PREFIX) => { + if let Some(pair) = split.next() { + if lp_coinfind(&ctx, pair).await.is_ok() { + to_propagate = true; + } + } + }, None | Some(_) => (), } } @@ -149,6 +157,7 @@ async fn process_p2p_message( &message.data, i_am_relay, ); + if process_fut.await { to_propagate = true; } From 43862b64f6e60f1c906e30d957650412904e6bae Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Tue, 5 Apr 2022 19:02:23 +0300 Subject: [PATCH 03/48] impl `send_raw_tx_bytes` for `MarketCoinOps` Signed-off-by: ozkanonur --- mm2src/coins/eth.rs | 14 ++++++++++++++ mm2src/coins/lightning.rs | 9 +++++++++ mm2src/coins/lp_coins.rs | 2 ++ mm2src/coins/qrc20.rs | 4 ++++ mm2src/coins/solana.rs | 13 +++++++++++++ mm2src/coins/solana/spl.rs | 4 ++++ mm2src/coins/test_coin.rs | 2 ++ mm2src/coins/utxo/bch.rs | 4 ++++ mm2src/coins/utxo/qtum.rs | 4 ++++ mm2src/coins/utxo/slp.rs | 13 +++++++++++++ mm2src/coins/utxo/utxo_common.rs | 9 +++++++++ mm2src/coins/utxo/utxo_standard.rs | 4 ++++ mm2src/coins/z_coin.rs | 4 ++++ 13 files changed, 86 insertions(+) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 3da456e72f..d36c2f0875 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -1119,6 +1119,20 @@ impl MarketCoinOps for EthCoin { ) } + fn send_raw_tx_bytes(&self, mut tx: &[u8]) -> Box + Send> { + if tx.starts_with(b"0x") { + tx = &tx[2..]; + } + + Box::new( + self.web3 + .eth() + .send_raw_transaction(tx.into()) + .map(|res| format!("{:02x}", res)) + .map_err(|e| ERRL!("{}", e)), + ) + } + fn wait_for_confirmations( &self, tx: &[u8], diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index 84853c99d0..ccb28a4f52 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -398,6 +398,15 @@ impl MarketCoinOps for LightningCoin { )) } + fn send_raw_tx_bytes(&self, _tx: &[u8]) -> Box + Send> { + Box::new(futures01::future::err( + MmError::new( + "send_raw_tx is not supported for lightning, please use send_payment method instead.".to_string(), + ) + .to_string(), + )) + } + // Todo: Implement this when implementing swaps for lightning as it's is used mainly for swaps fn wait_for_confirmations( &self, diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 40527a7b25..39e89623b3 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -422,6 +422,8 @@ pub trait MarketCoinOps { /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format fn send_raw_tx(&self, tx: &str) -> Box + Send>; + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send>; + fn wait_for_confirmations( &self, tx: &[u8], diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index cd2fd6d670..38ddb7899e 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -1057,6 +1057,10 @@ impl MarketCoinOps for Qrc20Coin { utxo_common::send_raw_tx(&self.utxo, tx) } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + utxo_common::send_raw_tx_bytes(&self.utxo, tx) + } + fn wait_for_confirmations( &self, tx: &[u8], diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index 4185e68edd..32d73c88c8 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -373,6 +373,19 @@ impl MarketCoinOps for SolanaCoin { Box::new(fut.boxed().compat()) } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + let coin = self.clone(); + let tx = tx.to_owned(); + let fut = async move { + let tx: Transaction = deserialize(tx.as_slice()) + .map_to_mm(|e| e) + .map_err(|e| format!("{:?}", e))?; + let signature = coin.rpc().send_transaction(&tx).await.map_err(|e| format!("{:?}", e))?; + Ok(signature.to_string()) + }; + Box::new(fut.boxed().compat()) + } + fn wait_for_confirmations( &self, _tx: &[u8], diff --git a/mm2src/coins/solana/spl.rs b/mm2src/coins/solana/spl.rs index c7b4cb0d27..cb10aedd61 100644 --- a/mm2src/coins/solana/spl.rs +++ b/mm2src/coins/solana/spl.rs @@ -222,6 +222,10 @@ impl MarketCoinOps for SplToken { self.platform_coin.send_raw_tx(tx) } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + self.platform_coin.send_raw_tx_bytes(tx) + } + fn wait_for_confirmations( &self, _tx: &[u8], diff --git a/mm2src/coins/test_coin.rs b/mm2src/coins/test_coin.rs index 2e929e599a..f3b6636ca2 100644 --- a/mm2src/coins/test_coin.rs +++ b/mm2src/coins/test_coin.rs @@ -44,6 +44,8 @@ impl MarketCoinOps for TestCoin { /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format fn send_raw_tx(&self, tx: &str) -> Box + Send> { unimplemented!() } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { unimplemented!() } + fn wait_for_confirmations( &self, tx: &[u8], diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index c8735e0147..70c8b5977b 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -1057,6 +1057,10 @@ impl MarketCoinOps for BchCoin { utxo_common::send_raw_tx(&self.utxo_arc, tx) } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + utxo_common::send_raw_tx_bytes(&self.utxo_arc, tx) + } + fn wait_for_confirmations( &self, tx: &[u8], diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index e5253dbbd2..02474dab2b 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -677,6 +677,10 @@ impl MarketCoinOps for QtumCoin { utxo_common::send_raw_tx(&self.utxo_arc, tx) } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + utxo_common::send_raw_tx_bytes(&self.utxo_arc, tx) + } + fn wait_for_confirmations( &self, tx: &[u8], diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 983204f345..46ca4333ee 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -1096,6 +1096,19 @@ impl MarketCoinOps for SlpToken { Box::new(fut.boxed().compat()) } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + let coin = self.clone(); + let tx = tx.to_owned(); + let fut = async move { + let tx = deserialize(tx.as_slice()) + .map_to_mm(|e| e) + .map_err(|e| format!("{:?}", e))?; + let hash = coin.broadcast_tx(&tx).await.map_err(|e| format!("{:?}", e))?; + Ok(format!("{:?}", hash)) + }; + Box::new(fut.boxed().compat()) + } + fn wait_for_confirmations( &self, tx: &[u8], diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index d07c699a97..f4e6d65a5f 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1706,6 +1706,15 @@ pub fn send_raw_tx(coin: &UtxoCoinFields, tx: &str) -> Box Box + Send> { + Box::new( + coin.rpc_client + .send_raw_transaction(tx.into()) + .map_err(|e| ERRL!("{}", e)) + .map(|hash| format!("{:?}", hash)), + ) +} + pub fn wait_for_confirmations( coin: &UtxoCoinFields, tx: &[u8], diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 28b5c21d2e..ddb84d124e 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -453,6 +453,10 @@ impl MarketCoinOps for UtxoStandardCoin { utxo_common::send_raw_tx(&self.utxo_arc, tx) } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + utxo_common::send_raw_tx_bytes(&self.utxo_arc, tx) + } + fn wait_for_confirmations( &self, tx: &[u8], diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index f6a8c1a53e..13aef032ea 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -733,6 +733,10 @@ impl MarketCoinOps for ZCoin { utxo_common::send_raw_tx(self.as_ref(), tx) } + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + utxo_common::send_raw_tx_bytes(self.as_ref(), tx) + } + fn wait_for_confirmations( &self, tx: &[u8], From b02ce08a52028d1cfa30ae25aa77711e66acfd33 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Tue, 5 Apr 2022 19:10:09 +0300 Subject: [PATCH 04/48] update transaction broadcasting Signed-off-by: ozkanonur --- mm2src/lp_network.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mm2src/lp_network.rs b/mm2src/lp_network.rs index cce17cb082..554367fa8f 100644 --- a/mm2src/lp_network.rs +++ b/mm2src/lp_network.rs @@ -18,7 +18,7 @@ use coins::lp_coinfind; // marketmaker // use common::executor::spawn; -use common::log; +use common::{log, Future01CompatExt}; use common::mm_ctx::{MmArc, MmWeak}; use common::mm_error::prelude::*; use common::mm_metrics::{ClockOps, MetricsOps}; @@ -140,8 +140,11 @@ async fn process_p2p_message( }, Some(lp_swap::TX_HELPER_PREFIX) => { if let Some(pair) = split.next() { - if lp_coinfind(&ctx, pair).await.is_ok() { - to_propagate = true; + if let Ok(Some(coin)) = lp_coinfind(&ctx, pair).await { + match coin.send_raw_tx_bytes(&message.data).compat().await { + Ok(id) => log::info!("Transaction broadcasted successfully: {:?} ", id), + Err(_) => todo!(), + } } } }, From f3747f7abb3656f06044ec503419df5a063244b8 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Tue, 5 Apr 2022 19:34:24 +0300 Subject: [PATCH 05/48] create and use dedicated func for sending transaction messages Signed-off-by: ozkanonur --- mm2src/lp_swap.rs | 12 ++++++++++-- mm2src/lp_swap/maker_swap.rs | 10 +++++----- mm2src/lp_swap/taker_swap.rs | 10 +++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/mm2src/lp_swap.rs b/mm2src/lp_swap.rs index 3ddac913ac..472a1b95ff 100644 --- a/mm2src/lp_swap.rs +++ b/mm2src/lp_swap.rs @@ -131,7 +131,6 @@ pub enum SwapMsg { TakerFee(Vec), MakerPayment(Vec), TakerPayment(Vec), - Transaction(Vec), } #[derive(Debug, Default)] @@ -192,6 +191,16 @@ pub fn broadcast_swap_message(ctx: &MmArc, topic: String, msg: SwapMsg, p2p_priv broadcast_p2p_msg(ctx, vec![topic], encoded_msg); } +pub fn broadcast_transaction_message(ctx: &MmArc, topic: String, msg: Vec, p2p_privkey: &Option) { + let p2p_private = match p2p_privkey { + Some(privkey) => privkey.0, + None => ctx.secp256k1_key_pair.or(&&|| panic!()).private().secret.take(), + }; + + let encoded_msg = encode_and_sign(&msg, &p2p_private).unwrap(); + broadcast_p2p_msg(ctx, vec![topic], encoded_msg); +} + pub async fn process_msg(ctx: MmArc, topic: &str, msg: &[u8]) { let uuid = match Uuid::from_str(topic) { Ok(u) => u, @@ -230,7 +239,6 @@ pub async fn process_msg(ctx: MmArc, topic: &str, msg: &[u8]) { SwapMsg::TakerFee(taker_fee) => msg_store.taker_fee = Some(taker_fee), SwapMsg::MakerPayment(maker_payment) => msg_store.maker_payment = Some(maker_payment), SwapMsg::TakerPayment(taker_payment) => msg_store.taker_payment = Some(taker_payment), - SwapMsg::Transaction(transaction) => msg_store.transaction = Some(transaction), } } else { warn!("Received message from unexpected sender for swap {}", uuid); diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index 2bdceaddd9..19adb9c5e7 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -11,7 +11,7 @@ use super::{broadcast_my_swap_status, broadcast_swap_message_every, check_other_ use crate::mm2::lp_dispatcher::{DispatcherContext, LpEvents}; use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{MakerOrderBuilder, OrderConfirmationsSettings}; -use crate::mm2::lp_swap::{broadcast_swap_message, tx_helper_topic}; +use crate::mm2::lp_swap::{tx_helper_topic, broadcast_transaction_message}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use bitcrypto::dhash160; @@ -854,10 +854,10 @@ impl MakerSwap { }, }; - broadcast_swap_message( + broadcast_transaction_message( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - SwapMsg::Transaction(transaction.tx_hex()), + transaction.tx_hex(), &self.p2p_privkey, ); @@ -934,10 +934,10 @@ impl MakerSwap { }, }; - broadcast_swap_message( + broadcast_transaction_message( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - SwapMsg::Transaction(transaction.tx_hex()), + transaction.tx_hex(), &self.p2p_privkey, ); diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index 749395054e..3f650a0cf2 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -10,7 +10,7 @@ use super::{broadcast_my_swap_status, broadcast_swap_message_every, check_other_ SwapConfirmationsSettings, SwapError, SwapMsg, SwapsContext, TransactionIdentifier, WAIT_CONFIRM_INTERVAL}; use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{MatchBy, OrderConfirmationsSettings, TakerAction, TakerOrderBuilder}; -use crate::mm2::lp_swap::{broadcast_swap_message, tx_helper_topic}; +use crate::mm2::lp_swap::{broadcast_transaction_message, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use coins::{lp_coinfind, CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, @@ -1288,10 +1288,10 @@ impl TakerSwap { }, }; - broadcast_swap_message( + broadcast_transaction_message( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - SwapMsg::Transaction(transaction.tx_hex()), + transaction.tx_hex(), &self.p2p_privkey, ); @@ -1338,10 +1338,10 @@ impl TakerSwap { }, }; - broadcast_swap_message( + broadcast_transaction_message( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - SwapMsg::Transaction(transaction.tx_hex()), + transaction.tx_hex(), &self.p2p_privkey, ); From 7acdd35c5a4180eaa8ef25d4721ae52a88855678 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Tue, 5 Apr 2022 19:35:36 +0300 Subject: [PATCH 06/48] remove unused field from `SwapMsgStore` Signed-off-by: ozkanonur --- mm2src/lp_swap.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/mm2src/lp_swap.rs b/mm2src/lp_swap.rs index 472a1b95ff..6469e0c885 100644 --- a/mm2src/lp_swap.rs +++ b/mm2src/lp_swap.rs @@ -141,7 +141,6 @@ pub struct SwapMsgStore { taker_fee: Option>, maker_payment: Option>, taker_payment: Option>, - transaction: Option>, accept_only_from: bits256, } From 06ecd566c202981c1a991cc741f082cbcc27eeb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Wed, 6 Apr 2022 10:00:21 +0300 Subject: [PATCH 07/48] fix linting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/lp_network.rs | 2 +- mm2src/lp_swap/maker_swap.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/lp_network.rs b/mm2src/lp_network.rs index 554367fa8f..02ea4b02ed 100644 --- a/mm2src/lp_network.rs +++ b/mm2src/lp_network.rs @@ -18,10 +18,10 @@ use coins::lp_coinfind; // marketmaker // use common::executor::spawn; -use common::{log, Future01CompatExt}; use common::mm_ctx::{MmArc, MmWeak}; use common::mm_error::prelude::*; use common::mm_metrics::{ClockOps, MetricsOps}; +use common::{log, Future01CompatExt}; use derive_more::Display; use futures::{channel::oneshot, StreamExt}; use mm2_libp2p::atomicdex_behaviour::{AdexBehaviourCmd, AdexBehaviourEvent, AdexCmdTx, AdexEventRx, AdexResponse, diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index 19adb9c5e7..107c3f3a98 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -11,7 +11,7 @@ use super::{broadcast_my_swap_status, broadcast_swap_message_every, check_other_ use crate::mm2::lp_dispatcher::{DispatcherContext, LpEvents}; use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{MakerOrderBuilder, OrderConfirmationsSettings}; -use crate::mm2::lp_swap::{tx_helper_topic, broadcast_transaction_message}; +use crate::mm2::lp_swap::{broadcast_transaction_message, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use bitcrypto::dhash160; From 5a73d5df7333616ec42bd192b42a2103292315a4 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 6 Apr 2022 10:36:52 +0300 Subject: [PATCH 08/48] log the error on transaction broadcasting Signed-off-by: ozkanonur --- mm2src/lp_network.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/lp_network.rs b/mm2src/lp_network.rs index 02ea4b02ed..40d77df6ce 100644 --- a/mm2src/lp_network.rs +++ b/mm2src/lp_network.rs @@ -143,7 +143,7 @@ async fn process_p2p_message( if let Ok(Some(coin)) = lp_coinfind(&ctx, pair).await { match coin.send_raw_tx_bytes(&message.data).compat().await { Ok(id) => log::info!("Transaction broadcasted successfully: {:?} ", id), - Err(_) => todo!(), + Err(e) => log::error!("Broadcast transaction failed. {}", e), } } } From 9a4c4965fb99753565e3bc3dd1c7a479f6da0bdf Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 6 Apr 2022 12:17:12 +0300 Subject: [PATCH 09/48] fix `send_raw_tx_bytes` of solana Signed-off-by: ozkanonur --- mm2src/coins/solana.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index 32d73c88c8..a56cc54219 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -377,7 +377,8 @@ impl MarketCoinOps for SolanaCoin { let coin = self.clone(); let tx = tx.to_owned(); let fut = async move { - let tx: Transaction = deserialize(tx.as_slice()) + let bytes = hex::decode(tx).map_to_mm(|e| e).map_err(|e| format!("{:?}", e))?; + let tx: Transaction = deserialize(bytes.as_slice()) .map_to_mm(|e| e) .map_err(|e| format!("{:?}", e))?; let signature = coin.rpc().send_transaction(&tx).await.map_err(|e| format!("{:?}", e))?; From 4a5d9c511092fd958686d4f0c1c782e75bc4543f Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 6 Apr 2022 13:27:04 +0300 Subject: [PATCH 10/48] fix `send_raw_tx_bytes` Signed-off-by: ozkanonur --- mm2src/coins/eth.rs | 9 +++------ mm2src/coins/qrc20.rs | 2 +- mm2src/coins/solana.rs | 3 +-- mm2src/coins/solana/solana_tests.rs | 6 ++++++ mm2src/coins/solana/spl_tests.rs | 9 +++++++++ mm2src/coins/utxo/bch.rs | 2 +- mm2src/coins/utxo/qtum.rs | 2 +- mm2src/coins/utxo/slp.rs | 23 ++--------------------- mm2src/coins/utxo/utxo_common.rs | 11 +---------- mm2src/coins/utxo/utxo_standard.rs | 2 +- mm2src/coins/z_coin.rs | 2 +- 11 files changed, 27 insertions(+), 44 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index d36c2f0875..f8a3ecc1b4 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -1119,15 +1119,12 @@ impl MarketCoinOps for EthCoin { ) } - fn send_raw_tx_bytes(&self, mut tx: &[u8]) -> Box + Send> { - if tx.starts_with(b"0x") { - tx = &tx[2..]; - } - + fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { + let bytes = try_fus!(hex::decode(tx)); Box::new( self.web3 .eth() - .send_raw_transaction(tx.into()) + .send_raw_transaction(bytes.into()) .map(|res| format!("{:02x}", res)) .map_err(|e| ERRL!("{}", e)), ) diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 38ddb7899e..db0320bdae 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -1058,7 +1058,7 @@ impl MarketCoinOps for Qrc20Coin { } fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx_bytes(&self.utxo, tx) + utxo_common::send_raw_tx(&self.utxo, tx) } fn wait_for_confirmations( diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index a56cc54219..32d73c88c8 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -377,8 +377,7 @@ impl MarketCoinOps for SolanaCoin { let coin = self.clone(); let tx = tx.to_owned(); let fut = async move { - let bytes = hex::decode(tx).map_to_mm(|e| e).map_err(|e| format!("{:?}", e))?; - let tx: Transaction = deserialize(bytes.as_slice()) + let tx: Transaction = deserialize(tx.as_slice()) .map_to_mm(|e| e) .map_err(|e| format!("{:?}", e))?; let signature = coin.rpc().send_transaction(&tx).await.map_err(|e| format!("{:?}", e))?; diff --git a/mm2src/coins/solana/solana_tests.rs b/mm2src/coins/solana/solana_tests.rs index a92e37338e..c5704315da 100644 --- a/mm2src/coins/solana/solana_tests.rs +++ b/mm2src/coins/solana/solana_tests.rs @@ -257,9 +257,15 @@ mod tests { .await .unwrap(); println!("{:?}", valid_tx_details); + let tx_str = str::from_utf8(&*valid_tx_details.tx_hex.0).unwrap(); let res = sol_coin.send_raw_tx(tx_str).compat().await; assert_eq!(res.is_err(), false); + + let res2 = sol_coin.send_raw_tx_bytes(&*valid_tx_details.tx_hex).compat().await; + assert_eq!(res2.is_err(), false); + assert_eq!(res, res2); + //println!("{:?}", res); } diff --git a/mm2src/coins/solana/spl_tests.rs b/mm2src/coins/solana/spl_tests.rs index 0e9c5d7329..c86d808bdb 100644 --- a/mm2src/coins/solana/spl_tests.rs +++ b/mm2src/coins/solana/spl_tests.rs @@ -82,9 +82,18 @@ mod tests { assert_eq!(valid_tx_details.my_balance_change, withdraw_amount.neg()); assert_eq!(valid_tx_details.coin, "USDC".to_string()); assert_ne!(valid_tx_details.timestamp, 0); + let tx_str = from_utf8(&*valid_tx_details.tx_hex.0).unwrap(); let res = usdc_sol_coin.send_raw_tx(tx_str).compat().await; assert_eq!(res.is_err(), false); println!("{:?}", res); + + let res2 = usdc_sol_coin + .send_raw_tx_bytes(&valid_tx_details.tx_hex.0) + .compat() + .await; + assert_eq!(res2.is_err(), false); + + assert_eq!(res, res2); } } diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index 70c8b5977b..8bc2d882e4 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -1058,7 +1058,7 @@ impl MarketCoinOps for BchCoin { } fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx_bytes(&self.utxo_arc, tx) + utxo_common::send_raw_tx(&self.utxo_arc, tx) } fn wait_for_confirmations( diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index 02474dab2b..786b38ae5d 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -678,7 +678,7 @@ impl MarketCoinOps for QtumCoin { } fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx_bytes(&self.utxo_arc, tx) + utxo_common::send_raw_tx(&self.utxo_arc, tx) } fn wait_for_confirmations( diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 46ca4333ee..b483b6017c 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -1083,30 +1083,11 @@ impl MarketCoinOps for SlpToken { /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format fn send_raw_tx(&self, tx: &str) -> Box + Send> { - let coin = self.clone(); - let tx = tx.to_owned(); - let fut = async move { - let bytes = hex::decode(tx).map_to_mm(|e| e).map_err(|e| format!("{:?}", e))?; - let tx = deserialize(bytes.as_slice()) - .map_to_mm(|e| e) - .map_err(|e| format!("{:?}", e))?; - let hash = coin.broadcast_tx(&tx).await.map_err(|e| format!("{:?}", e))?; - Ok(format!("{:?}", hash)) - }; - Box::new(fut.boxed().compat()) + utxo_common::send_raw_tx(self.as_ref(), tx) } fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - let coin = self.clone(); - let tx = tx.to_owned(); - let fut = async move { - let tx = deserialize(tx.as_slice()) - .map_to_mm(|e| e) - .map_err(|e| format!("{:?}", e))?; - let hash = coin.broadcast_tx(&tx).await.map_err(|e| format!("{:?}", e))?; - Ok(format!("{:?}", hash)) - }; - Box::new(fut.boxed().compat()) + utxo_common::send_raw_tx(self.as_ref(), tx) } fn wait_for_confirmations( diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index f4e6d65a5f..77885dfc42 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1696,7 +1696,7 @@ where Box::new(fut.boxed().compat()) } -pub fn send_raw_tx(coin: &UtxoCoinFields, tx: &str) -> Box + Send> { +pub fn send_raw_tx>(coin: &UtxoCoinFields, tx: T) -> Box + Send> { let bytes = try_fus!(hex::decode(tx)); Box::new( coin.rpc_client @@ -1706,15 +1706,6 @@ pub fn send_raw_tx(coin: &UtxoCoinFields, tx: &str) -> Box Box + Send> { - Box::new( - coin.rpc_client - .send_raw_transaction(tx.into()) - .map_err(|e| ERRL!("{}", e)) - .map(|hash| format!("{:?}", hash)), - ) -} - pub fn wait_for_confirmations( coin: &UtxoCoinFields, tx: &[u8], diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index ddb84d124e..c441e3e5dc 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -454,7 +454,7 @@ impl MarketCoinOps for UtxoStandardCoin { } fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx_bytes(&self.utxo_arc, tx) + utxo_common::send_raw_tx(&self.utxo_arc, tx) } fn wait_for_confirmations( diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index 13aef032ea..fae6bf784d 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -734,7 +734,7 @@ impl MarketCoinOps for ZCoin { } fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx_bytes(self.as_ref(), tx) + utxo_common::send_raw_tx(self.as_ref(), tx) } fn wait_for_confirmations( From a9f2e6bd545ac9b3430fde88566220e10c863320 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 6 Apr 2022 13:27:27 +0300 Subject: [PATCH 11/48] move use statement Signed-off-by: ozkanonur --- mm2src/lp_network.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/lp_network.rs b/mm2src/lp_network.rs index 40d77df6ce..40b744e16b 100644 --- a/mm2src/lp_network.rs +++ b/mm2src/lp_network.rs @@ -1,4 +1,3 @@ -use coins::lp_coinfind; /****************************************************************************** * Copyright © 2014-2019 The SuperNET Developers. * * * @@ -17,6 +16,7 @@ use coins::lp_coinfind; // lp_network.rs // marketmaker // +use coins::lp_coinfind; use common::executor::spawn; use common::mm_ctx::{MmArc, MmWeak}; use common::mm_error::prelude::*; From 840d0222156c11228e636a5cb3d488fe93fc7b5b Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 6 Apr 2022 13:36:40 +0300 Subject: [PATCH 12/48] save development state Signed-off-by: ozkanonur --- mm2src/coins/solana.rs | 3 ++- mm2src/coins/solana/spl_tests.rs | 3 +-- mm2src/coins/utxo/utxo_common.rs | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index 32d73c88c8..a56cc54219 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -377,7 +377,8 @@ impl MarketCoinOps for SolanaCoin { let coin = self.clone(); let tx = tx.to_owned(); let fut = async move { - let tx: Transaction = deserialize(tx.as_slice()) + let bytes = hex::decode(tx).map_to_mm(|e| e).map_err(|e| format!("{:?}", e))?; + let tx: Transaction = deserialize(bytes.as_slice()) .map_to_mm(|e| e) .map_err(|e| format!("{:?}", e))?; let signature = coin.rpc().send_transaction(&tx).await.map_err(|e| format!("{:?}", e))?; diff --git a/mm2src/coins/solana/spl_tests.rs b/mm2src/coins/solana/spl_tests.rs index c86d808bdb..8fa9a90b71 100644 --- a/mm2src/coins/solana/spl_tests.rs +++ b/mm2src/coins/solana/spl_tests.rs @@ -89,11 +89,10 @@ mod tests { println!("{:?}", res); let res2 = usdc_sol_coin - .send_raw_tx_bytes(&valid_tx_details.tx_hex.0) + .send_raw_tx_bytes(&*valid_tx_details.tx_hex.0) .compat() .await; assert_eq!(res2.is_err(), false); - assert_eq!(res, res2); } } diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 77885dfc42..a3827ac79b 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1696,7 +1696,10 @@ where Box::new(fut.boxed().compat()) } -pub fn send_raw_tx>(coin: &UtxoCoinFields, tx: T) -> Box + Send> { +pub fn send_raw_tx>( + coin: &UtxoCoinFields, + tx: T, +) -> Box + Send> { let bytes = try_fus!(hex::decode(tx)); Box::new( coin.rpc_client From 658ff564021438e99a8ec3a6cfc69606b4c80b49 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 6 Apr 2022 14:49:21 +0300 Subject: [PATCH 13/48] send transactions as p2p message Signed-off-by: ozkanonur --- mm2src/lp_swap/maker_swap.rs | 22 ++++++++++++++++++++++ mm2src/lp_swap/taker_swap.rs | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index 107c3f3a98..ea54d01919 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -681,6 +681,13 @@ impl MakerSwap { }, }; + broadcast_transaction_message( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + transaction.tx_hex(), + &self.p2p_privkey, + ); + let tx_hash = transaction.tx_hash(); log!({ "Maker payment tx {:02x}", tx_hash }); @@ -1159,6 +1166,14 @@ impl MakerSwap { Ok(Some(FoundSwapTxSpend::Spent(_))) => { log!("Warning: MakerPayment spent, but TakerPayment is not yet. Trying to spend TakerPayment"); let transaction = try_s!(try_spend_taker_payment(self, &secret_hash.0).await); + + broadcast_transaction_message( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + transaction.tx_hex(), + &self.p2p_privkey, + ); + Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: self.taker_coin.ticker().to_string(), @@ -1194,6 +1209,13 @@ impl MakerSwap { .await ); + broadcast_transaction_message( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + transaction.tx_hex(), + &self.p2p_privkey, + ); + Ok(RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, coin: self.maker_coin.ticker().to_string(), diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index 3f650a0cf2..fd80ec2b01 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -1031,6 +1031,13 @@ impl TakerSwap { }, }; + broadcast_transaction_message( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + transaction.tx_hex(), + &self.p2p_privkey, + ); + let tx_hash = transaction.tx_hash(); log!({"Taker fee tx hash {:02x}", tx_hash}); let tx_ident = TransactionIdentifier { @@ -1185,6 +1192,13 @@ impl TakerSwap { }, }; + broadcast_transaction_message( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + transaction.tx_hex(), + &self.p2p_privkey, + ); + let tx_hash = transaction.tx_hash(); log!({"Taker payment tx hash {:02x}", tx_hash }); let tx_ident = TransactionIdentifier { @@ -1546,6 +1560,13 @@ impl TakerSwap { .await ); + broadcast_transaction_message( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + transaction.tx_hex(), + &self.p2p_privkey, + ); + return Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: self.maker_coin.ticker().to_string(), @@ -1585,6 +1606,13 @@ impl TakerSwap { .await ); + broadcast_transaction_message( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + transaction.tx_hex(), + &self.p2p_privkey, + ); + Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: self.maker_coin.ticker().to_string(), @@ -1618,6 +1646,13 @@ impl TakerSwap { .await ); + broadcast_transaction_message( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + transaction.tx_hex(), + &self.p2p_privkey, + ); + Ok(RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, coin: self.maker_coin.ticker().to_string(), From f8ed4ccfa930c9690f651a7aebe8c3f58bde7477 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Thu, 7 Apr 2022 11:35:43 +0300 Subject: [PATCH 14/48] update exptected error result in test fn `construct_and_send_invalid_slp_htlc_should_fail` Signed-off-by: ozkanonur --- mm2src/coins/utxo/slp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index b483b6017c..af8b2990f8 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -2016,7 +2016,7 @@ mod slp_tests { let err = fusd.send_raw_tx(&tx_bytes_str).wait().unwrap_err(); println!("{:?}", err); - assert!(err.contains("is not valid with reason outputs greater than inputs")); + assert!(err.contains("the transaction was rejected by network rules.\\n\\ntransaction already in block chain")); let utxo_tx: UtxoTx = deserialize(tx_bytes).unwrap(); let err = block_on(fusd.broadcast_tx(&utxo_tx)).unwrap_err(); From fedbc32d4e92465ca020ff4df91bb1c92ef7d8f6 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Thu, 7 Apr 2022 11:43:11 +0300 Subject: [PATCH 15/48] [opt] inline wrapper functions Signed-off-by: ozkanonur --- mm2src/coins/qrc20.rs | 2 ++ mm2src/coins/solana/spl.rs | 2 ++ mm2src/coins/utxo/bch.rs | 2 ++ mm2src/coins/utxo/qtum.rs | 2 ++ mm2src/coins/utxo/slp.rs | 2 ++ mm2src/coins/utxo/utxo_standard.rs | 2 ++ mm2src/coins/z_coin.rs | 2 ++ 7 files changed, 14 insertions(+) diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index db0320bdae..7518834789 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -1053,10 +1053,12 @@ impl MarketCoinOps for Qrc20Coin { fn platform_ticker(&self) -> &str { &self.0.platform } + #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { utxo_common::send_raw_tx(&self.utxo, tx) } + #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { utxo_common::send_raw_tx(&self.utxo, tx) } diff --git a/mm2src/coins/solana/spl.rs b/mm2src/coins/solana/spl.rs index cb10aedd61..46f7601091 100644 --- a/mm2src/coins/solana/spl.rs +++ b/mm2src/coins/solana/spl.rs @@ -218,10 +218,12 @@ impl MarketCoinOps for SplToken { fn platform_ticker(&self) -> &str { self.platform_coin.ticker() } + #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { self.platform_coin.send_raw_tx(tx) } + #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { self.platform_coin.send_raw_tx_bytes(tx) } diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index 8bc2d882e4..b16e23374b 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -1053,10 +1053,12 @@ impl MarketCoinOps for BchCoin { fn platform_ticker(&self) -> &str { self.ticker() } + #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { utxo_common::send_raw_tx(&self.utxo_arc, tx) } + #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { utxo_common::send_raw_tx(&self.utxo_arc, tx) } diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index 786b38ae5d..d68fd24656 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -673,10 +673,12 @@ impl MarketCoinOps for QtumCoin { fn platform_ticker(&self) -> &str { self.ticker() } + #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { utxo_common::send_raw_tx(&self.utxo_arc, tx) } + #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { utxo_common::send_raw_tx(&self.utxo_arc, tx) } diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index af8b2990f8..466eb8d4b7 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -1081,11 +1081,13 @@ impl MarketCoinOps for SlpToken { fn platform_ticker(&self) -> &str { self.platform_coin.ticker() } + #[inline(always)] /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format fn send_raw_tx(&self, tx: &str) -> Box + Send> { utxo_common::send_raw_tx(self.as_ref(), tx) } + #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { utxo_common::send_raw_tx(self.as_ref(), tx) } diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index c441e3e5dc..7456665808 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -449,10 +449,12 @@ impl MarketCoinOps for UtxoStandardCoin { fn platform_ticker(&self) -> &str { self.ticker() } + #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { utxo_common::send_raw_tx(&self.utxo_arc, tx) } + #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { utxo_common::send_raw_tx(&self.utxo_arc, tx) } diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index fae6bf784d..5d2448a02b 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -729,10 +729,12 @@ impl MarketCoinOps for ZCoin { fn platform_ticker(&self) -> &str { self.ticker() } + #[inline(always)] fn send_raw_tx(&self, tx: &str) -> Box + Send> { utxo_common::send_raw_tx(self.as_ref(), tx) } + #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { utxo_common::send_raw_tx(self.as_ref(), tx) } From 78d64e3da56e49a7d989332b8fe12b84a3d72278 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Thu, 7 Apr 2022 19:04:18 +0300 Subject: [PATCH 16/48] fix `send_raw_tx` and test `send_raw_tx_bytes` Signed-off-by: ozkanonur --- mm2src/coins/utxo/slp.rs | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 466eb8d4b7..5c007f3eb2 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -1084,12 +1084,32 @@ impl MarketCoinOps for SlpToken { #[inline(always)] /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format fn send_raw_tx(&self, tx: &str) -> Box + Send> { - utxo_common::send_raw_tx(self.as_ref(), tx) + let _self = self.clone(); + let tx = tx.to_owned(); + let fut = async move { + let bytes = hex::decode(tx).map_to_mm(|e| e).map_err(|e| format!("{:?}", e))?; + let tx = deserialize(bytes.as_slice()) + .map_to_mm(|e| e) + .map_err(|e| format!("{:?}", e))?; + let hash = _self.broadcast_tx(&tx).await.map_err(|e| format!("{:?}", e))?; + Ok(format!("{:?}", hash)) + }; + + Box::new(fut.boxed().compat()) } - #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx(self.as_ref(), tx) + let _self = self.clone(); + let bytes = tx.to_owned(); + let fut = async move { + let tx = deserialize(bytes.as_slice()) + .map_to_mm(|e| e) + .map_err(|e| format!("{:?}", e))?; + let hash = _self.broadcast_tx(&tx).await.map_err(|e| format!("{:?}", e))?; + Ok(format!("{:?}", hash)) + }; + + Box::new(fut.boxed().compat()) } fn wait_for_confirmations( @@ -2014,11 +2034,16 @@ mod slp_tests { 142, 135, 205, 228, 173, 0, 0, 0, 0, 0, 25, 118, 169, 20, 140, 255, 252, 36, 9, 208, 99, 67, 125, 106, 168, 183, 90, 0, 155, 155, 165, 27, 113, 252, 136, 172, 216, 36, 92, 97, ]; - let tx_bytes_str = hex::encode(tx_bytes); + let tx_bytes_str = hex::encode(tx_bytes); let err = fusd.send_raw_tx(&tx_bytes_str).wait().unwrap_err(); println!("{:?}", err); - assert!(err.contains("the transaction was rejected by network rules.\\n\\ntransaction already in block chain")); + assert!(err.contains("is not valid with reason outputs greater than inputs")); + + let err2 = fusd.send_raw_tx_bytes(tx_bytes).wait().unwrap_err(); + println!("{:?}", err2); + assert!(err2.contains("is not valid with reason outputs greater than inputs")); + assert_eq!(err, err2); let utxo_tx: UtxoTx = deserialize(tx_bytes).unwrap(); let err = block_on(fusd.broadcast_tx(&utxo_tx)).unwrap_err(); From e9d16a93e7f7f0d6477f8dc1c050b24c9a019329 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Thu, 7 Apr 2022 19:08:24 +0300 Subject: [PATCH 17/48] un-inline `send_raw_tx` Signed-off-by: ozkanonur --- mm2src/coins/utxo/slp.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 5c007f3eb2..c164193b1b 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -1081,7 +1081,6 @@ impl MarketCoinOps for SlpToken { fn platform_ticker(&self) -> &str { self.platform_coin.ticker() } - #[inline(always)] /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format fn send_raw_tx(&self, tx: &str) -> Box + Send> { let _self = self.clone(); From 8545045834b031bdd32b7a2a03e09415c0943eff Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Sun, 10 Apr 2022 16:45:34 +0300 Subject: [PATCH 18/48] Updates after code-review Signed-off-by: ozkanonur --- mm2src/coins/solana/solana_tests.rs | 10 ++++++---- mm2src/coins/solana/spl_tests.rs | 7 +++---- mm2src/coins/utxo/slp.rs | 16 ++++++---------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/mm2src/coins/solana/solana_tests.rs b/mm2src/coins/solana/solana_tests.rs index c5704315da..774846b934 100644 --- a/mm2src/coins/solana/solana_tests.rs +++ b/mm2src/coins/solana/solana_tests.rs @@ -259,11 +259,13 @@ mod tests { println!("{:?}", valid_tx_details); let tx_str = str::from_utf8(&*valid_tx_details.tx_hex.0).unwrap(); - let res = sol_coin.send_raw_tx(tx_str).compat().await; - assert_eq!(res.is_err(), false); + let res = sol_coin.send_raw_tx(tx_str).compat().await.unwrap(); - let res2 = sol_coin.send_raw_tx_bytes(&*valid_tx_details.tx_hex).compat().await; - assert_eq!(res2.is_err(), false); + let res2 = sol_coin + .send_raw_tx_bytes(&*valid_tx_details.tx_hex) + .compat() + .await + .unwrap(); assert_eq!(res, res2); //println!("{:?}", res); diff --git a/mm2src/coins/solana/spl_tests.rs b/mm2src/coins/solana/spl_tests.rs index 8fa9a90b71..79b69200d3 100644 --- a/mm2src/coins/solana/spl_tests.rs +++ b/mm2src/coins/solana/spl_tests.rs @@ -84,15 +84,14 @@ mod tests { assert_ne!(valid_tx_details.timestamp, 0); let tx_str = from_utf8(&*valid_tx_details.tx_hex.0).unwrap(); - let res = usdc_sol_coin.send_raw_tx(tx_str).compat().await; - assert_eq!(res.is_err(), false); + let res = usdc_sol_coin.send_raw_tx(tx_str).compat().await.unwrap(); println!("{:?}", res); let res2 = usdc_sol_coin .send_raw_tx_bytes(&*valid_tx_details.tx_hex.0) .compat() - .await; - assert_eq!(res2.is_err(), false); + .await + .unwrap(); assert_eq!(res, res2); } } diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index c164193b1b..5b7f9d5326 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -1083,14 +1083,12 @@ impl MarketCoinOps for SlpToken { /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format fn send_raw_tx(&self, tx: &str) -> Box + Send> { - let _self = self.clone(); + let selfi = self.clone(); let tx = tx.to_owned(); let fut = async move { let bytes = hex::decode(tx).map_to_mm(|e| e).map_err(|e| format!("{:?}", e))?; - let tx = deserialize(bytes.as_slice()) - .map_to_mm(|e| e) - .map_err(|e| format!("{:?}", e))?; - let hash = _self.broadcast_tx(&tx).await.map_err(|e| format!("{:?}", e))?; + let tx = try_s!(deserialize(bytes.as_slice())); + let hash = selfi.broadcast_tx(&tx).await.map_err(|e| format!("{:?}", e))?; Ok(format!("{:?}", hash)) }; @@ -1098,13 +1096,11 @@ impl MarketCoinOps for SlpToken { } fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - let _self = self.clone(); + let selfi = self.clone(); let bytes = tx.to_owned(); let fut = async move { - let tx = deserialize(bytes.as_slice()) - .map_to_mm(|e| e) - .map_err(|e| format!("{:?}", e))?; - let hash = _self.broadcast_tx(&tx).await.map_err(|e| format!("{:?}", e))?; + let tx = try_s!(deserialize(bytes.as_slice())); + let hash = selfi.broadcast_tx(&tx).await.map_err(|e| format!("{:?}", e))?; Ok(format!("{:?}", hash)) }; From 5c24769605a3ce7ea6c336ffff7aeec351e7705c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Mon, 11 Apr 2022 14:08:32 +0300 Subject: [PATCH 19/48] change log level of tx broadcasting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/lp_network.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/lp_network.rs b/mm2src/lp_network.rs index 40b744e16b..9d2f6a7782 100644 --- a/mm2src/lp_network.rs +++ b/mm2src/lp_network.rs @@ -142,7 +142,7 @@ async fn process_p2p_message( if let Some(pair) = split.next() { if let Ok(Some(coin)) = lp_coinfind(&ctx, pair).await { match coin.send_raw_tx_bytes(&message.data).compat().await { - Ok(id) => log::info!("Transaction broadcasted successfully: {:?} ", id), + Ok(id) => log::debug!("Transaction broadcasted successfully: {:?} ", id), Err(e) => log::error!("Broadcast transaction failed. {}", e), } } From 1c3d7bd3c788cb7d332c85486d5edc283a8a7536 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 13 Apr 2022 11:38:09 +0300 Subject: [PATCH 20/48] save development state Signed-off-by: ozkanonur --- mm2src/lp_swap.rs | 2 +- mm2src/lp_swap/maker_swap.rs | 29 ++++--------------------- mm2src/lp_swap/taker_swap.rs | 41 +++--------------------------------- 3 files changed, 8 insertions(+), 64 deletions(-) diff --git a/mm2src/lp_swap.rs b/mm2src/lp_swap.rs index 6469e0c885..336700ff6f 100644 --- a/mm2src/lp_swap.rs +++ b/mm2src/lp_swap.rs @@ -190,7 +190,7 @@ pub fn broadcast_swap_message(ctx: &MmArc, topic: String, msg: SwapMsg, p2p_priv broadcast_p2p_msg(ctx, vec![topic], encoded_msg); } -pub fn broadcast_transaction_message(ctx: &MmArc, topic: String, msg: Vec, p2p_privkey: &Option) { +pub fn broadcast_p2p_tx_helper(ctx: &MmArc, topic: String, msg: Vec, p2p_privkey: &Option) { let p2p_private = match p2p_privkey { Some(privkey) => privkey.0, None => ctx.secp256k1_key_pair.or(&&|| panic!()).private().secret.take(), diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index ea54d01919..3e68110298 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -11,7 +11,7 @@ use super::{broadcast_my_swap_status, broadcast_swap_message_every, check_other_ use crate::mm2::lp_dispatcher::{DispatcherContext, LpEvents}; use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{MakerOrderBuilder, OrderConfirmationsSettings}; -use crate::mm2::lp_swap::{broadcast_transaction_message, tx_helper_topic}; +use crate::mm2::lp_swap::{broadcast_p2p_tx_helper, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use bitcrypto::dhash160; @@ -681,13 +681,6 @@ impl MakerSwap { }, }; - broadcast_transaction_message( - &self.ctx, - tx_helper_topic(self.maker_coin.ticker()), - transaction.tx_hex(), - &self.p2p_privkey, - ); - let tx_hash = transaction.tx_hash(); log!({ "Maker payment tx {:02x}", tx_hash }); @@ -861,9 +854,9 @@ impl MakerSwap { }, }; - broadcast_transaction_message( + broadcast_p2p_tx_helper( &self.ctx, - tx_helper_topic(self.taker_coin.ticker()), + tx_helper_topic(self.maker_coin.ticker()), transaction.tx_hex(), &self.p2p_privkey, ); @@ -941,7 +934,7 @@ impl MakerSwap { }, }; - broadcast_transaction_message( + broadcast_p2p_tx_helper( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), transaction.tx_hex(), @@ -1167,13 +1160,6 @@ impl MakerSwap { log!("Warning: MakerPayment spent, but TakerPayment is not yet. Trying to spend TakerPayment"); let transaction = try_s!(try_spend_taker_payment(self, &secret_hash.0).await); - broadcast_transaction_message( - &self.ctx, - tx_helper_topic(self.taker_coin.ticker()), - transaction.tx_hex(), - &self.p2p_privkey, - ); - Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: self.taker_coin.ticker().to_string(), @@ -1209,13 +1195,6 @@ impl MakerSwap { .await ); - broadcast_transaction_message( - &self.ctx, - tx_helper_topic(self.maker_coin.ticker()), - transaction.tx_hex(), - &self.p2p_privkey, - ); - Ok(RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, coin: self.maker_coin.ticker().to_string(), diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index fd80ec2b01..b9c04ce165 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -10,7 +10,7 @@ use super::{broadcast_my_swap_status, broadcast_swap_message_every, check_other_ SwapConfirmationsSettings, SwapError, SwapMsg, SwapsContext, TransactionIdentifier, WAIT_CONFIRM_INTERVAL}; use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{MatchBy, OrderConfirmationsSettings, TakerAction, TakerOrderBuilder}; -use crate::mm2::lp_swap::{broadcast_transaction_message, tx_helper_topic}; +use crate::mm2::lp_swap::{broadcast_p2p_tx_helper, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use coins::{lp_coinfind, CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, @@ -1031,13 +1031,6 @@ impl TakerSwap { }, }; - broadcast_transaction_message( - &self.ctx, - tx_helper_topic(self.taker_coin.ticker()), - transaction.tx_hex(), - &self.p2p_privkey, - ); - let tx_hash = transaction.tx_hash(); log!({"Taker fee tx hash {:02x}", tx_hash}); let tx_ident = TransactionIdentifier { @@ -1192,13 +1185,6 @@ impl TakerSwap { }, }; - broadcast_transaction_message( - &self.ctx, - tx_helper_topic(self.taker_coin.ticker()), - transaction.tx_hex(), - &self.p2p_privkey, - ); - let tx_hash = transaction.tx_hash(); log!({"Taker payment tx hash {:02x}", tx_hash }); let tx_ident = TransactionIdentifier { @@ -1302,7 +1288,7 @@ impl TakerSwap { }, }; - broadcast_transaction_message( + broadcast_p2p_tx_helper( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), transaction.tx_hex(), @@ -1352,7 +1338,7 @@ impl TakerSwap { }, }; - broadcast_transaction_message( + broadcast_p2p_tx_helper( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), transaction.tx_hex(), @@ -1560,13 +1546,6 @@ impl TakerSwap { .await ); - broadcast_transaction_message( - &self.ctx, - tx_helper_topic(self.maker_coin.ticker()), - transaction.tx_hex(), - &self.p2p_privkey, - ); - return Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: self.maker_coin.ticker().to_string(), @@ -1606,13 +1585,6 @@ impl TakerSwap { .await ); - broadcast_transaction_message( - &self.ctx, - tx_helper_topic(self.maker_coin.ticker()), - transaction.tx_hex(), - &self.p2p_privkey, - ); - Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, coin: self.maker_coin.ticker().to_string(), @@ -1646,13 +1618,6 @@ impl TakerSwap { .await ); - broadcast_transaction_message( - &self.ctx, - tx_helper_topic(self.taker_coin.ticker()), - transaction.tx_hex(), - &self.p2p_privkey, - ); - Ok(RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, coin: self.maker_coin.ticker().to_string(), From b11fe2c5afcb4d1aa52b334fec7d37a072f3c307 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 13 Apr 2022 14:32:02 +0300 Subject: [PATCH 21/48] implement fail-safe returns for `send_taker_refunds_payment` Signed-off-by: ozkanonur --- mm2src/coins/eth.rs | 11 +++--- mm2src/coins/lightning.rs | 4 +- mm2src/coins/lp_coins.rs | 25 +++++++++++- mm2src/coins/qrc20.rs | 19 ++++----- mm2src/coins/solana.rs | 4 +- mm2src/coins/solana/spl.rs | 4 +- mm2src/coins/test_coin.rs | 4 +- mm2src/coins/utxo/bch.rs | 4 +- mm2src/coins/utxo/qtum.rs | 4 +- mm2src/coins/utxo/slp.rs | 18 ++++----- mm2src/coins/utxo/utxo_common.rs | 44 ++++++++++++++------- mm2src/coins/utxo/utxo_standard.rs | 4 +- mm2src/lp_swap/taker_swap.rs | 62 +++++++++++++++++++++--------- 13 files changed, 138 insertions(+), 69 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index f8a3ecc1b4..e69d3df6cb 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -65,7 +65,7 @@ pub use ethcore_transaction::SignedTransaction as SignedEthTx; pub use rlp; mod web3_transport; -use crate::ValidatePaymentInput; +use crate::{FailSafeTxFut, FailSafeTxErr, ValidatePaymentInput}; use common::mm_number::MmNumber; use common::privkey::key_pair_from_secret; use web3_transport::{EthFeeHistoryNamespace, Web3Transport}; @@ -769,13 +769,14 @@ impl SwapOps for EthCoin { _secret_hash: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fus!(rlp::decode(taker_payment_tx)); - let signed = try_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(taker_payment_tx)); + let signed = try_fs_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) + .map_err(|e| FailSafeTxErr::Error(e)) .map(TransactionEnum::from), ) } diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index ccb28a4f52..ca30e31af1 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -5,7 +5,7 @@ use crate::utxo::{sat_from_big_decimal, BlockchainNetwork, FeePolicy, UtxoCommon use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionEnum, TransactionFut, UtxoStandardCoin, ValidateAddressResult, - ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest}; + ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, FailSafeTxFut}; use async_trait::async_trait; use bigdecimal::BigDecimal; use bitcoin::blockdata::script::Script; @@ -278,7 +278,7 @@ impl SwapOps for LightningCoin { _secret_hash: &[u8], _htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 39e89623b3..fd431670ec 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -88,6 +88,20 @@ macro_rules! try_fus { }; } +macro_rules! try_fs_fus { + ($e: expr) => { + match $e { + Ok(ok) => ok, + Err(err) => { + return Box::new(futures01::future::err(FailSafeTxErr::Error(format!( + "{:?}", + err + )))) + }, + } + }; +} + macro_rules! try_f { ($e: expr) => { match $e { @@ -227,6 +241,15 @@ impl Deref for TransactionEnum { pub type TransactionFut = Box + Send>; +#[derive(Debug, PartialEq)] +pub enum FailSafeTxErr { + /// Tx and Error + RpcCallFailed(TransactionEnum, String), + Error(String), +} + +pub type FailSafeTxFut = Box + Send>; + #[derive(Debug, PartialEq)] pub enum FoundSwapTxSpend { Spent(TransactionEnum), @@ -313,7 +336,7 @@ pub trait SwapOps { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut; + ) -> FailSafeTxFut; fn send_maker_refunds_payment( &self, diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 7518834789..b3b70f5e6f 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -11,11 +11,12 @@ use crate::utxo::{qtum, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy HistoryUtxoTxMap, RecentlySpentOutPoints, UtxoActivationParams, UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps, UtxoFromLegacyReqErr, UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps, VerboseTransactionFrom, UTXO_LOCK}; -use crate::{BalanceError, BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, - MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, SwapOps, TradeFee, TradePreimageError, - TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionEnum, - TransactionFut, TransactionType, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, - WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, WithdrawResult}; +use crate::{BalanceError, BalanceFut, CoinBalance, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, + MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, SwapOps, FailSafeTxErr, + TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, + TransactionDetails, TransactionEnum, TransactionFut, TransactionType, UnexpectedDerivationMethod, + ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, + WithdrawResult}; use async_trait::async_trait; use bigdecimal::BigDecimal; use bitcrypto::{dhash160, sha256}; @@ -821,9 +822,9 @@ impl SwapOps for Qrc20Coin { _secret_hash: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { - let payment_tx: UtxoTx = try_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let payment_tx: UtxoTx = try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -831,7 +832,7 @@ impl SwapOps for Qrc20Coin { .refund_hash_time_locked_payment(swap_contract_address, payment_tx) .await }; - Box::new(fut.boxed().compat()) + Box::new(fut.boxed().compat().map_err(|e| FailSafeTxErr::Error(e))) } fn send_maker_refunds_payment( diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index a56cc54219..5743b3fc06 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -3,7 +3,7 @@ use crate::solana::solana_common::{lamports_to_sol, PrepareTransferData, Suffici use crate::solana::spl::SplTokenInfo; use crate::{BalanceError, BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionType, - ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, WithdrawResult}; + ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, WithdrawResult, FailSafeTxFut}; use async_trait::async_trait; use base58::ToBase58; use bigdecimal::BigDecimal; @@ -484,7 +484,7 @@ impl SwapOps for SolanaCoin { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } diff --git a/mm2src/coins/solana/spl.rs b/mm2src/coins/solana/spl.rs index 46f7601091..dab4bad319 100644 --- a/mm2src/coins/solana/spl.rs +++ b/mm2src/coins/solana/spl.rs @@ -3,7 +3,7 @@ use crate::solana::solana_common::{ui_amount_to_amount, PrepareTransferData, Suf use crate::solana::{solana_common, AccountError, SolanaCommonOps, SolanaFeeDetails}; use crate::{BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, SolanaCoin, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionType, ValidateAddressResult, - ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, WithdrawResult}; + ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, WithdrawResult, FailSafeTxFut}; use async_trait::async_trait; use bigdecimal::BigDecimal; use bincode::serialize; @@ -321,7 +321,7 @@ impl SwapOps for SplToken { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } diff --git a/mm2src/coins/test_coin.rs b/mm2src/coins/test_coin.rs index f3b6636ca2..93d1abe61a 100644 --- a/mm2src/coins/test_coin.rs +++ b/mm2src/coins/test_coin.rs @@ -1,7 +1,7 @@ use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum, TransactionFut}; use crate::{BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, TradePreimageFut, TradePreimageResult, TradePreimageValue, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, - WithdrawRequest}; + WithdrawRequest, FailSafeTxFut}; use async_trait::async_trait; use bigdecimal::BigDecimal; use common::mm_ctx::MmArc; @@ -140,7 +140,7 @@ impl SwapOps for TestCoin { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index b16e23374b..e2d5c95b6a 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -7,7 +7,7 @@ use crate::utxo::utxo_builder::{UtxoArcBuilder, UtxoCoinBuilder}; use crate::utxo::utxo_common::big_decimal_from_sat_unsigned; use crate::{BlockHeightAndTime, CanRefundHtlc, CoinBalance, CoinProtocol, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, SwapOps, TradePreimageValue, TransactionType, TxFeeDetails, ValidateAddressResult, - ValidatePaymentInput, WithdrawFut}; + ValidatePaymentInput, WithdrawFut, FailSafeTxFut}; use common::log::warn; use common::mm_metrics::MetricsArc; use common::mm_number::MmNumber; @@ -905,7 +905,7 @@ impl SwapOps for BchCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_taker_refunds_payment(self.clone(), taker_tx, time_lock, maker_pub, secret_hash, htlc_privkey) } diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index d68fd24656..e1946e8988 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -14,7 +14,7 @@ use crate::utxo::utxo_builder::{MergeUtxoArcOps, UtxoCoinBuildError, UtxoCoinBui UtxoFieldsWithHardwareWalletBuilder, UtxoFieldsWithIguanaPrivKeyBuilder}; use crate::{eth, CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, DelegationError, DelegationFut, GetWithdrawSenderAddress, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, StakingInfosFut, SwapOps, - TradePreimageValue, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawSenderAddress}; + TradePreimageValue, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawSenderAddress, FailSafeTxFut}; use common::mm_metrics::MetricsArc; use common::mm_number::MmNumber; use crypto::trezor::utxo::TrezorUtxoCoin; @@ -537,7 +537,7 @@ impl SwapOps for QtumCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_taker_refunds_payment(self.clone(), taker_tx, time_lock, maker_pub, secret_hash, htlc_privkey) } diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 5b7f9d5326..9fc0f56e68 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -10,11 +10,11 @@ use crate::utxo::utxo_common::{self, big_decimal_from_sat_unsigned, payment_scri use crate::utxo::{generate_and_send_tx, sat_from_big_decimal, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy, GenerateTxError, RecentlySpentOutPoints, UtxoCoinConf, UtxoCoinFields, UtxoCommonOps, UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps}; -use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, - NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, SwapOps, TradeFee, TradePreimageError, - TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionEnum, - TransactionFut, TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, - WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; +use crate::{BalanceFut, CoinBalance, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, + MmCoin, NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, SwapOps, FailSafeTxErr, + TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, + TransactionDetails, TransactionEnum, TransactionFut, TxFeeDetails, UnexpectedDerivationMethod, + ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; use async_trait::async_trait; use bitcrypto::dhash160; @@ -1280,11 +1280,11 @@ impl SwapOps for SlpToken { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { let tx = taker_payment_tx.to_owned(); - let maker_pub = try_fus!(Public::from_slice(maker_pub)); + let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); let secret_hash = secret_hash.to_owned(); - let keypair = try_fus!(key_pair_from_secret(htlc_privkey)); + let keypair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { @@ -1294,7 +1294,7 @@ impl SwapOps for SlpToken { ); Ok(tx.into()) }; - Box::new(fut.boxed().compat()) + Box::new(fut.boxed().compat().map_err(|e| FailSafeTxErr::Error(e))) } fn send_maker_refunds_payment( diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index a3827ac79b..362e37f5ce 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -8,9 +8,9 @@ use crate::init_withdraw::WithdrawTaskHandle; use crate::utxo::rpc_clients::{electrum_script_hash, BlockHashOrHeight, UnspentInfo, UtxoRpcClientEnum, UtxoRpcClientOps, UtxoRpcResult}; use crate::utxo::utxo_withdraw::{InitUtxoWithdraw, StandardUtxoWithdraw, UtxoWithdraw}; -use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, GetWithdrawSenderAddress, HDAddressId, - TradePreimageValue, TxFeeDetails, ValidateAddressResult, ValidatePaymentInput, WithdrawFrom, - WithdrawResult, WithdrawSenderAddress}; +use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, FailSafeTxFut, GetWithdrawSenderAddress, + HDAddressId, FailSafeTxErr, TradePreimageValue, TxFeeDetails, ValidateAddressResult, + ValidatePaymentInput, WithdrawFrom, WithdrawResult, WithdrawSenderAddress}; use bigdecimal::{BigDecimal, Zero}; pub use bitcrypto::{dhash160, sha256, ChecksumType}; use chain::constants::SEQUENCE_FINAL; @@ -1219,31 +1219,36 @@ pub fn send_taker_refunds_payment( maker_pub: &[u8], secret_hash: &[u8], htlc_privkey: &[u8], -) -> TransactionFut +) -> FailSafeTxFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_fs_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = + try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| FailSafeTxErr::Error(format!("{:?}", e)))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default().push_opcode(Opcode::OP_1).into_script(); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fus!(Public::from_slice(maker_pub)), + &try_fs_fus!(Public::from_slice(maker_pub)), ); let fut = async move { - let fee = try_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = match coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await { + Ok(f) => f, + Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + }; + let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, script_pubkey, }; - let transaction = try_s!( - coin.p2sh_spending_tx( + let transaction = match coin + .p2sh_spending_tx( prev_tx, redeem_script.into(), vec![output], @@ -1253,9 +1258,22 @@ where &key_pair, ) .await - ); + { + Ok(tx) => tx, + Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + }; let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); - try_s!(tx_fut.await); + + match tx_fut.await { + Ok(_) => (), + Err(err) => { + return Err(FailSafeTxErr::RpcCallFailed( + TransactionEnum::from(transaction), + format!("{:?}", err), + )); + }, + } + Ok(transaction.into()) }; Box::new(fut.boxed().compat()) diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 7456665808..895bb2809f 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -13,7 +13,7 @@ use crate::init_withdraw::{InitWithdrawCoin, WithdrawTaskHandle}; use crate::utxo::utxo_builder::{UtxoArcBuilder, UtxoCoinBuilder}; use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, GetWithdrawSenderAddress, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, SwapOps, TradePreimageValue, ValidateAddressResult, - ValidatePaymentInput, WithdrawFut, WithdrawSenderAddress}; + ValidatePaymentInput, WithdrawFut, WithdrawSenderAddress, FailSafeTxFut}; use common::mm_metrics::MetricsArc; use common::mm_number::MmNumber; use crypto::trezor::utxo::TrezorUtxoCoin; @@ -313,7 +313,7 @@ impl SwapOps for UtxoStandardCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_taker_refunds_payment(self.clone(), taker_tx, time_lock, maker_pub, secret_hash, htlc_privkey) } diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index b9c04ce165..d076b5471a 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -13,8 +13,8 @@ use crate::mm2::lp_ordermatch::{MatchBy, OrderConfirmationsSettings, TakerAction use crate::mm2::lp_swap::{broadcast_p2p_tx_helper, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; -use coins::{lp_coinfind, CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, - ValidatePaymentInput}; +use coins::{lp_coinfind, CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, FailSafeTxErr, TradeFee, + TradePreimageValue, ValidatePaymentInput}; use common::executor::Timer; use common::log::{debug, error, warn}; use common::mm_ctx::MmArc; @@ -1331,10 +1331,24 @@ impl TakerSwap { let transaction = match refund_fut.compat().await { Ok(t) => t, - Err(err) => { - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::TakerPaymentRefundFailed(ERRL!("{}", err).into()), - ])) + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::TakerPaymentRefundFailed(ERRL!("{:?}", err).into()), + ])); + }, + FailSafeTxErr::Error(err) => { + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::TakerPaymentRefundFailed(ERRL!("{:?}", err).into()), + ])); + }, }, }; @@ -1604,20 +1618,32 @@ impl TakerSwap { ); } - let transaction = try_s!( - self.taker_coin - .send_taker_refunds_payment( - &taker_payment, - taker_payment_lock as u32, - other_taker_coin_htlc_pub.as_slice(), - &secret_hash, - taker_coin_htlc_keypair.private().secret.as_slice(), - &taker_coin_swap_contract_address, - ) - .compat() - .await + let fut = self.taker_coin.send_taker_refunds_payment( + &taker_payment, + taker_payment_lock as u32, + other_taker_coin_htlc_pub.as_slice(), + &secret_hash, + taker_coin_htlc_keypair.private().secret.as_slice(), + &taker_coin_swap_contract_address, ); + let transaction = match fut.compat().await { + Ok(t) => t, + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return ERR!("{:?}", err); + }, + FailSafeTxErr::Error(err) => return ERR!("{:?}", err), + }, + }; + Ok(RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, coin: self.maker_coin.ticker().to_string(), From 98df7cffa3c408a6e6fdea50741814ff27493001 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 13 Apr 2022 17:56:01 +0300 Subject: [PATCH 22/48] save development state Signed-off-by: ozkanonur --- mm2src/coins/eth.rs | 79 +++++++------ mm2src/coins/lightning.rs | 22 ++-- mm2src/coins/lp_coins.rs | 33 ++++-- mm2src/coins/qrc20.rs | 81 +++++++------ mm2src/coins/qrc20/swap.rs | 40 ++++--- mm2src/coins/solana.rs | 16 +-- mm2src/coins/solana/spl.rs | 22 ++-- mm2src/coins/test_coin.rs | 16 +-- mm2src/coins/utxo.rs | 29 +++-- mm2src/coins/utxo/bch.rs | 14 +-- mm2src/coins/utxo/qtum.rs | 18 +-- mm2src/coins/utxo/slp.rs | 70 +++++------ mm2src/coins/utxo/utxo_common.rs | 142 +++++++++++++--------- mm2src/coins/utxo/utxo_standard.rs | 14 +-- mm2src/coins/z_coin.rs | 66 +++++------ mm2src/lp_swap/maker_swap.rs | 135 +++++++++++++++------ mm2src/lp_swap/taker_swap.rs | 181 +++++++++++++++++++++-------- 17 files changed, 609 insertions(+), 369 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index e69d3df6cb..ec8666aa1d 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -58,14 +58,14 @@ use super::{BalanceError, BalanceFut, CoinBalance, CoinProtocol, CoinTransportMe FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, NumConversResult, RpcClientType, RpcTransportEventHandler, RpcTransportEventHandlerShared, SwapOps, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, Transaction, - TransactionDetails, TransactionEnum, TransactionFut, ValidateAddressResult, WithdrawError, WithdrawFee, - WithdrawFut, WithdrawRequest, WithdrawResult}; + TransactionDetails, TransactionEnum, ValidateAddressResult, WithdrawError, WithdrawFee, WithdrawFut, + WithdrawRequest, WithdrawResult}; pub use ethcore_transaction::SignedTransaction as SignedEthTx; pub use rlp; mod web3_transport; -use crate::{FailSafeTxFut, FailSafeTxErr, ValidatePaymentInput}; +use crate::{FailSafeTxErr, FailSafeTxFut, ValidatePaymentInput}; use common::mm_number::MmNumber; use common::privkey::key_pair_from_secret; use web3_transport::{EthFeeHistoryNamespace, Web3Transport}; @@ -665,11 +665,12 @@ impl Deref for EthCoin { #[async_trait] impl SwapOps for EthCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { - let address = try_fus!(addr_from_raw_pubkey(fee_addr)); + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { + let address = try_fs_fus!(addr_from_raw_pubkey(fee_addr)); Box::new( - self.send_to_address(address, try_fus!(wei_from_big_decimal(&amount, self.decimals))) + self.send_to_address(address, try_fs_fus!(wei_from_big_decimal(&amount, self.decimals))) + .map_err(|e| FailSafeTxErr::Error(e)) .map(TransactionEnum::from), ) } @@ -682,19 +683,20 @@ impl SwapOps for EthCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { - let taker_addr = try_fus!(addr_from_raw_pubkey(taker_pub)); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let taker_addr = try_fs_fus!(addr_from_raw_pubkey(taker_pub)); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.send_hash_time_locked_payment( self.etomic_swap_id(time_lock, secret_hash), - try_fus!(wei_from_big_decimal(&amount, self.decimals)), + try_fs_fus!(wei_from_big_decimal(&amount, self.decimals)), time_lock, secret_hash, taker_addr, swap_contract_address, ) + .map_err(|e| FailSafeTxErr::Error(e)) .map(TransactionEnum::from), ) } @@ -707,19 +709,20 @@ impl SwapOps for EthCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { - let maker_addr = try_fus!(addr_from_raw_pubkey(maker_pub)); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let maker_addr = try_fs_fus!(addr_from_raw_pubkey(maker_pub)); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.send_hash_time_locked_payment( self.etomic_swap_id(time_lock, secret_hash), - try_fus!(wei_from_big_decimal(&amount, self.decimals)), + try_fs_fus!(wei_from_big_decimal(&amount, self.decimals)), time_lock, secret_hash, maker_addr, swap_contract_address, ) + .map_err(|e| FailSafeTxErr::Error(e)) .map(TransactionEnum::from), ) } @@ -732,13 +735,14 @@ impl SwapOps for EthCoin { secret: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fus!(rlp::decode(taker_payment_tx)); - let signed = try_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(taker_payment_tx)); + let signed = try_fs_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) + .map_err(|e| FailSafeTxErr::Error(e)) .map(TransactionEnum::from), ) } @@ -751,12 +755,13 @@ impl SwapOps for EthCoin { secret: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fus!(rlp::decode(maker_payment_tx)); - let signed = try_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(maker_payment_tx)); + let signed = try_fs_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) + .map_err(|e| FailSafeTxErr::Error(e)) .map(TransactionEnum::from), ) } @@ -789,13 +794,14 @@ impl SwapOps for EthCoin { _secret_hash: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fus!(rlp::decode(maker_payment_tx)); - let signed = try_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(maker_payment_tx)); + let signed = try_fs_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) + .map_err(|e| FailSafeTxErr::Error(e)) .map(TransactionEnum::from), ) } @@ -1207,18 +1213,18 @@ impl MarketCoinOps for EthCoin { wait_until: u64, from_block: u64, swap_contract_address: &Option, - ) -> TransactionFut { - let unverified: UnverifiedTransaction = try_fus!(rlp::decode(tx_bytes)); - let tx = try_fus!(SignedEthTx::new(unverified)); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let unverified: UnverifiedTransaction = try_fs_fus!(rlp::decode(tx_bytes)); + let tx = try_fs_fus!(SignedEthTx::new(unverified)); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); let func_name = match self.coin_type { EthCoinType::Eth => "ethPayment", EthCoinType::Erc20 { .. } => "erc20Payment", }; - let payment_func = try_fus!(SWAP_CONTRACT.function(func_name)); - let decoded = try_fus!(payment_func.decode_input(&tx.data)); + let payment_func = try_fs_fus!(SWAP_CONTRACT.function(func_name)); + let decoded = try_fs_fus!(payment_func.decode_input(&tx.data)); let id = match &decoded[0] { Token::FixedBytes(bytes) => bytes.clone(), _ => panic!(), @@ -1273,16 +1279,15 @@ impl MarketCoinOps for EthCoin { }, }; - return Ok(TransactionEnum::from(try_s!(signed_tx_from_web3_tx(transaction)))); + return Ok(TransactionEnum::from(try_fs_s!(signed_tx_from_web3_tx(transaction)))); } } if now_ms() / 1000 > wait_until { - return ERR!( + return Err(FailSafeTxErr::Error(format!( "Waited too long until {} for transaction {:?} to be spent ", - wait_until, - tx - ); + wait_until, tx + ))); } Timer::sleep(5.).await; continue; diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index ca30e31af1..7033d3f9f2 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -2,10 +2,10 @@ use super::{lp_coinfind_or_err, MmCoinEnum}; use crate::utxo::rpc_clients::UtxoRpcClientEnum; use crate::utxo::utxo_common::{big_decimal_from_sat_unsigned, UtxoTxBuilder}; use crate::utxo::{sat_from_big_decimal, BlockchainNetwork, FeePolicy, UtxoCommonOps, UtxoTxGenerationOps}; -use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, - NegotiateSwapContractAddrErr, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, - TradePreimageValue, TransactionEnum, TransactionFut, UtxoStandardCoin, ValidateAddressResult, - ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, FailSafeTxFut}; +use crate::{BalanceFut, CoinBalance, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, + MmCoin, NegotiateSwapContractAddrErr, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, + TradePreimageValue, TransactionEnum, UtxoStandardCoin, ValidateAddressResult, + ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest}; use async_trait::async_trait; use bigdecimal::BigDecimal; use bitcoin::blockdata::script::Script; @@ -220,7 +220,7 @@ impl LightningCoin { #[async_trait] // Todo: Implement this when implementing swaps for lightning as it's is used only for swaps impl SwapOps for LightningCoin { - fn send_taker_fee(&self, _fee_addr: &[u8], _amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { unimplemented!() } + fn send_taker_fee(&self, _fee_addr: &[u8], _amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { unimplemented!() } fn send_maker_payment( &self, @@ -230,7 +230,7 @@ impl SwapOps for LightningCoin { _secret_hash: &[u8], _amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -242,7 +242,7 @@ impl SwapOps for LightningCoin { _secret_hash: &[u8], _amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -254,7 +254,7 @@ impl SwapOps for LightningCoin { _secret: &[u8], _htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -266,7 +266,7 @@ impl SwapOps for LightningCoin { _secret: &[u8], _htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -290,7 +290,7 @@ impl SwapOps for LightningCoin { _secret_hash: &[u8], _htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -426,7 +426,7 @@ impl MarketCoinOps for LightningCoin { _wait_until: u64, _from_block: u64, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index fd431670ec..c56ee84b0e 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -89,14 +89,25 @@ macro_rules! try_fus { } macro_rules! try_fs_fus { + ($e: expr) => { + match $e { + Ok(ok) => ok, + Err(err) => return Box::new(futures01::future::err(FailSafeTxErr::Error(ERRL!("{:?}", err)))), + } + }; +} + +macro_rules! try_fs_s { ($e: expr) => { match $e { Ok(ok) => ok, Err(err) => { - return Box::new(futures01::future::err(FailSafeTxErr::Error(format!( - "{:?}", + return Err(FailSafeTxErr::Error(format!( + "{}:{}] {:?}", + file!(), + line!(), err - )))) + ))) }, } }; @@ -239,8 +250,6 @@ impl Deref for TransactionEnum { } } -pub type TransactionFut = Box + Send>; - #[derive(Debug, PartialEq)] pub enum FailSafeTxErr { /// Tx and Error @@ -286,7 +295,7 @@ pub struct ValidatePaymentInput { /// Swap operations (mostly based on the Hash/Time locked transactions implemented by coin wallets). #[async_trait] pub trait SwapOps { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> TransactionFut; + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> FailSafeTxFut; fn send_maker_payment( &self, @@ -296,7 +305,7 @@ pub trait SwapOps { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut; + ) -> FailSafeTxFut; fn send_taker_payment( &self, @@ -306,7 +315,7 @@ pub trait SwapOps { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut; + ) -> FailSafeTxFut; fn send_maker_spends_taker_payment( &self, @@ -316,7 +325,7 @@ pub trait SwapOps { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut; + ) -> FailSafeTxFut; fn send_taker_spends_maker_payment( &self, @@ -326,7 +335,7 @@ pub trait SwapOps { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut; + ) -> FailSafeTxFut; fn send_taker_refunds_payment( &self, @@ -346,7 +355,7 @@ pub trait SwapOps { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut; + ) -> FailSafeTxFut; fn validate_fee( &self, @@ -462,7 +471,7 @@ pub trait MarketCoinOps { wait_until: u64, from_block: u64, swap_contract_address: &Option, - ) -> TransactionFut; + ) -> FailSafeTxFut; fn tx_enum_from_bytes(&self, bytes: &[u8]) -> Result; diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index b3b70f5e6f..25a64cbf60 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -11,12 +11,11 @@ use crate::utxo::{qtum, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy HistoryUtxoTxMap, RecentlySpentOutPoints, UtxoActivationParams, UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps, UtxoFromLegacyReqErr, UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps, VerboseTransactionFrom, UTXO_LOCK}; -use crate::{BalanceError, BalanceFut, CoinBalance, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, - MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, SwapOps, FailSafeTxErr, +use crate::{BalanceError, BalanceFut, CoinBalance, FailSafeTxErr, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, + HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, SwapOps, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, - TransactionDetails, TransactionEnum, TransactionFut, TransactionType, UnexpectedDerivationMethod, - ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, - WithdrawResult}; + TransactionDetails, TransactionEnum, TransactionType, UnexpectedDerivationMethod, ValidateAddressResult, + ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, WithdrawResult}; use async_trait::async_trait; use bigdecimal::BigDecimal; use bitcrypto::{dhash160, sha256}; @@ -444,7 +443,10 @@ impl Qrc20Coin { /// Generate and send a transaction with the specified UTXO outputs. /// Note this function locks the `UTXO_LOCK`. - pub async fn send_contract_calls(&self, outputs: Vec) -> Result { + pub async fn send_contract_calls( + &self, + outputs: Vec, + ) -> Result { // TODO: we need to somehow refactor it using RecentlySpentOutpoints cache // Move over all QRC20 tokens should share the same cache with each other and base QTUM coin let _utxo_lock = UTXO_LOCK.lock().await; @@ -455,8 +457,16 @@ impl Qrc20Coin { .generate_qrc20_transaction(outputs) .await .mm_err(|e| e.into_withdraw_error(platform, decimals)) - .map_err(|e| ERRL!("{}", e))?; - let _tx = try_s!(self.utxo.rpc_client.send_transaction(&signed).compat().await); + .map_err(|e| FailSafeTxErr::Error(ERRL!("{}", e)))?; + let _tx = match self.utxo.rpc_client.send_transaction(&signed).compat().await { + Ok(tx) => tx, + Err(err) => { + return Err(FailSafeTxErr::RpcCallFailed( + TransactionEnum::from(signed), + format!("{:?}", err), + )); + }, + }; Ok(signed.into()) } @@ -709,11 +719,11 @@ impl UtxoCommonOps for Qrc20Coin { #[async_trait] impl SwapOps for Qrc20Coin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { - let to_address = try_fus!(self.contract_address_from_raw_pubkey(fee_addr)); - let amount = try_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { + let to_address = try_fs_fus!(self.contract_address_from_raw_pubkey(fee_addr)); + let amount = try_fs_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let transfer_output = - try_fus!(self.transfer_output(to_address, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT)); + try_fs_fus!(self.transfer_output(to_address, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT)); let outputs = vec![transfer_output]; let selfi = self.clone(); @@ -730,12 +740,12 @@ impl SwapOps for Qrc20Coin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { - let taker_addr = try_fus!(self.contract_address_from_raw_pubkey(taker_pub)); + ) -> FailSafeTxFut { + let taker_addr = try_fs_fus!(self.contract_address_from_raw_pubkey(taker_pub)); let id = qrc20_swap_id(time_lock, secret_hash); - let value = try_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); + let value = try_fs_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let secret_hash = Vec::from(secret_hash); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -754,12 +764,12 @@ impl SwapOps for Qrc20Coin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { - let maker_addr = try_fus!(self.contract_address_from_raw_pubkey(maker_pub)); + ) -> FailSafeTxFut { + let maker_addr = try_fs_fus!(self.contract_address_from_raw_pubkey(maker_pub)); let id = qrc20_swap_id(time_lock, secret_hash); - let value = try_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); + let value = try_fs_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let secret_hash = Vec::from(secret_hash); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -778,9 +788,9 @@ impl SwapOps for Qrc20Coin { secret: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { - let payment_tx: UtxoTx = try_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let payment_tx: UtxoTx = try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); let secret = secret.to_vec(); let selfi = self.clone(); @@ -800,10 +810,10 @@ impl SwapOps for Qrc20Coin { secret: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { - let payment_tx: UtxoTx = try_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + ) -> FailSafeTxFut { + let payment_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); let secret = secret.to_vec(); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -832,7 +842,7 @@ impl SwapOps for Qrc20Coin { .refund_hash_time_locked_payment(swap_contract_address, payment_tx) .await }; - Box::new(fut.boxed().compat().map_err(|e| FailSafeTxErr::Error(e))) + Box::new(fut.boxed().compat()) } fn send_maker_refunds_payment( @@ -843,9 +853,9 @@ impl SwapOps for Qrc20Coin { _secret_hash: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { - let payment_tx: UtxoTx = try_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); - let swap_contract_address = try_fus!(swap_contract_address.try_to_address()); + ) -> FailSafeTxFut { + let payment_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -1088,11 +1098,16 @@ impl MarketCoinOps for Qrc20Coin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> TransactionFut { - let tx: UtxoTx = try_fus!(deserialize(transaction).map_err(|e| ERRL!("{:?}", e))); + ) -> FailSafeTxFut { + let tx: UtxoTx = try_fs_fus!(deserialize(transaction).map_err(|e| ERRL!("{:?}", e))); let selfi = self.clone(); - let fut = async move { selfi.wait_for_tx_spend_impl(tx, wait_until, from_block).await }; + let fut = async move { + selfi + .wait_for_tx_spend_impl(tx, wait_until, from_block) + .map_err(|e| FailSafeTxErr::Error(e)) + .await + }; Box::new(fut.boxed().compat()) } diff --git a/mm2src/coins/qrc20/swap.rs b/mm2src/coins/qrc20/swap.rs index 185f96a2dd..51b360a47a 100644 --- a/mm2src/coins/qrc20/swap.rs +++ b/mm2src/coins/qrc20/swap.rs @@ -37,16 +37,19 @@ impl Qrc20Coin { secret_hash: Vec, receiver_addr: H160, swap_contract_address: H160, - ) -> Result { - let balance = try_s!(self.my_spendable_balance().compat().await); - let balance = try_s!(wei_from_big_decimal(&balance, self.utxo.decimals)); + ) -> Result { + let balance = try_fs_s!(self.my_spendable_balance().compat().await); + let balance = try_fs_s!(wei_from_big_decimal(&balance, self.utxo.decimals)); // Check the balance to avoid unnecessary burning of gas if balance < value { - return ERR!("Balance {} is less than value {}", balance, value); + return Err(FailSafeTxErr::Error(format!( + "Balance {} is less than value {}", + balance, value + ))); } - let outputs = try_s!( + let outputs = try_fs_s!( self.generate_swap_payment_outputs( balance, id, @@ -67,17 +70,21 @@ impl Qrc20Coin { payment_tx: UtxoTx, swap_contract_address: H160, secret: Vec, - ) -> Result { + ) -> Result { let Erc20PaymentDetails { swap_id, value, sender, .. - } = try_s!(self.erc20_payment_details_from_tx(&payment_tx).await); + } = try_fs_s!(self.erc20_payment_details_from_tx(&payment_tx).await); - let status = try_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); + let status = try_fs_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { - return ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); + return Err(FailSafeTxErr::Error(format!( + "Payment state is not PAYMENT_STATE_SENT, got {}", + status + ))); } - let spend_output = try_s!(self.receiver_spend_output(&swap_contract_address, swap_id, value, secret, sender)); + let spend_output = + try_fs_s!(self.receiver_spend_output(&swap_contract_address, swap_id, value, secret, sender)); self.send_contract_calls(vec![spend_output]).await } @@ -85,22 +92,25 @@ impl Qrc20Coin { &self, swap_contract_address: H160, payment_tx: UtxoTx, - ) -> Result { + ) -> Result { let Erc20PaymentDetails { swap_id, value, receiver, secret_hash, .. - } = try_s!(self.erc20_payment_details_from_tx(&payment_tx).await); + } = try_fs_s!(self.erc20_payment_details_from_tx(&payment_tx).await); - let status = try_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); + let status = try_fs_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { - return ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); + return Err(FailSafeTxErr::Error(format!( + "Payment state is not PAYMENT_STATE_SENT, got {}", + status + ))); } let refund_output = - try_s!(self.sender_refund_output(&swap_contract_address, swap_id, value, secret_hash, receiver)); + try_fs_s!(self.sender_refund_output(&swap_contract_address, swap_id, value, secret_hash, receiver)); self.send_contract_calls(vec![refund_output]).await } diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index 5743b3fc06..4ef618f147 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -1,4 +1,4 @@ -use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum, TransactionFut}; +use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum}; use crate::solana::solana_common::{lamports_to_sol, PrepareTransferData, SufficientBalanceError}; use crate::solana::spl::SplTokenInfo; use crate::{BalanceError, BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, @@ -404,7 +404,7 @@ impl MarketCoinOps for SolanaCoin { _wait_until: u64, _from_block: u64, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -426,7 +426,7 @@ impl MarketCoinOps for SolanaCoin { #[allow(clippy::forget_ref, clippy::forget_copy, clippy::cast_ref_to_mut)] #[async_trait] impl SwapOps for SolanaCoin { - fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { unimplemented!() } + fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { unimplemented!() } fn send_maker_payment( &self, @@ -436,7 +436,7 @@ impl SwapOps for SolanaCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -448,7 +448,7 @@ impl SwapOps for SolanaCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -460,7 +460,7 @@ impl SwapOps for SolanaCoin { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -472,7 +472,7 @@ impl SwapOps for SolanaCoin { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -496,7 +496,7 @@ impl SwapOps for SolanaCoin { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } diff --git a/mm2src/coins/solana/spl.rs b/mm2src/coins/solana/spl.rs index dab4bad319..8acc23d62b 100644 --- a/mm2src/coins/solana/spl.rs +++ b/mm2src/coins/solana/spl.rs @@ -1,9 +1,9 @@ -use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum, TransactionFut}; +use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum}; use crate::solana::solana_common::{ui_amount_to_amount, PrepareTransferData, SufficientBalanceError}; use crate::solana::{solana_common, AccountError, SolanaCommonOps, SolanaFeeDetails}; -use crate::{BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, SolanaCoin, TradePreimageFut, - TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionType, ValidateAddressResult, - ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, WithdrawResult, FailSafeTxFut}; +use crate::{BalanceFut, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, SolanaCoin, + TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionType, + ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, WithdrawResult}; use async_trait::async_trait; use bigdecimal::BigDecimal; use bincode::serialize; @@ -245,7 +245,7 @@ impl MarketCoinOps for SplToken { _wait_until: u64, _from_block: u64, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -263,7 +263,7 @@ impl MarketCoinOps for SplToken { #[allow(clippy::forget_ref, clippy::forget_copy, clippy::cast_ref_to_mut)] #[async_trait] impl SwapOps for SplToken { - fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { unimplemented!() } + fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { unimplemented!() } fn send_maker_payment( &self, @@ -273,7 +273,7 @@ impl SwapOps for SplToken { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -285,7 +285,7 @@ impl SwapOps for SplToken { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -297,7 +297,7 @@ impl SwapOps for SplToken { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -309,7 +309,7 @@ impl SwapOps for SplToken { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -333,7 +333,7 @@ impl SwapOps for SplToken { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { todo!() } diff --git a/mm2src/coins/test_coin.rs b/mm2src/coins/test_coin.rs index 93d1abe61a..b4fc4c5327 100644 --- a/mm2src/coins/test_coin.rs +++ b/mm2src/coins/test_coin.rs @@ -1,4 +1,4 @@ -use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum, TransactionFut}; +use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum}; use crate::{BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, TradePreimageFut, TradePreimageResult, TradePreimageValue, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawRequest, FailSafeTxFut}; @@ -63,7 +63,7 @@ impl MarketCoinOps for TestCoin { wait_until: u64, from_block: u64, swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -82,7 +82,7 @@ impl MarketCoinOps for TestCoin { #[mockable] #[allow(clippy::forget_ref, clippy::forget_copy, clippy::cast_ref_to_mut)] impl SwapOps for TestCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> TransactionFut { unimplemented!() } + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> FailSafeTxFut { unimplemented!() } fn send_maker_payment( &self, @@ -92,7 +92,7 @@ impl SwapOps for TestCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -104,7 +104,7 @@ impl SwapOps for TestCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -116,7 +116,7 @@ impl SwapOps for TestCoin { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -128,7 +128,7 @@ impl SwapOps for TestCoin { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } @@ -152,7 +152,7 @@ impl SwapOps for TestCoin { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { unimplemented!() } diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 8469fb1be4..66a6b9f3db 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -91,11 +91,12 @@ use super::{BalanceError, BalanceFut, BalanceResult, CoinsContext, DerivationMet HistorySyncState, KmdRewardsDetails, MarketCoinOps, MmCoin, NumConversError, NumConversResult, PrivKeyNotAllowed, PrivKeyPolicy, RpcTransportEventHandler, RpcTransportEventHandlerShared, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, Transaction, TransactionDetails, - TransactionEnum, TransactionFut, UnexpectedDerivationMethod, WithdrawError, WithdrawRequest}; + TransactionEnum, UnexpectedDerivationMethod, WithdrawError, WithdrawRequest}; use crate::coin_balance::{EnableCoinScanPolicy, HDAddressBalanceScanner}; use crate::hd_wallet::{HDAccountOps, HDAccountsMutex, HDAddress, HDWalletCoinOps, HDWalletOps, InvalidBip44ChainError}; use crate::hd_wallet_storage::{HDAccountStorageItem, HDWalletCoinStorage, HDWalletStorageError, HDWalletStorageResult}; use crate::utxo::utxo_block_header_storage::BlockHeaderStorageError; +use crate::FailSafeTxErr; use utxo_block_header_storage::BlockHeaderStorage; #[cfg(not(target_arch = "wasm32"))] pub mod tx_cache; #[cfg(target_arch = "wasm32")] @@ -1457,12 +1458,12 @@ pub fn sat_from_big_decimal(amount: &BigDecimal, decimals: u8) -> NumConversResu }) } -async fn send_outputs_from_my_address_impl(coin: T, outputs: Vec) -> Result +async fn send_outputs_from_my_address_impl(coin: T, outputs: Vec) -> Result where T: AsRef + UtxoCommonOps, { - let my_address = try_s!(coin.as_ref().derivation_method.iguana_or_err()); - let (unspents, recently_sent_txs) = try_s!(coin.list_unspent_ordered(my_address).await); + let my_address = try_fs_s!(coin.as_ref().derivation_method.iguana_or_err()); + let (unspents, recently_sent_txs) = try_fs_s!(coin.list_unspent_ordered(my_address).await); generate_and_send_tx(&coin, unspents, None, FeePolicy::SendExact, recently_sent_txs, outputs).await } @@ -1474,12 +1475,12 @@ async fn generate_and_send_tx( fee_policy: FeePolicy, mut recently_spent: AsyncMutexGuard<'_, RecentlySpentOutPoints>, outputs: Vec, -) -> Result +) -> Result where T: AsRef + UtxoTxGenerationOps + UtxoTxBroadcastOps, { - let my_address = try_s!(coin.as_ref().derivation_method.iguana_or_err()); - let key_pair = try_s!(coin.as_ref().priv_key_policy.key_pair_or_err()); + let my_address = try_fs_s!(coin.as_ref().derivation_method.iguana_or_err()); + let key_pair = try_fs_s!(coin.as_ref().priv_key_policy.key_pair_or_err()); let mut builder = UtxoTxBuilder::new(coin) .add_available_inputs(unspents) @@ -1488,7 +1489,7 @@ where if let Some(required) = required_inputs { builder = builder.add_required_inputs(required); } - let (unsigned, _) = try_s!(builder.build().await); + let (unsigned, _) = try_fs_s!(builder.build().await); let spent_unspents = unsigned .inputs @@ -1506,7 +1507,7 @@ where }; let prev_script = Builder::build_p2pkh(&my_address.hash); - let signed = try_s!(sign_tx( + let signed = try_fs_s!(sign_tx( unsigned, key_pair, prev_script, @@ -1514,7 +1515,15 @@ where coin.as_ref().conf.fork_id )); - try_s!(coin.broadcast_tx(&signed).await); + match coin.broadcast_tx(&signed).await { + Ok(_) => (), + Err(err) => { + return Err(FailSafeTxErr::RpcCallFailed( + TransactionEnum::from(signed), + format!("{:?}", err), + )); + }, + }; recently_spent.add_spent(spent_unspents, signed.hash(), signed.outputs.clone()); diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index e2d5c95b6a..9089b45639 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -831,7 +831,7 @@ impl UtxoCommonOps for BchCoin { #[async_trait] impl SwapOps for BchCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { utxo_common::send_taker_fee(self.clone(), fee_addr, amount) } @@ -843,7 +843,7 @@ impl SwapOps for BchCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_maker_payment(self.clone(), time_lock, maker_pub, taker_pub, secret_hash, amount) } @@ -855,7 +855,7 @@ impl SwapOps for BchCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_taker_payment(self.clone(), time_lock, taker_pub, maker_pub, secret_hash, amount) } @@ -867,7 +867,7 @@ impl SwapOps for BchCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_maker_spends_taker_payment( self.clone(), taker_payment_tx, @@ -886,7 +886,7 @@ impl SwapOps for BchCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_taker_spends_maker_payment( self.clone(), maker_payment_tx, @@ -917,7 +917,7 @@ impl SwapOps for BchCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_maker_refunds_payment(self.clone(), maker_tx, time_lock, taker_pub, secret_hash, htlc_privkey) } @@ -1087,7 +1087,7 @@ impl MarketCoinOps for BchCoin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::wait_for_output_spend( &self.utxo_arc, transaction, diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index e1946e8988..7be8e9e3b1 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -12,9 +12,9 @@ use crate::init_create_account::{self, CreateNewAccountParams, InitCreateHDAccou use crate::init_withdraw::{InitWithdrawCoin, WithdrawTaskHandle}; use crate::utxo::utxo_builder::{MergeUtxoArcOps, UtxoCoinBuildError, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, UtxoFieldsWithHardwareWalletBuilder, UtxoFieldsWithIguanaPrivKeyBuilder}; -use crate::{eth, CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, DelegationError, DelegationFut, +use crate::{eth, CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, DelegationError, DelegationFut, FailSafeTxFut, GetWithdrawSenderAddress, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, StakingInfosFut, SwapOps, - TradePreimageValue, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawSenderAddress, FailSafeTxFut}; + TradePreimageValue, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawSenderAddress}; use common::mm_metrics::MetricsArc; use common::mm_number::MmNumber; use crypto::trezor::utxo::TrezorUtxoCoin; @@ -477,7 +477,7 @@ impl UtxoStandardOps for QtumCoin { #[async_trait] impl SwapOps for QtumCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { utxo_common::send_taker_fee(self.clone(), fee_addr, amount) } @@ -489,7 +489,7 @@ impl SwapOps for QtumCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_maker_payment(self.clone(), time_lock, maker_pub, taker_pub, secret_hash, amount) } @@ -501,7 +501,7 @@ impl SwapOps for QtumCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_taker_payment(self.clone(), time_lock, taker_pub, maker_pub, secret_hash, amount) } @@ -513,7 +513,7 @@ impl SwapOps for QtumCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_maker_spends_taker_payment(self.clone(), taker_tx, time_lock, taker_pub, secret, htlc_privkey) } @@ -525,7 +525,7 @@ impl SwapOps for QtumCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_taker_spends_maker_payment(self.clone(), maker_tx, time_lock, maker_pub, secret, htlc_privkey) } @@ -549,7 +549,7 @@ impl SwapOps for QtumCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_maker_refunds_payment(self.clone(), maker_tx, time_lock, taker_pub, secret_hash, htlc_privkey) } @@ -707,7 +707,7 @@ impl MarketCoinOps for QtumCoin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::wait_for_output_spend( &self.utxo_arc, transaction, diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 9fc0f56e68..c0c3b01840 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -10,10 +10,10 @@ use crate::utxo::utxo_common::{self, big_decimal_from_sat_unsigned, payment_scri use crate::utxo::{generate_and_send_tx, sat_from_big_decimal, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy, GenerateTxError, RecentlySpentOutPoints, UtxoCoinConf, UtxoCoinFields, UtxoCommonOps, UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps}; -use crate::{BalanceFut, CoinBalance, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, - MmCoin, NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, SwapOps, FailSafeTxErr, +use crate::{BalanceFut, CoinBalance, FailSafeTxErr, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, + MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, SwapOps, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, - TransactionDetails, TransactionEnum, TransactionFut, TxFeeDetails, UnexpectedDerivationMethod, + TransactionDetails, TransactionEnum, TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; use async_trait::async_trait; @@ -408,8 +408,8 @@ impl SlpToken { Ok((preimage, recently_spent)) } - pub async fn send_slp_outputs(&self, slp_outputs: Vec) -> Result { - let (preimage, recently_spent) = try_s!(self.generate_slp_tx_preimage(slp_outputs).await); + pub async fn send_slp_outputs(&self, slp_outputs: Vec) -> Result { + let (preimage, recently_spent) = try_fs_s!(self.generate_slp_tx_preimage(slp_outputs).await); generate_and_send_tx( self, preimage.available_bch_inputs, @@ -428,11 +428,11 @@ impl SlpToken { time_lock: u32, secret_hash: &[u8], amount: u64, - ) -> Result { + ) -> Result { let payment_script = payment_script(time_lock, secret_hash, my_pub, other_pub); let script_pubkey = ScriptBuilder::build_p2sh(&dhash160(&payment_script).into()).to_bytes(); let slp_out = SlpOutput { amount, script_pubkey }; - let (preimage, recently_spent) = try_s!(self.generate_slp_tx_preimage(vec![slp_out]).await); + let (preimage, recently_spent) = try_fs_s!(self.generate_slp_tx_preimage(vec![slp_out]).await); generate_and_send_tx( self, preimage.available_bch_inputs, @@ -1125,7 +1125,7 @@ impl MarketCoinOps for SlpToken { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::wait_for_output_spend( self.platform_coin.as_ref(), transaction, @@ -1150,15 +1150,15 @@ impl MarketCoinOps for SlpToken { #[async_trait] impl SwapOps for SlpToken { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { let coin = self.clone(); - let fee_pubkey = try_fus!(Public::from_slice(fee_addr)); + let fee_pubkey = try_fs_fus!(Public::from_slice(fee_addr)); let script_pubkey = ScriptBuilder::build_p2pkh(&fee_pubkey.address_hash().into()).into(); - let amount = try_fus!(sat_from_big_decimal(&amount, self.decimals())); + let amount = try_fs_fus!(sat_from_big_decimal(&amount, self.decimals())); let fut = async move { let slp_out = SlpOutput { amount, script_pubkey }; - let (preimage, recently_spent) = try_s!(coin.generate_slp_tx_preimage(vec![slp_out]).await); + let (preimage, recently_spent) = try_fs_s!(coin.generate_slp_tx_preimage(vec![slp_out]).await); generate_and_send_tx( &coin, preimage.available_bch_inputs, @@ -1180,15 +1180,15 @@ impl SwapOps for SlpToken { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { - let maker_pub = try_fus!(Public::from_slice(maker_pub)); - let taker_pub = try_fus!(Public::from_slice(taker_pub)); - let amount = try_fus!(sat_from_big_decimal(&amount, self.decimals())); + ) -> FailSafeTxFut { + let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); + let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); + let amount = try_fs_fus!(sat_from_big_decimal(&amount, self.decimals())); let secret_hash = secret_hash.to_owned(); let coin = self.clone(); let fut = async move { - let tx = try_s!( + let tx = try_fs_s!( coin.send_htlc(&maker_pub, &taker_pub, time_lock, &secret_hash, amount) .await ); @@ -1205,15 +1205,15 @@ impl SwapOps for SlpToken { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { - let taker_pub = try_fus!(Public::from_slice(taker_pub)); - let maker_pub = try_fus!(Public::from_slice(maker_pub)); - let amount = try_fus!(sat_from_big_decimal(&amount, self.decimals())); + ) -> FailSafeTxFut { + let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); + let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); + let amount = try_fs_fus!(sat_from_big_decimal(&amount, self.decimals())); let secret_hash = secret_hash.to_owned(); let coin = self.clone(); let fut = async move { - let tx = try_s!( + let tx = try_fs_s!( coin.send_htlc(&taker_pub, &maker_pub, time_lock, &secret_hash, amount) .await ); @@ -1230,15 +1230,15 @@ impl SwapOps for SlpToken { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { let tx = taker_payment_tx.to_owned(); - let taker_pub = try_fus!(Public::from_slice(taker_pub)); + let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); let secret = secret.to_owned(); - let htlc_keypair = try_fus!(key_pair_from_secret(htlc_privkey)); + let htlc_keypair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { - let tx = try_s!( + let tx = try_fs_s!( coin.spend_htlc(&tx, &taker_pub, time_lock, &secret, &htlc_keypair) .await ); @@ -1255,15 +1255,15 @@ impl SwapOps for SlpToken { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { let tx = maker_payment_tx.to_owned(); - let maker_pub = try_fus!(Public::from_slice(maker_pub)); + let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); let secret = secret.to_owned(); - let htlc_keypair = try_fus!(key_pair_from_secret(htlc_privkey)); + let htlc_keypair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { - let tx = try_s!( + let tx = try_fs_s!( coin.spend_htlc(&tx, &maker_pub, time_lock, &secret, &htlc_keypair) .await ); @@ -1305,15 +1305,15 @@ impl SwapOps for SlpToken { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { let tx = maker_payment_tx.to_owned(); - let taker_pub = try_fus!(Public::from_slice(taker_pub)); + let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); let secret_hash = secret_hash.to_owned(); - let keypair = try_fus!(key_pair_from_secret(htlc_privkey)); + let keypair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { - let tx = try_s!( + let tx = try_fs_s!( coin.refund_htlc(&tx, &taker_pub, time_lock, &secret_hash, &keypair) .await ); @@ -2001,7 +2001,7 @@ mod slp_tests { script_pubkey: ScriptBuilder::build_p2sh(&dhash160(&htlc_script).into()).into(), }; - let err = block_on(generate_and_send_tx( + let FailSafeTxErr::Error(err) = block_on(generate_and_send_tx( &fusd, unspents, None, diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 362e37f5ce..2575b0aabe 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -8,8 +8,8 @@ use crate::init_withdraw::WithdrawTaskHandle; use crate::utxo::rpc_clients::{electrum_script_hash, BlockHashOrHeight, UnspentInfo, UtxoRpcClientEnum, UtxoRpcClientOps, UtxoRpcResult}; use crate::utxo::utxo_withdraw::{InitUtxoWithdraw, StandardUtxoWithdraw, UtxoWithdraw}; -use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, FailSafeTxFut, GetWithdrawSenderAddress, - HDAddressId, FailSafeTxErr, TradePreimageValue, TxFeeDetails, ValidateAddressResult, +use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, FailSafeTxErr, FailSafeTxFut, + GetWithdrawSenderAddress, HDAddressId, TradePreimageValue, TxFeeDetails, ValidateAddressResult, ValidatePaymentInput, WithdrawFrom, WithdrawResult, WithdrawSenderAddress}; use bigdecimal::{BigDecimal, Zero}; pub use bitcrypto::{dhash160, sha256, ChecksumType}; @@ -561,7 +561,7 @@ pub async fn get_current_mtp(coin: &UtxoCoinFields, coin_variant: CoinVariant) - .await } -pub fn send_outputs_from_my_address(coin: T, outputs: Vec) -> TransactionFut +pub fn send_outputs_from_my_address(coin: T, outputs: Vec) -> FailSafeTxFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { @@ -1014,11 +1014,11 @@ where }) } -pub fn send_taker_fee(coin: T, fee_pub_key: &[u8], amount: BigDecimal) -> TransactionFut +pub fn send_taker_fee(coin: T, fee_pub_key: &[u8], amount: BigDecimal) -> FailSafeTxFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let address = try_fus!(address_from_raw_pubkey( + let address = try_fs_fus!(address_from_raw_pubkey( fee_pub_key, coin.as_ref().conf.pub_addr_prefix, coin.as_ref().conf.pub_t_addr_prefix, @@ -1026,7 +1026,7 @@ where coin.as_ref().conf.bech32_hrp.clone(), coin.addr_format().clone(), )); - let amount = try_fus!(sat_from_big_decimal(&amount, coin.as_ref().decimals)); + let amount = try_fs_fus!(sat_from_big_decimal(&amount, coin.as_ref().decimals)); let output = TransactionOutput { value: amount, script_pubkey: Builder::build_p2pkh(&address.hash).to_bytes(), @@ -1041,14 +1041,14 @@ pub fn send_maker_payment( taker_pub: &[u8], secret_hash: &[u8], amount: BigDecimal, -) -> TransactionFut +) -> FailSafeTxFut where T: AsRef + UtxoCommonOps + Clone + Send + Sync + 'static, { let SwapPaymentOutputsResult { payment_address, outputs, - } = try_fus!(generate_swap_payment_outputs( + } = try_fs_fus!(generate_swap_payment_outputs( &coin, time_lock, maker_pub, @@ -1059,11 +1059,11 @@ where let send_fut = match &coin.as_ref().rpc_client { UtxoRpcClientEnum::Electrum(_) => Either::A(send_outputs_from_my_address(coin, outputs)), UtxoRpcClientEnum::Native(client) => { - let addr_string = try_fus!(payment_address.display_address()); + let addr_string = try_fs_fus!(payment_address.display_address()); Either::B( client .import_address(&addr_string, &addr_string, false) - .map_err(|e| ERRL!("{}", e)) + .map_err(|e| FailSafeTxErr::Error(ERRL!("{}", e))) .and_then(move |_| send_outputs_from_my_address(coin, outputs)), ) }, @@ -1078,14 +1078,14 @@ pub fn send_taker_payment( maker_pub: &[u8], secret_hash: &[u8], amount: BigDecimal, -) -> TransactionFut +) -> FailSafeTxFut where T: AsRef + UtxoCommonOps + Clone + Send + Sync + 'static, { let SwapPaymentOutputsResult { payment_address, outputs, - } = try_fus!(generate_swap_payment_outputs( + } = try_fs_fus!(generate_swap_payment_outputs( &coin, time_lock, taker_pub, @@ -1093,14 +1093,15 @@ where secret_hash, amount )); + let send_fut = match &coin.as_ref().rpc_client { UtxoRpcClientEnum::Electrum(_) => Either::A(send_outputs_from_my_address(coin, outputs)), UtxoRpcClientEnum::Native(client) => { - let addr_string = try_fus!(payment_address.display_address()); + let addr_string = try_fs_fus!(payment_address.display_address()); Either::B( client .import_address(&addr_string, &addr_string, false) - .map_err(|e| ERRL!("{}", e)) + .map_err(|e| FailSafeTxErr::Error(ERRL!("{}", e))) .and_then(move |_| send_outputs_from_my_address(coin, outputs)), ) }, @@ -1115,14 +1116,14 @@ pub fn send_maker_spends_taker_payment( taker_pub: &[u8], secret: &[u8], htlc_privkey: &[u8], -) -> TransactionFut +) -> FailSafeTxFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_fs_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default() .push_data(secret) @@ -1131,18 +1132,19 @@ where let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fus!(Public::from_slice(taker_pub)), + &try_fs_fus!(Public::from_slice(taker_pub)), key_pair.public(), ); let fut = async move { - let fee = try_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = try_fs_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, script_pubkey, }; - let transaction = try_s!( - coin.p2sh_spending_tx( + + let transaction = match coin + .p2sh_spending_tx( prev_tx, redeem_script.into(), vec![output], @@ -1152,9 +1154,21 @@ where &key_pair, ) .await - ); + { + Ok(tx) => tx, + Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + }; + let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); - try_s!(tx_fut.await); + match tx_fut.await { + Ok(_) => (), + Err(err) => { + return Err(FailSafeTxErr::RpcCallFailed( + TransactionEnum::from(transaction), + format!("{:?}", err), + )); + }, + }; Ok(transaction.into()) }; Box::new(fut.boxed().compat()) @@ -1167,14 +1181,14 @@ pub fn send_taker_spends_maker_payment( maker_pub: &[u8], secret: &[u8], htlc_privkey: &[u8], -) -> TransactionFut +) -> FailSafeTxFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_fs_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default() .push_data(secret) @@ -1183,18 +1197,18 @@ where let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fus!(Public::from_slice(maker_pub)), + &try_fs_fus!(Public::from_slice(maker_pub)), key_pair.public(), ); let fut = async move { - let fee = try_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = try_fs_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, script_pubkey, }; - let transaction = try_s!( - coin.p2sh_spending_tx( + let transaction = match coin + .p2sh_spending_tx( prev_tx, redeem_script.into(), vec![output], @@ -1204,9 +1218,21 @@ where &key_pair, ) .await - ); + { + Ok(tx) => tx, + Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + }; + let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); - try_s!(tx_fut.await); + match tx_fut.await { + Ok(_) => (), + Err(err) => { + return Err(FailSafeTxErr::RpcCallFailed( + TransactionEnum::from(transaction), + format!("{:?}", err), + )); + }, + }; Ok(transaction.into()) }; Box::new(fut.boxed().compat()) @@ -1286,31 +1312,31 @@ pub fn send_maker_refunds_payment( taker_pub: &[u8], secret_hash: &[u8], htlc_privkey: &[u8], -) -> TransactionFut +) -> FailSafeTxFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_fs_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default().push_opcode(Opcode::OP_1).into_script(); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fus!(Public::from_slice(taker_pub)), + &try_fs_fus!(Public::from_slice(taker_pub)), ); let fut = async move { - let fee = try_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = try_fs_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, script_pubkey, }; - let transaction = try_s!( - coin.p2sh_spending_tx( + let transaction = match coin + .p2sh_spending_tx( prev_tx, redeem_script.into(), vec![output], @@ -1320,9 +1346,23 @@ where &key_pair, ) .await - ); + { + Ok(tx) => tx, + Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + }; + let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); - try_s!(tx_fut.await); + + match tx_fut.await { + Ok(_) => (), + Err(err) => { + return Err(FailSafeTxErr::RpcCallFailed( + TransactionEnum::from(transaction), + format!("{:?}", err), + )); + }, + } + Ok(transaction.into()) }; Box::new(fut.boxed().compat()) @@ -1753,8 +1793,8 @@ pub fn wait_for_output_spend( output_index: usize, from_block: u64, wait_until: u64, -) -> TransactionFut { - let mut tx: UtxoTx = try_fus!(deserialize(tx_bytes).map_err(|e| ERRL!("{:?}", e))); +) -> FailSafeTxFut { + let mut tx: UtxoTx = try_fs_fus!(deserialize(tx_bytes).map_err(|e| ERRL!("{:?}", e))); tx.tx_hash_algo = coin.tx_hash_algo; let client = coin.rpc_client.clone(); let tx_hash_algo = coin.tx_hash_algo; @@ -1782,12 +1822,10 @@ pub fn wait_for_output_spend( }; if now_ms() / 1000 > wait_until { - return ERR!( + return Err(FailSafeTxErr::Error(format!( "Waited too long until {} for transaction {:?} {} to be spent ", - wait_until, - tx, - output_index, - ); + wait_until, tx, output_index, + ))); } Timer::sleep(10.).await; } @@ -3594,7 +3632,7 @@ pub async fn merge_utxo_loop( ticker, tx.hash().reversed() ), - Err(e) => error!("Error {} on UTXO merge attempt for coin {}", e, ticker), + Err(e) => error!("Error {:?} on UTXO merge attempt for coin {}", e, ticker), } } } diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 895bb2809f..3550b20778 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -246,7 +246,7 @@ impl UtxoStandardOps for UtxoStandardCoin { #[async_trait] impl SwapOps for UtxoStandardCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { utxo_common::send_taker_fee(self.clone(), fee_addr, amount) } @@ -258,7 +258,7 @@ impl SwapOps for UtxoStandardCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_maker_payment(self.clone(), time_lock, maker_pub, taker_pub, secret_hash, amount) } @@ -270,7 +270,7 @@ impl SwapOps for UtxoStandardCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_taker_payment(self.clone(), time_lock, taker_pub, maker_pub, secret_hash, amount) } @@ -282,7 +282,7 @@ impl SwapOps for UtxoStandardCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_maker_spends_taker_payment( self.clone(), taker_payment_tx, @@ -301,7 +301,7 @@ impl SwapOps for UtxoStandardCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_taker_spends_maker_payment(self.clone(), maker_tx, time_lock, maker_pub, secret, htlc_privkey) } @@ -325,7 +325,7 @@ impl SwapOps for UtxoStandardCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::send_maker_refunds_payment(self.clone(), maker_tx, time_lock, taker_pub, secret_hash, htlc_privkey) } @@ -483,7 +483,7 @@ impl MarketCoinOps for UtxoStandardCoin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::wait_for_output_spend( &self.utxo_arc, transaction, diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index 5d2448a02b..c3bf3e5ef2 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -9,8 +9,8 @@ use crate::utxo::{sat_from_big_decimal, utxo_common, ActualTxFee, AdditionalTxDa UtxoTxGenerationOps, UtxoWeak, VerboseTransactionFrom}; use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, - TradePreimageValue, TransactionDetails, TransactionEnum, TransactionFut, TxFeeDetails, - UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawRequest}; + TradePreimageValue, TransactionDetails, TransactionEnum, FailSafeTxFut, TxFeeDetails, + UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawRequest, FailSafeTxErr}; use crate::{Transaction, WithdrawError}; use async_trait::async_trait; use bitcrypto::dhash160; @@ -756,7 +756,7 @@ impl MarketCoinOps for ZCoin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { utxo_common::wait_for_output_spend( self.as_ref(), transaction, @@ -790,11 +790,11 @@ impl MarketCoinOps for ZCoin { #[async_trait] impl SwapOps for ZCoin { - fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> TransactionFut { + fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> FailSafeTxFut { let selfi = self.clone(); let uuid = uuid.to_owned(); let fut = async move { - let tx = try_s!(z_send_dex_fee(&selfi, amount, &uuid).await); + let tx = try_fs_s!(z_send_dex_fee(&selfi, amount, &uuid).await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -808,13 +808,13 @@ impl SwapOps for ZCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { let selfi = self.clone(); - let maker_pub = try_fus!(Public::from_slice(maker_pub)); - let taker_pub = try_fus!(Public::from_slice(taker_pub)); + let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); + let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); let secret_hash = secret_hash.to_vec(); let fut = async move { - let utxo_tx = try_s!(z_send_htlc(&selfi, time_lock, &maker_pub, &taker_pub, &secret_hash, amount).await); + let utxo_tx = try_fs_s!(z_send_htlc(&selfi, time_lock, &maker_pub, &taker_pub, &secret_hash, amount).await); Ok(utxo_tx.into()) }; Box::new(fut.boxed().compat()) @@ -828,13 +828,13 @@ impl SwapOps for ZCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> TransactionFut { + ) -> FailSafeTxFut { let selfi = self.clone(); - let taker_pub = try_fus!(Public::from_slice(taker_pub)); - let maker_pub = try_fus!(Public::from_slice(maker_pub)); + let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); + let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); let secret_hash = secret_hash.to_vec(); let fut = async move { - let utxo_tx = try_s!(z_send_htlc(&selfi, time_lock, &taker_pub, &maker_pub, &secret_hash, amount).await); + let utxo_tx = try_fs_s!(z_send_htlc(&selfi, time_lock, &taker_pub, &maker_pub, &secret_hash, amount).await); Ok(utxo_tx.into()) }; Box::new(fut.boxed().compat()) @@ -848,13 +848,13 @@ impl SwapOps for ZCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { - let tx = try_fus!(ZTransaction::read(taker_payment_tx)); - let key_pair = try_fus!(key_pair_from_secret(htlc_privkey)); + ) -> FailSafeTxFut { + let tx = try_fs_fus!(ZTransaction::read(taker_payment_tx)); + let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fus!(Public::from_slice(taker_pub)), + &try_fs_fus!(Public::from_slice(taker_pub)), key_pair.public(), ); let script_data = ScriptBuilder::default() @@ -872,7 +872,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_s!(tx_fut.await); + let tx = try_fs_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -886,13 +886,13 @@ impl SwapOps for ZCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { - let tx = try_fus!(ZTransaction::read(maker_payment_tx)); - let key_pair = try_fus!(key_pair_from_secret(htlc_privkey)); + ) -> FailSafeTxFut { + let tx = try_fs_fus!(ZTransaction::read(maker_payment_tx)); + let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fus!(Public::from_slice(maker_pub)), + &try_fs_fus!(Public::from_slice(maker_pub)), key_pair.public(), ); let script_data = ScriptBuilder::default() @@ -910,7 +910,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_s!(tx_fut.await); + let tx = try_fs_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -924,14 +924,14 @@ impl SwapOps for ZCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { - let tx = try_fus!(ZTransaction::read(taker_payment_tx)); - let key_pair = try_fus!(key_pair_from_secret(htlc_privkey)); + ) -> FailSafeTxFut { + let tx = try_fs_fus!(ZTransaction::read(taker_payment_tx)); + let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fus!(Public::from_slice(maker_pub)), + &try_fs_fus!(Public::from_slice(maker_pub)), ); let script_data = ScriptBuilder::default().push_opcode(Opcode::OP_1).into_script(); let selfi = self.clone(); @@ -945,7 +945,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_s!(tx_fut.await); + let tx = try_fs_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -959,14 +959,14 @@ impl SwapOps for ZCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> TransactionFut { - let tx = try_fus!(ZTransaction::read(maker_payment_tx)); - let key_pair = try_fus!(key_pair_from_secret(htlc_privkey)); + ) -> FailSafeTxFut { + let tx = try_fs_fus!(ZTransaction::read(maker_payment_tx)); + let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fus!(Public::from_slice(taker_pub)), + &try_fs_fus!(Public::from_slice(taker_pub)), ); let script_data = ScriptBuilder::default().push_opcode(Opcode::OP_1).into_script(); let selfi = self.clone(); @@ -980,7 +980,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_s!(tx_fut.await); + let tx = try_fs_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index 3e68110298..36f2f152e4 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -15,7 +15,7 @@ use crate::mm2::lp_swap::{broadcast_p2p_tx_helper, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use bitcrypto::dhash160; -use coins::{CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, +use coins::{CanRefundHtlc, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, TransactionEnum, ValidatePaymentInput}; use common::log::{debug, error, warn}; use common::mm_error::prelude::*; @@ -651,6 +651,7 @@ impl MakerSwap { &self.r().data.maker_coin_swap_contract_address, ) .compat(); + let transaction = match transaction_f.await { Ok(res) => match res { Some(tx) => tx, @@ -666,10 +667,24 @@ impl MakerSwap { match payment_fut.compat().await { Ok(t) => t, - Err(err) => { - return Ok((Some(MakerSwapCommand::Finish), vec![ - MakerSwapEvent::MakerPaymentTransactionFailed(ERRL!("{}", err).into()), - ])) + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return Ok((Some(MakerSwapCommand::Finish), vec![ + MakerSwapEvent::MakerPaymentTransactionFailed(ERRL!("{}", err).into()), + ])) + }, + FailSafeTxErr::Error(err) => { + return Ok((Some(MakerSwapCommand::Finish), vec![ + MakerSwapEvent::MakerPaymentTransactionFailed(ERRL!("{}", err).into()), + ])) + }, }, } }, @@ -842,21 +857,40 @@ impl MakerSwap { let transaction = match spend_fut.compat().await { Ok(t) => t, - Err(err) => { - return Ok((Some(MakerSwapCommand::RefundMakerPayment), vec![ - MakerSwapEvent::TakerPaymentSpendFailed( - ERRL!("!taker_coin.send_maker_spends_taker_payment: {}", err).into(), - ), - MakerSwapEvent::MakerPaymentWaitRefundStarted { - wait_until: self.wait_refund_until(), - }, - ])) + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return Ok((Some(MakerSwapCommand::RefundMakerPayment), vec![ + MakerSwapEvent::TakerPaymentSpendFailed( + ERRL!("!taker_coin.send_maker_spends_taker_payment: {}", err).into(), + ), + MakerSwapEvent::MakerPaymentWaitRefundStarted { + wait_until: self.wait_refund_until(), + }, + ])) + }, + FailSafeTxErr::Error(err) => { + return Ok((Some(MakerSwapCommand::RefundMakerPayment), vec![ + MakerSwapEvent::TakerPaymentSpendFailed( + ERRL!("!taker_coin.send_maker_spends_taker_payment: {}", err).into(), + ), + MakerSwapEvent::MakerPaymentWaitRefundStarted { + wait_until: self.wait_refund_until(), + }, + ])) + }, }, }; broadcast_p2p_tx_helper( &self.ctx, - tx_helper_topic(self.maker_coin.ticker()), + tx_helper_topic(self.taker_coin.ticker()), transaction.tx_hex(), &self.p2p_privkey, ); @@ -925,12 +959,28 @@ impl MakerSwap { let transaction = match spend_fut.compat().await { Ok(t) => t, - Err(err) => { - return Ok((Some(MakerSwapCommand::Finish), vec![ - MakerSwapEvent::MakerPaymentRefundFailed( - ERRL!("!maker_coin.send_maker_refunds_payment: {}", err).into(), - ), - ])) + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return Ok((Some(MakerSwapCommand::Finish), vec![ + MakerSwapEvent::MakerPaymentRefundFailed( + ERRL!("!maker_coin.send_maker_refunds_payment: {}", err).into(), + ), + ])) + }, + FailSafeTxErr::Error(err) => { + return Ok((Some(MakerSwapCommand::Finish), vec![ + MakerSwapEvent::MakerPaymentRefundFailed( + ERRL!("!maker_coin.send_maker_refunds_payment: {}", err).into(), + ), + ])) + }, }, }; @@ -1091,7 +1141,7 @@ impl MakerSwap { ) .compat() .await - .map_err(|e| ERRL!("{}", e)) + .map_err(|e| ERRL!("{:?}", e)) } if self.finished_at.load(Ordering::Relaxed) == 0 { @@ -1181,19 +1231,34 @@ impl MakerSwap { self.r().data.maker_payment_lock + 3700 ); } - let transaction = try_s!( - self.maker_coin - .send_maker_refunds_payment( - &maker_payment, - maker_payment_lock, - other_maker_coin_htlc_pub.as_slice(), - &secret_hash.0, - maker_coin_htlc_keypair.private().secret.as_slice(), - &maker_coin_swap_contract_address, - ) - .compat() - .await - ); + let transaction = match self + .maker_coin + .send_maker_refunds_payment( + &maker_payment, + maker_payment_lock, + other_maker_coin_htlc_pub.as_slice(), + &secret_hash.0, + maker_coin_htlc_keypair.private().secret.as_slice(), + &maker_coin_swap_contract_address, + ) + .compat() + .await + { + Ok(t) => t, + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return ERR!("{}", err); + }, + FailSafeTxErr::Error(err) => return ERR!("{}", err), + }, + }; Ok(RecoveredSwap { action: RecoveredSwapAction::RefundedMyPayment, diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index d076b5471a..798538d156 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -13,7 +13,7 @@ use crate::mm2::lp_ordermatch::{MatchBy, OrderConfirmationsSettings, TakerAction use crate::mm2::lp_swap::{broadcast_p2p_tx_helper, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; -use coins::{lp_coinfind, CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, FailSafeTxErr, TradeFee, +use coins::{lp_coinfind, CanRefundHtlc, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, ValidatePaymentInput}; use common::executor::Timer; use common::log::{debug, error, warn}; @@ -1024,10 +1024,24 @@ impl TakerSwap { .await; let transaction = match fee_tx { Ok(t) => t, - Err(err) => { - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::TakerFeeSendFailed(ERRL!("{}", err).into()), - ])) + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::TakerFeeSendFailed(ERRL!("{}", err).into()), + ])); + }, + FailSafeTxErr::Error(err) => { + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::TakerFeeSendFailed(ERRL!("{}", err).into()), + ])) + }, }, }; @@ -1170,10 +1184,24 @@ impl TakerSwap { match payment_fut.compat().await { Ok(t) => t, - Err(e) => { - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::TakerPaymentTransactionFailed(ERRL!("{}", e).into()), - ])) + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::TakerPaymentTransactionFailed(ERRL!("{}", err).into()), + ])); + }, + FailSafeTxErr::Error(err) => { + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::TakerPaymentTransactionFailed(ERRL!("{}", err).into()), + ])) + }, }, } }, @@ -1234,13 +1262,30 @@ impl TakerSwap { ); let tx = match f.compat().await { Ok(t) => t, - Err(e) => { - return Ok((Some(TakerSwapCommand::RefundTakerPayment), vec![ - TakerSwapEvent::TakerPaymentWaitForSpendFailed(e.into()), - TakerSwapEvent::TakerPaymentWaitRefundStarted { - wait_until: self.wait_refund_until(), - }, - ])) + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.taker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return Ok((Some(TakerSwapCommand::RefundTakerPayment), vec![ + TakerSwapEvent::TakerPaymentWaitForSpendFailed(err.into()), + TakerSwapEvent::TakerPaymentWaitRefundStarted { + wait_until: self.wait_refund_until(), + }, + ])); + }, + FailSafeTxErr::Error(err) => { + return Ok((Some(TakerSwapCommand::RefundTakerPayment), vec![ + TakerSwapEvent::TakerPaymentWaitForSpendFailed(err.into()), + TakerSwapEvent::TakerPaymentWaitRefundStarted { + wait_until: self.wait_refund_until(), + }, + ])) + }, }, }; drop(send_abort_handle); @@ -1281,10 +1326,24 @@ impl TakerSwap { ); let transaction = match spend_fut.compat().await { Ok(t) => t, - Err(err) => { - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::MakerPaymentSpendFailed(ERRL!("{}", err).into()), - ])) + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::MakerPaymentSpendFailed(ERRL!("{}", err).into()), + ])); + }, + FailSafeTxErr::Error(err) => { + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::MakerPaymentSpendFailed(ERRL!("{}", err).into()), + ])) + }, }, }; @@ -1546,19 +1605,34 @@ impl TakerSwap { let secret = self.r().secret.0; let maker_coin_swap_contract_address = self.r().data.maker_coin_swap_contract_address.clone(); - let transaction = try_s!( - self.maker_coin - .send_taker_spends_maker_payment( - &maker_payment, - self.maker_payment_lock.load(Ordering::Relaxed) as u32, - other_maker_coin_htlc_pub.as_slice(), - &secret, - maker_coin_htlc_keypair.private().secret.as_slice(), - &maker_coin_swap_contract_address, - ) - .compat() - .await - ); + let transaction = match self + .maker_coin + .send_taker_spends_maker_payment( + &maker_payment, + self.maker_payment_lock.load(Ordering::Relaxed) as u32, + other_maker_coin_htlc_pub.as_slice(), + &secret, + maker_coin_htlc_keypair.private().secret.as_slice(), + &maker_coin_swap_contract_address, + ) + .compat() + .await + { + Ok(t) => t, + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return ERR!("{}", err); + }, + FailSafeTxErr::Error(err) => return ERR!("{}", err), + }, + }; return Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, @@ -1585,19 +1659,34 @@ impl TakerSwap { FoundSwapTxSpend::Spent(tx) => { check_maker_payment_is_not_spent!(); let secret = try_s!(self.taker_coin.extract_secret(&self.r().secret_hash.0, &tx.tx_hex())); - let transaction = try_s!( - self.maker_coin - .send_taker_spends_maker_payment( - &maker_payment, - self.maker_payment_lock.load(Ordering::Relaxed) as u32, - other_maker_coin_htlc_pub.as_slice(), - &secret, - maker_coin_htlc_keypair.private().secret.as_slice(), - &maker_coin_swap_contract_address, - ) - .compat() - .await - ); + let transaction = match self + .maker_coin + .send_taker_spends_maker_payment( + &maker_payment, + self.maker_payment_lock.load(Ordering::Relaxed) as u32, + other_maker_coin_htlc_pub.as_slice(), + &secret, + maker_coin_htlc_keypair.private().secret.as_slice(), + &maker_coin_swap_contract_address, + ) + .compat() + .await + { + Ok(t) => t, + Err(err_enum) => match err_enum { + FailSafeTxErr::RpcCallFailed(tx, err) => { + broadcast_p2p_tx_helper( + &self.ctx, + tx_helper_topic(self.maker_coin.ticker()), + tx.tx_hex(), + &self.p2p_privkey, + ); + + return ERR!("{}", err); + }, + FailSafeTxErr::Error(err) => return ERR!("{}", err), + }, + }; Ok(RecoveredSwap { action: RecoveredSwapAction::SpentOtherPayment, From b1f9745872abe0b3d0181a70e8383727838ca493 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 13 Apr 2022 18:29:11 +0300 Subject: [PATCH 23/48] optimize code-base Signed-off-by: ozkanonur --- mm2src/coins/eth.rs | 32 +++++++++++++------------- mm2src/coins/lightning.rs | 22 +++++++++--------- mm2src/coins/lp_coins.rs | 29 +++++++++--------------- mm2src/coins/qrc20.rs | 22 +++++++++--------- mm2src/coins/solana.rs | 21 ++++++++--------- mm2src/coins/solana/spl.rs | 20 ++++++++--------- mm2src/coins/test_coin.rs | 20 ++++++++--------- mm2src/coins/utxo.rs | 2 +- mm2src/coins/utxo/bch.rs | 20 ++++++++--------- mm2src/coins/utxo/qtum.rs | 21 ++++++++--------- mm2src/coins/utxo/slp.rs | 36 +++++++++++++++++------------- mm2src/coins/utxo/utxo_common.rs | 30 ++++++++++++------------- mm2src/coins/utxo/utxo_standard.rs | 20 ++++++++--------- mm2src/coins/z_coin.rs | 25 +++++++++++---------- mm2src/docker_tests/qrc20_tests.rs | 11 ++++++--- mm2src/lp_swap/maker_swap.rs | 6 ++--- 16 files changed, 172 insertions(+), 165 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index ec8666aa1d..06141c9bb8 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -65,7 +65,7 @@ pub use ethcore_transaction::SignedTransaction as SignedEthTx; pub use rlp; mod web3_transport; -use crate::{FailSafeTxErr, FailSafeTxFut, ValidatePaymentInput}; +use crate::{FailSafeTxErr, TransactionFut, ValidatePaymentInput}; use common::mm_number::MmNumber; use common::privkey::key_pair_from_secret; use web3_transport::{EthFeeHistoryNamespace, Web3Transport}; @@ -665,12 +665,12 @@ impl Deref for EthCoin { #[async_trait] impl SwapOps for EthCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { let address = try_fs_fus!(addr_from_raw_pubkey(fee_addr)); Box::new( self.send_to_address(address, try_fs_fus!(wei_from_big_decimal(&amount, self.decimals))) - .map_err(|e| FailSafeTxErr::Error(e)) + .map_err(FailSafeTxErr::Error) .map(TransactionEnum::from), ) } @@ -683,7 +683,7 @@ impl SwapOps for EthCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let taker_addr = try_fs_fus!(addr_from_raw_pubkey(taker_pub)); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); @@ -696,7 +696,7 @@ impl SwapOps for EthCoin { taker_addr, swap_contract_address, ) - .map_err(|e| FailSafeTxErr::Error(e)) + .map_err(FailSafeTxErr::Error) .map(TransactionEnum::from), ) } @@ -709,7 +709,7 @@ impl SwapOps for EthCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let maker_addr = try_fs_fus!(addr_from_raw_pubkey(maker_pub)); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); @@ -722,7 +722,7 @@ impl SwapOps for EthCoin { maker_addr, swap_contract_address, ) - .map_err(|e| FailSafeTxErr::Error(e)) + .map_err(FailSafeTxErr::Error) .map(TransactionEnum::from), ) } @@ -735,14 +735,14 @@ impl SwapOps for EthCoin { secret: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(taker_payment_tx)); let signed = try_fs_fus!(SignedEthTx::new(tx)); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) - .map_err(|e| FailSafeTxErr::Error(e)) + .map_err(FailSafeTxErr::Error) .map(TransactionEnum::from), ) } @@ -755,13 +755,13 @@ impl SwapOps for EthCoin { secret: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(maker_payment_tx)); let signed = try_fs_fus!(SignedEthTx::new(tx)); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) - .map_err(|e| FailSafeTxErr::Error(e)) + .map_err(FailSafeTxErr::Error) .map(TransactionEnum::from), ) } @@ -774,14 +774,14 @@ impl SwapOps for EthCoin { _secret_hash: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(taker_payment_tx)); let signed = try_fs_fus!(SignedEthTx::new(tx)); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) - .map_err(|e| FailSafeTxErr::Error(e)) + .map_err(FailSafeTxErr::Error) .map(TransactionEnum::from), ) } @@ -794,14 +794,14 @@ impl SwapOps for EthCoin { _secret_hash: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(maker_payment_tx)); let signed = try_fs_fus!(SignedEthTx::new(tx)); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) - .map_err(|e| FailSafeTxErr::Error(e)) + .map_err(FailSafeTxErr::Error) .map(TransactionEnum::from), ) } @@ -1213,7 +1213,7 @@ impl MarketCoinOps for EthCoin { wait_until: u64, from_block: u64, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let unverified: UnverifiedTransaction = try_fs_fus!(rlp::decode(tx_bytes)); let tx = try_fs_fus!(SignedEthTx::new(unverified)); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index 7033d3f9f2..ccb28a4f52 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -2,9 +2,9 @@ use super::{lp_coinfind_or_err, MmCoinEnum}; use crate::utxo::rpc_clients::UtxoRpcClientEnum; use crate::utxo::utxo_common::{big_decimal_from_sat_unsigned, UtxoTxBuilder}; use crate::utxo::{sat_from_big_decimal, BlockchainNetwork, FeePolicy, UtxoCommonOps, UtxoTxGenerationOps}; -use crate::{BalanceFut, CoinBalance, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, - MmCoin, NegotiateSwapContractAddrErr, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, - TradePreimageValue, TransactionEnum, UtxoStandardCoin, ValidateAddressResult, +use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, + NegotiateSwapContractAddrErr, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, + TradePreimageValue, TransactionEnum, TransactionFut, UtxoStandardCoin, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest}; use async_trait::async_trait; use bigdecimal::BigDecimal; @@ -220,7 +220,7 @@ impl LightningCoin { #[async_trait] // Todo: Implement this when implementing swaps for lightning as it's is used only for swaps impl SwapOps for LightningCoin { - fn send_taker_fee(&self, _fee_addr: &[u8], _amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { unimplemented!() } + fn send_taker_fee(&self, _fee_addr: &[u8], _amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { unimplemented!() } fn send_maker_payment( &self, @@ -230,7 +230,7 @@ impl SwapOps for LightningCoin { _secret_hash: &[u8], _amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -242,7 +242,7 @@ impl SwapOps for LightningCoin { _secret_hash: &[u8], _amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -254,7 +254,7 @@ impl SwapOps for LightningCoin { _secret: &[u8], _htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -266,7 +266,7 @@ impl SwapOps for LightningCoin { _secret: &[u8], _htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -278,7 +278,7 @@ impl SwapOps for LightningCoin { _secret_hash: &[u8], _htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -290,7 +290,7 @@ impl SwapOps for LightningCoin { _secret_hash: &[u8], _htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -426,7 +426,7 @@ impl MarketCoinOps for LightningCoin { _wait_until: u64, _from_block: u64, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index c56ee84b0e..e3f90556a6 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -101,14 +101,7 @@ macro_rules! try_fs_s { ($e: expr) => { match $e { Ok(ok) => ok, - Err(err) => { - return Err(FailSafeTxErr::Error(format!( - "{}:{}] {:?}", - file!(), - line!(), - err - ))) - }, + Err(err) => return Err(FailSafeTxErr::Error(format!("{}:{}] {:?}", file!(), line!(), err))), } }; } @@ -253,11 +246,11 @@ impl Deref for TransactionEnum { #[derive(Debug, PartialEq)] pub enum FailSafeTxErr { /// Tx and Error - RpcCallFailed(TransactionEnum, String), + RpcCallFailed(Box, String), Error(String), } -pub type FailSafeTxFut = Box + Send>; +pub type TransactionFut = Box + Send>; #[derive(Debug, PartialEq)] pub enum FoundSwapTxSpend { @@ -295,7 +288,7 @@ pub struct ValidatePaymentInput { /// Swap operations (mostly based on the Hash/Time locked transactions implemented by coin wallets). #[async_trait] pub trait SwapOps { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> FailSafeTxFut; + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> TransactionFut; fn send_maker_payment( &self, @@ -305,7 +298,7 @@ pub trait SwapOps { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut; + ) -> TransactionFut; fn send_taker_payment( &self, @@ -315,7 +308,7 @@ pub trait SwapOps { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut; + ) -> TransactionFut; fn send_maker_spends_taker_payment( &self, @@ -325,7 +318,7 @@ pub trait SwapOps { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut; + ) -> TransactionFut; fn send_taker_spends_maker_payment( &self, @@ -335,7 +328,7 @@ pub trait SwapOps { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut; + ) -> TransactionFut; fn send_taker_refunds_payment( &self, @@ -345,7 +338,7 @@ pub trait SwapOps { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut; + ) -> TransactionFut; fn send_maker_refunds_payment( &self, @@ -355,7 +348,7 @@ pub trait SwapOps { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut; + ) -> TransactionFut; fn validate_fee( &self, @@ -471,7 +464,7 @@ pub trait MarketCoinOps { wait_until: u64, from_block: u64, swap_contract_address: &Option, - ) -> FailSafeTxFut; + ) -> TransactionFut; fn tx_enum_from_bytes(&self, bytes: &[u8]) -> Result; diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 25a64cbf60..67f993bc0e 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -11,7 +11,7 @@ use crate::utxo::{qtum, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy HistoryUtxoTxMap, RecentlySpentOutPoints, UtxoActivationParams, UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps, UtxoFromLegacyReqErr, UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps, VerboseTransactionFrom, UTXO_LOCK}; -use crate::{BalanceError, BalanceFut, CoinBalance, FailSafeTxErr, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, +use crate::{BalanceError, BalanceFut, CoinBalance, FailSafeTxErr, TransactionFut, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, SwapOps, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionEnum, TransactionType, UnexpectedDerivationMethod, ValidateAddressResult, @@ -462,7 +462,7 @@ impl Qrc20Coin { Ok(tx) => tx, Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( - TransactionEnum::from(signed), + Box::new(TransactionEnum::from(signed)), format!("{:?}", err), )); }, @@ -719,7 +719,7 @@ impl UtxoCommonOps for Qrc20Coin { #[async_trait] impl SwapOps for Qrc20Coin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { let to_address = try_fs_fus!(self.contract_address_from_raw_pubkey(fee_addr)); let amount = try_fs_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let transfer_output = @@ -740,7 +740,7 @@ impl SwapOps for Qrc20Coin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let taker_addr = try_fs_fus!(self.contract_address_from_raw_pubkey(taker_pub)); let id = qrc20_swap_id(time_lock, secret_hash); let value = try_fs_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); @@ -764,7 +764,7 @@ impl SwapOps for Qrc20Coin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let maker_addr = try_fs_fus!(self.contract_address_from_raw_pubkey(maker_pub)); let id = qrc20_swap_id(time_lock, secret_hash); let value = try_fs_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); @@ -788,7 +788,7 @@ impl SwapOps for Qrc20Coin { secret: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let payment_tx: UtxoTx = try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); let secret = secret.to_vec(); @@ -810,7 +810,7 @@ impl SwapOps for Qrc20Coin { secret: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let payment_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); let secret = secret.to_vec(); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); @@ -832,7 +832,7 @@ impl SwapOps for Qrc20Coin { _secret_hash: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let payment_tx: UtxoTx = try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); @@ -853,7 +853,7 @@ impl SwapOps for Qrc20Coin { _secret_hash: &[u8], _htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let payment_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); @@ -1098,14 +1098,14 @@ impl MarketCoinOps for Qrc20Coin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx: UtxoTx = try_fs_fus!(deserialize(transaction).map_err(|e| ERRL!("{:?}", e))); let selfi = self.clone(); let fut = async move { selfi .wait_for_tx_spend_impl(tx, wait_until, from_block) - .map_err(|e| FailSafeTxErr::Error(e)) + .map_err(FailSafeTxErr::Error) .await }; Box::new(fut.boxed().compat()) diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index 4ef618f147..c9a3b0b76e 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -2,8 +2,9 @@ use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, Trade use crate::solana::solana_common::{lamports_to_sol, PrepareTransferData, SufficientBalanceError}; use crate::solana::spl::SplTokenInfo; use crate::{BalanceError, BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, - TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionType, - ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, WithdrawResult, FailSafeTxFut}; + TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionFut, + TransactionType, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, + WithdrawResult}; use async_trait::async_trait; use base58::ToBase58; use bigdecimal::BigDecimal; @@ -404,7 +405,7 @@ impl MarketCoinOps for SolanaCoin { _wait_until: u64, _from_block: u64, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -426,7 +427,7 @@ impl MarketCoinOps for SolanaCoin { #[allow(clippy::forget_ref, clippy::forget_copy, clippy::cast_ref_to_mut)] #[async_trait] impl SwapOps for SolanaCoin { - fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { unimplemented!() } + fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { unimplemented!() } fn send_maker_payment( &self, @@ -436,7 +437,7 @@ impl SwapOps for SolanaCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -448,7 +449,7 @@ impl SwapOps for SolanaCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -460,7 +461,7 @@ impl SwapOps for SolanaCoin { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -472,7 +473,7 @@ impl SwapOps for SolanaCoin { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -484,7 +485,7 @@ impl SwapOps for SolanaCoin { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -496,7 +497,7 @@ impl SwapOps for SolanaCoin { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } diff --git a/mm2src/coins/solana/spl.rs b/mm2src/coins/solana/spl.rs index 8acc23d62b..8b68b72926 100644 --- a/mm2src/coins/solana/spl.rs +++ b/mm2src/coins/solana/spl.rs @@ -1,8 +1,8 @@ use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum}; use crate::solana::solana_common::{ui_amount_to_amount, PrepareTransferData, SufficientBalanceError}; use crate::solana::{solana_common, AccountError, SolanaCommonOps, SolanaFeeDetails}; -use crate::{BalanceFut, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, SolanaCoin, - TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionType, +use crate::{BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, SolanaCoin, TradePreimageFut, + TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionFut, TransactionType, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFut, WithdrawRequest, WithdrawResult}; use async_trait::async_trait; use bigdecimal::BigDecimal; @@ -245,7 +245,7 @@ impl MarketCoinOps for SplToken { _wait_until: u64, _from_block: u64, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -263,7 +263,7 @@ impl MarketCoinOps for SplToken { #[allow(clippy::forget_ref, clippy::forget_copy, clippy::cast_ref_to_mut)] #[async_trait] impl SwapOps for SplToken { - fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { unimplemented!() } + fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { unimplemented!() } fn send_maker_payment( &self, @@ -273,7 +273,7 @@ impl SwapOps for SplToken { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -285,7 +285,7 @@ impl SwapOps for SplToken { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -297,7 +297,7 @@ impl SwapOps for SplToken { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -309,7 +309,7 @@ impl SwapOps for SplToken { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -321,7 +321,7 @@ impl SwapOps for SplToken { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -333,7 +333,7 @@ impl SwapOps for SplToken { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { todo!() } diff --git a/mm2src/coins/test_coin.rs b/mm2src/coins/test_coin.rs index b4fc4c5327..322237d255 100644 --- a/mm2src/coins/test_coin.rs +++ b/mm2src/coins/test_coin.rs @@ -1,7 +1,7 @@ use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, SwapOps, TradeFee, TransactionEnum}; use crate::{BalanceFut, FeeApproxStage, FoundSwapTxSpend, NegotiateSwapContractAddrErr, TradePreimageFut, - TradePreimageResult, TradePreimageValue, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, - WithdrawRequest, FailSafeTxFut}; + TradePreimageResult, TradePreimageValue, TransactionFut, ValidateAddressResult, ValidatePaymentInput, + WithdrawFut, WithdrawRequest}; use async_trait::async_trait; use bigdecimal::BigDecimal; use common::mm_ctx::MmArc; @@ -63,7 +63,7 @@ impl MarketCoinOps for TestCoin { wait_until: u64, from_block: u64, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -82,7 +82,7 @@ impl MarketCoinOps for TestCoin { #[mockable] #[allow(clippy::forget_ref, clippy::forget_copy, clippy::cast_ref_to_mut)] impl SwapOps for TestCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> FailSafeTxFut { unimplemented!() } + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> TransactionFut { unimplemented!() } fn send_maker_payment( &self, @@ -92,7 +92,7 @@ impl SwapOps for TestCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -104,7 +104,7 @@ impl SwapOps for TestCoin { secret_hash: &[u8], amount: BigDecimal, swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -116,7 +116,7 @@ impl SwapOps for TestCoin { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -128,7 +128,7 @@ impl SwapOps for TestCoin { secret: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -140,7 +140,7 @@ impl SwapOps for TestCoin { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } @@ -152,7 +152,7 @@ impl SwapOps for TestCoin { secret_hash: &[u8], htlc_privkey: &[u8], swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { unimplemented!() } diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 66a6b9f3db..9a952be2f1 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -1519,7 +1519,7 @@ where Ok(_) => (), Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( - TransactionEnum::from(signed), + Box::new(TransactionEnum::from(signed)), format!("{:?}", err), )); }, diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index 9089b45639..a0fa468c63 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -6,8 +6,8 @@ use crate::utxo::slp::{parse_slp_script, ParseSlpScriptError, SlpGenesisParams, use crate::utxo::utxo_builder::{UtxoArcBuilder, UtxoCoinBuilder}; use crate::utxo::utxo_common::big_decimal_from_sat_unsigned; use crate::{BlockHeightAndTime, CanRefundHtlc, CoinBalance, CoinProtocol, NegotiateSwapContractAddrErr, - PrivKeyBuildPolicy, SwapOps, TradePreimageValue, TransactionType, TxFeeDetails, ValidateAddressResult, - ValidatePaymentInput, WithdrawFut, FailSafeTxFut}; + PrivKeyBuildPolicy, SwapOps, TradePreimageValue, TransactionFut, TransactionType, TxFeeDetails, + ValidateAddressResult, ValidatePaymentInput, WithdrawFut}; use common::log::warn; use common::mm_metrics::MetricsArc; use common::mm_number::MmNumber; @@ -831,7 +831,7 @@ impl UtxoCommonOps for BchCoin { #[async_trait] impl SwapOps for BchCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { utxo_common::send_taker_fee(self.clone(), fee_addr, amount) } @@ -843,7 +843,7 @@ impl SwapOps for BchCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_maker_payment(self.clone(), time_lock, maker_pub, taker_pub, secret_hash, amount) } @@ -855,7 +855,7 @@ impl SwapOps for BchCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_taker_payment(self.clone(), time_lock, taker_pub, maker_pub, secret_hash, amount) } @@ -867,7 +867,7 @@ impl SwapOps for BchCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_maker_spends_taker_payment( self.clone(), taker_payment_tx, @@ -886,7 +886,7 @@ impl SwapOps for BchCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_taker_spends_maker_payment( self.clone(), maker_payment_tx, @@ -905,7 +905,7 @@ impl SwapOps for BchCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_taker_refunds_payment(self.clone(), taker_tx, time_lock, maker_pub, secret_hash, htlc_privkey) } @@ -917,7 +917,7 @@ impl SwapOps for BchCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_maker_refunds_payment(self.clone(), maker_tx, time_lock, taker_pub, secret_hash, htlc_privkey) } @@ -1087,7 +1087,7 @@ impl MarketCoinOps for BchCoin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::wait_for_output_spend( &self.utxo_arc, transaction, diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index 7be8e9e3b1..4738d4a85c 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -12,9 +12,10 @@ use crate::init_create_account::{self, CreateNewAccountParams, InitCreateHDAccou use crate::init_withdraw::{InitWithdrawCoin, WithdrawTaskHandle}; use crate::utxo::utxo_builder::{MergeUtxoArcOps, UtxoCoinBuildError, UtxoCoinBuilder, UtxoCoinBuilderCommonOps, UtxoFieldsWithHardwareWalletBuilder, UtxoFieldsWithIguanaPrivKeyBuilder}; -use crate::{eth, CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, DelegationError, DelegationFut, FailSafeTxFut, +use crate::{eth, CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, DelegationError, DelegationFut, GetWithdrawSenderAddress, NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, StakingInfosFut, SwapOps, - TradePreimageValue, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawSenderAddress}; + TradePreimageValue, TransactionFut, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, + WithdrawSenderAddress}; use common::mm_metrics::MetricsArc; use common::mm_number::MmNumber; use crypto::trezor::utxo::TrezorUtxoCoin; @@ -477,7 +478,7 @@ impl UtxoStandardOps for QtumCoin { #[async_trait] impl SwapOps for QtumCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { utxo_common::send_taker_fee(self.clone(), fee_addr, amount) } @@ -489,7 +490,7 @@ impl SwapOps for QtumCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_maker_payment(self.clone(), time_lock, maker_pub, taker_pub, secret_hash, amount) } @@ -501,7 +502,7 @@ impl SwapOps for QtumCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_taker_payment(self.clone(), time_lock, taker_pub, maker_pub, secret_hash, amount) } @@ -513,7 +514,7 @@ impl SwapOps for QtumCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_maker_spends_taker_payment(self.clone(), taker_tx, time_lock, taker_pub, secret, htlc_privkey) } @@ -525,7 +526,7 @@ impl SwapOps for QtumCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_taker_spends_maker_payment(self.clone(), maker_tx, time_lock, maker_pub, secret, htlc_privkey) } @@ -537,7 +538,7 @@ impl SwapOps for QtumCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_taker_refunds_payment(self.clone(), taker_tx, time_lock, maker_pub, secret_hash, htlc_privkey) } @@ -549,7 +550,7 @@ impl SwapOps for QtumCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_maker_refunds_payment(self.clone(), maker_tx, time_lock, taker_pub, secret_hash, htlc_privkey) } @@ -707,7 +708,7 @@ impl MarketCoinOps for QtumCoin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::wait_for_output_spend( &self.utxo_arc, transaction, diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index c0c3b01840..b9972b283e 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -10,11 +10,11 @@ use crate::utxo::utxo_common::{self, big_decimal_from_sat_unsigned, payment_scri use crate::utxo::{generate_and_send_tx, sat_from_big_decimal, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy, GenerateTxError, RecentlySpentOutPoints, UtxoCoinConf, UtxoCoinFields, UtxoCommonOps, UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps}; -use crate::{BalanceFut, CoinBalance, FailSafeTxErr, FailSafeTxFut, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, - MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, SwapOps, - TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, - TransactionDetails, TransactionEnum, TxFeeDetails, UnexpectedDerivationMethod, - ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; +use crate::{BalanceFut, CoinBalance, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, + MmCoin, NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, SwapOps, TradeFee, + TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, + TransactionEnum, TransactionFut, TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, + ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; use async_trait::async_trait; use bitcrypto::dhash160; @@ -1125,7 +1125,7 @@ impl MarketCoinOps for SlpToken { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::wait_for_output_spend( self.platform_coin.as_ref(), transaction, @@ -1150,7 +1150,7 @@ impl MarketCoinOps for SlpToken { #[async_trait] impl SwapOps for SlpToken { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { let coin = self.clone(); let fee_pubkey = try_fs_fus!(Public::from_slice(fee_addr)); let script_pubkey = ScriptBuilder::build_p2pkh(&fee_pubkey.address_hash().into()).into(); @@ -1180,7 +1180,7 @@ impl SwapOps for SlpToken { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); let amount = try_fs_fus!(sat_from_big_decimal(&amount, self.decimals())); @@ -1205,7 +1205,7 @@ impl SwapOps for SlpToken { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); let amount = try_fs_fus!(sat_from_big_decimal(&amount, self.decimals())); @@ -1230,7 +1230,7 @@ impl SwapOps for SlpToken { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx = taker_payment_tx.to_owned(); let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); let secret = secret.to_owned(); @@ -1255,7 +1255,7 @@ impl SwapOps for SlpToken { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx = maker_payment_tx.to_owned(); let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); let secret = secret.to_owned(); @@ -1280,7 +1280,7 @@ impl SwapOps for SlpToken { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx = taker_payment_tx.to_owned(); let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); let secret_hash = secret_hash.to_owned(); @@ -1294,7 +1294,7 @@ impl SwapOps for SlpToken { ); Ok(tx.into()) }; - Box::new(fut.boxed().compat().map_err(|e| FailSafeTxErr::Error(e))) + Box::new(fut.boxed().compat().map_err(FailSafeTxErr::Error)) } fn send_maker_refunds_payment( @@ -1305,7 +1305,7 @@ impl SwapOps for SlpToken { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx = maker_payment_tx.to_owned(); let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); let secret_hash = secret_hash.to_owned(); @@ -2001,7 +2001,7 @@ mod slp_tests { script_pubkey: ScriptBuilder::build_p2sh(&dhash160(&htlc_script).into()).into(), }; - let FailSafeTxErr::Error(err) = block_on(generate_and_send_tx( + let tx_err = block_on(generate_and_send_tx( &fusd, unspents, None, @@ -2010,6 +2010,12 @@ mod slp_tests { vec![slp_send_op_return_out, invalid_slp_send_out], )) .unwrap_err(); + + let err = match tx_err { + FailSafeTxErr::RpcCallFailed(_tx, err) => err, + FailSafeTxErr::Error(err) => err, + }; + println!("{:?}", err); assert!(err.contains("is not valid with reason outputs greater than inputs")); diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 2575b0aabe..bc92976f72 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -8,8 +8,8 @@ use crate::init_withdraw::WithdrawTaskHandle; use crate::utxo::rpc_clients::{electrum_script_hash, BlockHashOrHeight, UnspentInfo, UtxoRpcClientEnum, UtxoRpcClientOps, UtxoRpcResult}; use crate::utxo::utxo_withdraw::{InitUtxoWithdraw, StandardUtxoWithdraw, UtxoWithdraw}; -use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, FailSafeTxErr, FailSafeTxFut, - GetWithdrawSenderAddress, HDAddressId, TradePreimageValue, TxFeeDetails, ValidateAddressResult, +use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, FailSafeTxErr, GetWithdrawSenderAddress, + HDAddressId, TradePreimageValue, TransactionFut, TxFeeDetails, ValidateAddressResult, ValidatePaymentInput, WithdrawFrom, WithdrawResult, WithdrawSenderAddress}; use bigdecimal::{BigDecimal, Zero}; pub use bitcrypto::{dhash160, sha256, ChecksumType}; @@ -561,7 +561,7 @@ pub async fn get_current_mtp(coin: &UtxoCoinFields, coin_variant: CoinVariant) - .await } -pub fn send_outputs_from_my_address(coin: T, outputs: Vec) -> FailSafeTxFut +pub fn send_outputs_from_my_address(coin: T, outputs: Vec) -> TransactionFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { @@ -1014,7 +1014,7 @@ where }) } -pub fn send_taker_fee(coin: T, fee_pub_key: &[u8], amount: BigDecimal) -> FailSafeTxFut +pub fn send_taker_fee(coin: T, fee_pub_key: &[u8], amount: BigDecimal) -> TransactionFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { @@ -1041,7 +1041,7 @@ pub fn send_maker_payment( taker_pub: &[u8], secret_hash: &[u8], amount: BigDecimal, -) -> FailSafeTxFut +) -> TransactionFut where T: AsRef + UtxoCommonOps + Clone + Send + Sync + 'static, { @@ -1078,7 +1078,7 @@ pub fn send_taker_payment( maker_pub: &[u8], secret_hash: &[u8], amount: BigDecimal, -) -> FailSafeTxFut +) -> TransactionFut where T: AsRef + UtxoCommonOps + Clone + Send + Sync + 'static, { @@ -1116,7 +1116,7 @@ pub fn send_maker_spends_taker_payment( taker_pub: &[u8], secret: &[u8], htlc_privkey: &[u8], -) -> FailSafeTxFut +) -> TransactionFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { @@ -1164,7 +1164,7 @@ where Ok(_) => (), Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( - TransactionEnum::from(transaction), + Box::new(TransactionEnum::from(transaction)), format!("{:?}", err), )); }, @@ -1181,7 +1181,7 @@ pub fn send_taker_spends_maker_payment( maker_pub: &[u8], secret: &[u8], htlc_privkey: &[u8], -) -> FailSafeTxFut +) -> TransactionFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { @@ -1228,7 +1228,7 @@ where Ok(_) => (), Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( - TransactionEnum::from(transaction), + Box::new(TransactionEnum::from(transaction)), format!("{:?}", err), )); }, @@ -1245,7 +1245,7 @@ pub fn send_taker_refunds_payment( maker_pub: &[u8], secret_hash: &[u8], htlc_privkey: &[u8], -) -> FailSafeTxFut +) -> TransactionFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { @@ -1294,7 +1294,7 @@ where Ok(_) => (), Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( - TransactionEnum::from(transaction), + Box::new(TransactionEnum::from(transaction)), format!("{:?}", err), )); }, @@ -1312,7 +1312,7 @@ pub fn send_maker_refunds_payment( taker_pub: &[u8], secret_hash: &[u8], htlc_privkey: &[u8], -) -> FailSafeTxFut +) -> TransactionFut where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { @@ -1357,7 +1357,7 @@ where Ok(_) => (), Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( - TransactionEnum::from(transaction), + Box::new(TransactionEnum::from(transaction)), format!("{:?}", err), )); }, @@ -1793,7 +1793,7 @@ pub fn wait_for_output_spend( output_index: usize, from_block: u64, wait_until: u64, -) -> FailSafeTxFut { +) -> TransactionFut { let mut tx: UtxoTx = try_fs_fus!(deserialize(tx_bytes).map_err(|e| ERRL!("{:?}", e))); tx.tx_hash_algo = coin.tx_hash_algo; let client = coin.rpc_client.clone(); diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 3550b20778..1ea659bea3 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -12,8 +12,8 @@ use crate::init_create_account::{self, CreateNewAccountParams, InitCreateHDAccou use crate::init_withdraw::{InitWithdrawCoin, WithdrawTaskHandle}; use crate::utxo::utxo_builder::{UtxoArcBuilder, UtxoCoinBuilder}; use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, GetWithdrawSenderAddress, - NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, SwapOps, TradePreimageValue, ValidateAddressResult, - ValidatePaymentInput, WithdrawFut, WithdrawSenderAddress, FailSafeTxFut}; + NegotiateSwapContractAddrErr, PrivKeyBuildPolicy, SwapOps, TradePreimageValue, TransactionFut, + ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawSenderAddress}; use common::mm_metrics::MetricsArc; use common::mm_number::MmNumber; use crypto::trezor::utxo::TrezorUtxoCoin; @@ -246,7 +246,7 @@ impl UtxoStandardOps for UtxoStandardCoin { #[async_trait] impl SwapOps for UtxoStandardCoin { - fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> FailSafeTxFut { + fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { utxo_common::send_taker_fee(self.clone(), fee_addr, amount) } @@ -258,7 +258,7 @@ impl SwapOps for UtxoStandardCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_maker_payment(self.clone(), time_lock, maker_pub, taker_pub, secret_hash, amount) } @@ -270,7 +270,7 @@ impl SwapOps for UtxoStandardCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_taker_payment(self.clone(), time_lock, taker_pub, maker_pub, secret_hash, amount) } @@ -282,7 +282,7 @@ impl SwapOps for UtxoStandardCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_maker_spends_taker_payment( self.clone(), taker_payment_tx, @@ -301,7 +301,7 @@ impl SwapOps for UtxoStandardCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_taker_spends_maker_payment(self.clone(), maker_tx, time_lock, maker_pub, secret, htlc_privkey) } @@ -313,7 +313,7 @@ impl SwapOps for UtxoStandardCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_taker_refunds_payment(self.clone(), taker_tx, time_lock, maker_pub, secret_hash, htlc_privkey) } @@ -325,7 +325,7 @@ impl SwapOps for UtxoStandardCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::send_maker_refunds_payment(self.clone(), maker_tx, time_lock, taker_pub, secret_hash, htlc_privkey) } @@ -483,7 +483,7 @@ impl MarketCoinOps for UtxoStandardCoin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::wait_for_output_spend( &self.utxo_arc, transaction, diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index c3bf3e5ef2..0dd6494701 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -7,10 +7,11 @@ use crate::utxo::{sat_from_big_decimal, utxo_common, ActualTxFee, AdditionalTxDa FeePolicy, HistoryUtxoTx, HistoryUtxoTxMap, RecentlySpentOutPoints, UtxoActivationParams, UtxoAddressFormat, UtxoArc, UtxoCoinFields, UtxoCommonOps, UtxoFeeDetails, UtxoTxBroadcastOps, UtxoTxGenerationOps, UtxoWeak, VerboseTransactionFrom}; -use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, - NegotiateSwapContractAddrErr, NumConversError, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, - TradePreimageValue, TransactionDetails, TransactionEnum, FailSafeTxFut, TxFeeDetails, - UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawRequest, FailSafeTxErr}; +use crate::{BalanceFut, CoinBalance, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, + MmCoin, NegotiateSwapContractAddrErr, NumConversError, SwapOps, TradeFee, TradePreimageFut, + TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionEnum, TransactionFut, + TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, + WithdrawRequest}; use crate::{Transaction, WithdrawError}; use async_trait::async_trait; use bitcrypto::dhash160; @@ -756,7 +757,7 @@ impl MarketCoinOps for ZCoin { wait_until: u64, from_block: u64, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { utxo_common::wait_for_output_spend( self.as_ref(), transaction, @@ -790,7 +791,7 @@ impl MarketCoinOps for ZCoin { #[async_trait] impl SwapOps for ZCoin { - fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> FailSafeTxFut { + fn send_taker_fee(&self, _fee_addr: &[u8], amount: BigDecimal, uuid: &[u8]) -> TransactionFut { let selfi = self.clone(); let uuid = uuid.to_owned(); let fut = async move { @@ -808,7 +809,7 @@ impl SwapOps for ZCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let selfi = self.clone(); let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); @@ -828,7 +829,7 @@ impl SwapOps for ZCoin { secret_hash: &[u8], amount: BigDecimal, _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let selfi = self.clone(); let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); @@ -848,7 +849,7 @@ impl SwapOps for ZCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx = try_fs_fus!(ZTransaction::read(taker_payment_tx)); let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( @@ -886,7 +887,7 @@ impl SwapOps for ZCoin { secret: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx = try_fs_fus!(ZTransaction::read(maker_payment_tx)); let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( @@ -924,7 +925,7 @@ impl SwapOps for ZCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx = try_fs_fus!(ZTransaction::read(taker_payment_tx)); let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( @@ -959,7 +960,7 @@ impl SwapOps for ZCoin { secret_hash: &[u8], htlc_privkey: &[u8], _swap_contract_address: &Option, - ) -> FailSafeTxFut { + ) -> TransactionFut { let tx = try_fs_fus!(ZTransaction::read(maker_payment_tx)); let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( diff --git a/mm2src/docker_tests/qrc20_tests.rs b/mm2src/docker_tests/qrc20_tests.rs index 58c49bcab8..47ca4d7a0e 100644 --- a/mm2src/docker_tests/qrc20_tests.rs +++ b/mm2src/docker_tests/qrc20_tests.rs @@ -7,8 +7,8 @@ use coins::utxo::qtum::{qtum_coin_with_priv_key, QtumCoin}; use coins::utxo::rpc_clients::UtxoRpcClientEnum; use coins::utxo::utxo_common::big_decimal_from_sat; use coins::utxo::{UtxoActivationParams, UtxoCommonOps}; -use coins::{FeeApproxStage, FoundSwapTxSpend, MarketCoinOps, MmCoin, SwapOps, TradePreimageValue, TransactionEnum, - ValidatePaymentInput}; +use coins::{FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, MarketCoinOps, MmCoin, SwapOps, TradePreimageValue, + TransactionEnum, ValidatePaymentInput}; use common::log::debug; use common::mm_ctx::{MmArc, MmCtxBuilder}; use common::{temp_dir, DEX_FEE_ADDR_RAW_PUBKEY}; @@ -727,7 +727,7 @@ fn test_wait_for_tx_spend() { // first try to check if the wait_for_tx_spend() returns an error correctly let wait_until = (now_ms() / 1000) + 5; - let err = maker_coin + let tx_err = maker_coin .wait_for_tx_spend( &payment_tx_hex, wait_until, @@ -736,6 +736,11 @@ fn test_wait_for_tx_spend() { ) .wait() .expect_err("Expected 'Waited too long' error"); + + let err = match tx_err { + FailSafeTxErr::RpcCallFailed(_tx, err) => err, + FailSafeTxErr::Error(err) => err, + }; log!("error: "[err]); assert!(err.contains("Waited too long")); diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index 36f2f152e4..60a4cbf77e 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -678,7 +678,7 @@ impl MakerSwap { return Ok((Some(MakerSwapCommand::Finish), vec![ MakerSwapEvent::MakerPaymentTransactionFailed(ERRL!("{}", err).into()), - ])) + ])); }, FailSafeTxErr::Error(err) => { return Ok((Some(MakerSwapCommand::Finish), vec![ @@ -873,7 +873,7 @@ impl MakerSwap { MakerSwapEvent::MakerPaymentWaitRefundStarted { wait_until: self.wait_refund_until(), }, - ])) + ])); }, FailSafeTxErr::Error(err) => { return Ok((Some(MakerSwapCommand::RefundMakerPayment), vec![ @@ -972,7 +972,7 @@ impl MakerSwap { MakerSwapEvent::MakerPaymentRefundFailed( ERRL!("!maker_coin.send_maker_refunds_payment: {}", err).into(), ), - ])) + ])); }, FailSafeTxErr::Error(err) => { return Ok((Some(MakerSwapCommand::Finish), vec![ From f136301b029024c4a1ca253d3719b34bce283be1 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 13 Apr 2022 19:08:23 +0300 Subject: [PATCH 24/48] fix fmt Signed-off-by: ozkanonur --- mm2src/coins/qrc20.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 67f993bc0e..9c93947a0d 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -11,10 +11,10 @@ use crate::utxo::{qtum, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy HistoryUtxoTxMap, RecentlySpentOutPoints, UtxoActivationParams, UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps, UtxoFromLegacyReqErr, UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps, VerboseTransactionFrom, UTXO_LOCK}; -use crate::{BalanceError, BalanceFut, CoinBalance, FailSafeTxErr, TransactionFut, FeeApproxStage, FoundSwapTxSpend, - HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, SwapOps, - TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, - TransactionDetails, TransactionEnum, TransactionType, UnexpectedDerivationMethod, ValidateAddressResult, +use crate::{BalanceError, BalanceFut, CoinBalance, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, + MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, SwapOps, TradeFee, + TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, + TransactionEnum, TransactionFut, TransactionType, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, WithdrawResult}; use async_trait::async_trait; use bigdecimal::BigDecimal; From 9a203e7dbb605e2890b692e883f0ef519969c588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Wed, 13 Apr 2022 22:44:55 +0300 Subject: [PATCH 25/48] create wrapper macro `FSTX_ERR` that wraps `ERR` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/eth.rs | 7 ++++--- mm2src/coins/lp_coins.rs | 5 +++++ mm2src/coins/qrc20/swap.rs | 15 +++------------ mm2src/coins/utxo/utxo_common.rs | 18 ++++++++++-------- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 06141c9bb8..35d805066b 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -1284,10 +1284,11 @@ impl MarketCoinOps for EthCoin { } if now_ms() / 1000 > wait_until { - return Err(FailSafeTxErr::Error(format!( + return FSTX_ERR!( "Waited too long until {} for transaction {:?} to be spent ", - wait_until, tx - ))); + wait_until, + tx, + ); } Timer::sleep(5.).await; continue; diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index e3f90556a6..0cc91eef87 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -97,6 +97,11 @@ macro_rules! try_fs_fus { }; } +macro_rules! FSTX_ERR { + ($format: expr, $($args: tt)+) => { Err(FailSafeTxErr::Error((ERRL!($format, $($args)+)))) }; + ($format: expr) => { Err(FailSafeTxErr::Error(ERRL!($format))) } +} + macro_rules! try_fs_s { ($e: expr) => { match $e { diff --git a/mm2src/coins/qrc20/swap.rs b/mm2src/coins/qrc20/swap.rs index 51b360a47a..ff186515fb 100644 --- a/mm2src/coins/qrc20/swap.rs +++ b/mm2src/coins/qrc20/swap.rs @@ -43,10 +43,7 @@ impl Qrc20Coin { // Check the balance to avoid unnecessary burning of gas if balance < value { - return Err(FailSafeTxErr::Error(format!( - "Balance {} is less than value {}", - balance, value - ))); + return FSTX_ERR!("Balance {} is less than value {}", balance, value); } let outputs = try_fs_s!( @@ -77,10 +74,7 @@ impl Qrc20Coin { let status = try_fs_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { - return Err(FailSafeTxErr::Error(format!( - "Payment state is not PAYMENT_STATE_SENT, got {}", - status - ))); + return FSTX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); } let spend_output = @@ -103,10 +97,7 @@ impl Qrc20Coin { let status = try_fs_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { - return Err(FailSafeTxErr::Error(format!( - "Payment state is not PAYMENT_STATE_SENT, got {}", - status - ))); + return FSTX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); } let refund_output = diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index bc92976f72..b43b0c4461 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1156,7 +1156,7 @@ where .await { Ok(tx) => tx, - Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + Err(err) => return FSTX_ERR!("{:?}", err), }; let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); @@ -1220,7 +1220,7 @@ where .await { Ok(tx) => tx, - Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + Err(err) => return FSTX_ERR!("{:?}", err), }; let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); @@ -1265,7 +1265,7 @@ where let fut = async move { let fee = match coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await { Ok(f) => f, - Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + Err(err) => return FSTX_ERR!("{:?}", err), }; let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); @@ -1286,7 +1286,7 @@ where .await { Ok(tx) => tx, - Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + Err(err) => return FSTX_ERR!("{:?}", err), }; let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); @@ -1348,7 +1348,7 @@ where .await { Ok(tx) => tx, - Err(err) => return Err(FailSafeTxErr::Error(format!("{:?}", err))), + Err(err) => return FSTX_ERR!("{:?}", err), }; let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); @@ -1822,10 +1822,12 @@ pub fn wait_for_output_spend( }; if now_ms() / 1000 > wait_until { - return Err(FailSafeTxErr::Error(format!( + return FSTX_ERR!( "Waited too long until {} for transaction {:?} {} to be spent ", - wait_until, tx, output_index, - ))); + wait_until, + tx, + output_index, + ); } Timer::sleep(10.).await; } From b6c8ecba769b8e3e439fb6c423a790ff9d3f66b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Wed, 13 Apr 2022 22:46:58 +0300 Subject: [PATCH 26/48] fix indendation of `FSTX_ERR` macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/lp_coins.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 0cc91eef87..c73cf98c6a 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -98,8 +98,8 @@ macro_rules! try_fs_fus { } macro_rules! FSTX_ERR { - ($format: expr, $($args: tt)+) => { Err(FailSafeTxErr::Error((ERRL!($format, $($args)+)))) }; - ($format: expr) => { Err(FailSafeTxErr::Error(ERRL!($format))) } + ($format: expr, $($args: tt)+) => { Err(FailSafeTxErr::Error((ERRL!($format, $($args)+)))) }; + ($format: expr) => { Err(FailSafeTxErr::Error(ERRL!($format))) } } macro_rules! try_fs_s { From d10d4a90814cd3ca46c1cfd1a45a273d6dee22e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Wed, 13 Apr 2022 23:09:02 +0300 Subject: [PATCH 27/48] update namings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/eth.rs | 52 ++++++++++++++++---------------- mm2src/coins/lp_coins.rs | 4 +-- mm2src/coins/qrc20.rs | 36 +++++++++++----------- mm2src/coins/qrc20/swap.rs | 18 +++++------ mm2src/coins/utxo.rs | 12 ++++---- mm2src/coins/utxo/slp.rs | 48 ++++++++++++++--------------- mm2src/coins/utxo/utxo_common.rs | 52 ++++++++++++++++---------------- mm2src/coins/z_coin.rs | 48 +++++++++++++++-------------- 8 files changed, 136 insertions(+), 134 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 35d805066b..a820a6599a 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -666,10 +666,10 @@ impl Deref for EthCoin { #[async_trait] impl SwapOps for EthCoin { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { - let address = try_fs_fus!(addr_from_raw_pubkey(fee_addr)); + let address = try_fstx_fus!(addr_from_raw_pubkey(fee_addr)); Box::new( - self.send_to_address(address, try_fs_fus!(wei_from_big_decimal(&amount, self.decimals))) + self.send_to_address(address, try_fstx_fus!(wei_from_big_decimal(&amount, self.decimals))) .map_err(FailSafeTxErr::Error) .map(TransactionEnum::from), ) @@ -684,13 +684,13 @@ impl SwapOps for EthCoin { amount: BigDecimal, swap_contract_address: &Option, ) -> TransactionFut { - let taker_addr = try_fs_fus!(addr_from_raw_pubkey(taker_pub)); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let taker_addr = try_fstx_fus!(addr_from_raw_pubkey(taker_pub)); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); Box::new( self.send_hash_time_locked_payment( self.etomic_swap_id(time_lock, secret_hash), - try_fs_fus!(wei_from_big_decimal(&amount, self.decimals)), + try_fstx_fus!(wei_from_big_decimal(&amount, self.decimals)), time_lock, secret_hash, taker_addr, @@ -710,13 +710,13 @@ impl SwapOps for EthCoin { amount: BigDecimal, swap_contract_address: &Option, ) -> TransactionFut { - let maker_addr = try_fs_fus!(addr_from_raw_pubkey(maker_pub)); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let maker_addr = try_fstx_fus!(addr_from_raw_pubkey(maker_pub)); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); Box::new( self.send_hash_time_locked_payment( self.etomic_swap_id(time_lock, secret_hash), - try_fs_fus!(wei_from_big_decimal(&amount, self.decimals)), + try_fstx_fus!(wei_from_big_decimal(&amount, self.decimals)), time_lock, secret_hash, maker_addr, @@ -736,9 +736,9 @@ impl SwapOps for EthCoin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(taker_payment_tx)); - let signed = try_fs_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let tx: UnverifiedTransaction = try_fstx_fus!(rlp::decode(taker_payment_tx)); + let signed = try_fstx_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) @@ -756,9 +756,9 @@ impl SwapOps for EthCoin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(maker_payment_tx)); - let signed = try_fs_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let tx: UnverifiedTransaction = try_fstx_fus!(rlp::decode(maker_payment_tx)); + let signed = try_fstx_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) .map_err(FailSafeTxErr::Error) @@ -775,9 +775,9 @@ impl SwapOps for EthCoin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(taker_payment_tx)); - let signed = try_fs_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let tx: UnverifiedTransaction = try_fstx_fus!(rlp::decode(taker_payment_tx)); + let signed = try_fstx_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) @@ -795,9 +795,9 @@ impl SwapOps for EthCoin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fs_fus!(rlp::decode(maker_payment_tx)); - let signed = try_fs_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let tx: UnverifiedTransaction = try_fstx_fus!(rlp::decode(maker_payment_tx)); + let signed = try_fstx_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) @@ -1214,17 +1214,17 @@ impl MarketCoinOps for EthCoin { from_block: u64, swap_contract_address: &Option, ) -> TransactionFut { - let unverified: UnverifiedTransaction = try_fs_fus!(rlp::decode(tx_bytes)); - let tx = try_fs_fus!(SignedEthTx::new(unverified)); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let unverified: UnverifiedTransaction = try_fstx_fus!(rlp::decode(tx_bytes)); + let tx = try_fstx_fus!(SignedEthTx::new(unverified)); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); let func_name = match self.coin_type { EthCoinType::Eth => "ethPayment", EthCoinType::Erc20 { .. } => "erc20Payment", }; - let payment_func = try_fs_fus!(SWAP_CONTRACT.function(func_name)); - let decoded = try_fs_fus!(payment_func.decode_input(&tx.data)); + let payment_func = try_fstx_fus!(SWAP_CONTRACT.function(func_name)); + let decoded = try_fstx_fus!(payment_func.decode_input(&tx.data)); let id = match &decoded[0] { Token::FixedBytes(bytes) => bytes.clone(), _ => panic!(), @@ -1279,7 +1279,7 @@ impl MarketCoinOps for EthCoin { }, }; - return Ok(TransactionEnum::from(try_fs_s!(signed_tx_from_web3_tx(transaction)))); + return Ok(TransactionEnum::from(try_fstx_s!(signed_tx_from_web3_tx(transaction)))); } } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index c73cf98c6a..124c365e85 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -88,7 +88,7 @@ macro_rules! try_fus { }; } -macro_rules! try_fs_fus { +macro_rules! try_fstx_fus { ($e: expr) => { match $e { Ok(ok) => ok, @@ -102,7 +102,7 @@ macro_rules! FSTX_ERR { ($format: expr) => { Err(FailSafeTxErr::Error(ERRL!($format))) } } -macro_rules! try_fs_s { +macro_rules! try_fstx_s { ($e: expr) => { match $e { Ok(ok) => ok, diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 9c93947a0d..67173c6f2d 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -720,10 +720,10 @@ impl UtxoCommonOps for Qrc20Coin { #[async_trait] impl SwapOps for Qrc20Coin { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { - let to_address = try_fs_fus!(self.contract_address_from_raw_pubkey(fee_addr)); - let amount = try_fs_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); + let to_address = try_fstx_fus!(self.contract_address_from_raw_pubkey(fee_addr)); + let amount = try_fstx_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let transfer_output = - try_fs_fus!(self.transfer_output(to_address, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT)); + try_fstx_fus!(self.transfer_output(to_address, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT)); let outputs = vec![transfer_output]; let selfi = self.clone(); @@ -741,11 +741,11 @@ impl SwapOps for Qrc20Coin { amount: BigDecimal, swap_contract_address: &Option, ) -> TransactionFut { - let taker_addr = try_fs_fus!(self.contract_address_from_raw_pubkey(taker_pub)); + let taker_addr = try_fstx_fus!(self.contract_address_from_raw_pubkey(taker_pub)); let id = qrc20_swap_id(time_lock, secret_hash); - let value = try_fs_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); + let value = try_fstx_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let secret_hash = Vec::from(secret_hash); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -765,11 +765,11 @@ impl SwapOps for Qrc20Coin { amount: BigDecimal, swap_contract_address: &Option, ) -> TransactionFut { - let maker_addr = try_fs_fus!(self.contract_address_from_raw_pubkey(maker_pub)); + let maker_addr = try_fstx_fus!(self.contract_address_from_raw_pubkey(maker_pub)); let id = qrc20_swap_id(time_lock, secret_hash); - let value = try_fs_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); + let value = try_fstx_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let secret_hash = Vec::from(secret_hash); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -789,8 +789,8 @@ impl SwapOps for Qrc20Coin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let payment_tx: UtxoTx = try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let payment_tx: UtxoTx = try_fstx_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); let secret = secret.to_vec(); let selfi = self.clone(); @@ -811,9 +811,9 @@ impl SwapOps for Qrc20Coin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let payment_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let payment_tx: UtxoTx = try_fstx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); let secret = secret.to_vec(); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -833,8 +833,8 @@ impl SwapOps for Qrc20Coin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let payment_tx: UtxoTx = try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let payment_tx: UtxoTx = try_fstx_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -854,8 +854,8 @@ impl SwapOps for Qrc20Coin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let payment_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); - let swap_contract_address = try_fs_fus!(swap_contract_address.try_to_address()); + let payment_tx: UtxoTx = try_fstx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -1099,7 +1099,7 @@ impl MarketCoinOps for Qrc20Coin { from_block: u64, _swap_contract_address: &Option, ) -> TransactionFut { - let tx: UtxoTx = try_fs_fus!(deserialize(transaction).map_err(|e| ERRL!("{:?}", e))); + let tx: UtxoTx = try_fstx_fus!(deserialize(transaction).map_err(|e| ERRL!("{:?}", e))); let selfi = self.clone(); let fut = async move { diff --git a/mm2src/coins/qrc20/swap.rs b/mm2src/coins/qrc20/swap.rs index ff186515fb..3dcbf20659 100644 --- a/mm2src/coins/qrc20/swap.rs +++ b/mm2src/coins/qrc20/swap.rs @@ -38,15 +38,15 @@ impl Qrc20Coin { receiver_addr: H160, swap_contract_address: H160, ) -> Result { - let balance = try_fs_s!(self.my_spendable_balance().compat().await); - let balance = try_fs_s!(wei_from_big_decimal(&balance, self.utxo.decimals)); + let balance = try_fstx_s!(self.my_spendable_balance().compat().await); + let balance = try_fstx_s!(wei_from_big_decimal(&balance, self.utxo.decimals)); // Check the balance to avoid unnecessary burning of gas if balance < value { return FSTX_ERR!("Balance {} is less than value {}", balance, value); } - let outputs = try_fs_s!( + let outputs = try_fstx_s!( self.generate_swap_payment_outputs( balance, id, @@ -70,15 +70,15 @@ impl Qrc20Coin { ) -> Result { let Erc20PaymentDetails { swap_id, value, sender, .. - } = try_fs_s!(self.erc20_payment_details_from_tx(&payment_tx).await); + } = try_fstx_s!(self.erc20_payment_details_from_tx(&payment_tx).await); - let status = try_fs_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); + let status = try_fstx_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { return FSTX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); } let spend_output = - try_fs_s!(self.receiver_spend_output(&swap_contract_address, swap_id, value, secret, sender)); + try_fstx_s!(self.receiver_spend_output(&swap_contract_address, swap_id, value, secret, sender)); self.send_contract_calls(vec![spend_output]).await } @@ -93,15 +93,15 @@ impl Qrc20Coin { receiver, secret_hash, .. - } = try_fs_s!(self.erc20_payment_details_from_tx(&payment_tx).await); + } = try_fstx_s!(self.erc20_payment_details_from_tx(&payment_tx).await); - let status = try_fs_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); + let status = try_fstx_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { return FSTX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); } let refund_output = - try_fs_s!(self.sender_refund_output(&swap_contract_address, swap_id, value, secret_hash, receiver)); + try_fstx_s!(self.sender_refund_output(&swap_contract_address, swap_id, value, secret_hash, receiver)); self.send_contract_calls(vec![refund_output]).await } diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 9a952be2f1..19775a9733 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -1462,8 +1462,8 @@ async fn send_outputs_from_my_address_impl(coin: T, outputs: Vec + UtxoCommonOps, { - let my_address = try_fs_s!(coin.as_ref().derivation_method.iguana_or_err()); - let (unspents, recently_sent_txs) = try_fs_s!(coin.list_unspent_ordered(my_address).await); + let my_address = try_fstx_s!(coin.as_ref().derivation_method.iguana_or_err()); + let (unspents, recently_sent_txs) = try_fstx_s!(coin.list_unspent_ordered(my_address).await); generate_and_send_tx(&coin, unspents, None, FeePolicy::SendExact, recently_sent_txs, outputs).await } @@ -1479,8 +1479,8 @@ async fn generate_and_send_tx( where T: AsRef + UtxoTxGenerationOps + UtxoTxBroadcastOps, { - let my_address = try_fs_s!(coin.as_ref().derivation_method.iguana_or_err()); - let key_pair = try_fs_s!(coin.as_ref().priv_key_policy.key_pair_or_err()); + let my_address = try_fstx_s!(coin.as_ref().derivation_method.iguana_or_err()); + let key_pair = try_fstx_s!(coin.as_ref().priv_key_policy.key_pair_or_err()); let mut builder = UtxoTxBuilder::new(coin) .add_available_inputs(unspents) @@ -1489,7 +1489,7 @@ where if let Some(required) = required_inputs { builder = builder.add_required_inputs(required); } - let (unsigned, _) = try_fs_s!(builder.build().await); + let (unsigned, _) = try_fstx_s!(builder.build().await); let spent_unspents = unsigned .inputs @@ -1507,7 +1507,7 @@ where }; let prev_script = Builder::build_p2pkh(&my_address.hash); - let signed = try_fs_s!(sign_tx( + let signed = try_fstx_s!(sign_tx( unsigned, key_pair, prev_script, diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index b9972b283e..e60832509d 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -409,7 +409,7 @@ impl SlpToken { } pub async fn send_slp_outputs(&self, slp_outputs: Vec) -> Result { - let (preimage, recently_spent) = try_fs_s!(self.generate_slp_tx_preimage(slp_outputs).await); + let (preimage, recently_spent) = try_fstx_s!(self.generate_slp_tx_preimage(slp_outputs).await); generate_and_send_tx( self, preimage.available_bch_inputs, @@ -432,7 +432,7 @@ impl SlpToken { let payment_script = payment_script(time_lock, secret_hash, my_pub, other_pub); let script_pubkey = ScriptBuilder::build_p2sh(&dhash160(&payment_script).into()).to_bytes(); let slp_out = SlpOutput { amount, script_pubkey }; - let (preimage, recently_spent) = try_fs_s!(self.generate_slp_tx_preimage(vec![slp_out]).await); + let (preimage, recently_spent) = try_fstx_s!(self.generate_slp_tx_preimage(vec![slp_out]).await); generate_and_send_tx( self, preimage.available_bch_inputs, @@ -1152,13 +1152,13 @@ impl MarketCoinOps for SlpToken { impl SwapOps for SlpToken { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { let coin = self.clone(); - let fee_pubkey = try_fs_fus!(Public::from_slice(fee_addr)); + let fee_pubkey = try_fstx_fus!(Public::from_slice(fee_addr)); let script_pubkey = ScriptBuilder::build_p2pkh(&fee_pubkey.address_hash().into()).into(); - let amount = try_fs_fus!(sat_from_big_decimal(&amount, self.decimals())); + let amount = try_fstx_fus!(sat_from_big_decimal(&amount, self.decimals())); let fut = async move { let slp_out = SlpOutput { amount, script_pubkey }; - let (preimage, recently_spent) = try_fs_s!(coin.generate_slp_tx_preimage(vec![slp_out]).await); + let (preimage, recently_spent) = try_fstx_s!(coin.generate_slp_tx_preimage(vec![slp_out]).await); generate_and_send_tx( &coin, preimage.available_bch_inputs, @@ -1181,14 +1181,14 @@ impl SwapOps for SlpToken { amount: BigDecimal, _swap_contract_address: &Option, ) -> TransactionFut { - let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); - let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); - let amount = try_fs_fus!(sat_from_big_decimal(&amount, self.decimals())); + let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); + let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); + let amount = try_fstx_fus!(sat_from_big_decimal(&amount, self.decimals())); let secret_hash = secret_hash.to_owned(); let coin = self.clone(); let fut = async move { - let tx = try_fs_s!( + let tx = try_fstx_s!( coin.send_htlc(&maker_pub, &taker_pub, time_lock, &secret_hash, amount) .await ); @@ -1206,14 +1206,14 @@ impl SwapOps for SlpToken { amount: BigDecimal, _swap_contract_address: &Option, ) -> TransactionFut { - let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); - let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); - let amount = try_fs_fus!(sat_from_big_decimal(&amount, self.decimals())); + let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); + let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); + let amount = try_fstx_fus!(sat_from_big_decimal(&amount, self.decimals())); let secret_hash = secret_hash.to_owned(); let coin = self.clone(); let fut = async move { - let tx = try_fs_s!( + let tx = try_fstx_s!( coin.send_htlc(&taker_pub, &maker_pub, time_lock, &secret_hash, amount) .await ); @@ -1232,13 +1232,13 @@ impl SwapOps for SlpToken { _swap_contract_address: &Option, ) -> TransactionFut { let tx = taker_payment_tx.to_owned(); - let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); + let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); let secret = secret.to_owned(); - let htlc_keypair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let htlc_keypair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { - let tx = try_fs_s!( + let tx = try_fstx_s!( coin.spend_htlc(&tx, &taker_pub, time_lock, &secret, &htlc_keypair) .await ); @@ -1257,13 +1257,13 @@ impl SwapOps for SlpToken { _swap_contract_address: &Option, ) -> TransactionFut { let tx = maker_payment_tx.to_owned(); - let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); + let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); let secret = secret.to_owned(); - let htlc_keypair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let htlc_keypair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { - let tx = try_fs_s!( + let tx = try_fstx_s!( coin.spend_htlc(&tx, &maker_pub, time_lock, &secret, &htlc_keypair) .await ); @@ -1282,9 +1282,9 @@ impl SwapOps for SlpToken { _swap_contract_address: &Option, ) -> TransactionFut { let tx = taker_payment_tx.to_owned(); - let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); + let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); let secret_hash = secret_hash.to_owned(); - let keypair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let keypair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { @@ -1307,13 +1307,13 @@ impl SwapOps for SlpToken { _swap_contract_address: &Option, ) -> TransactionFut { let tx = maker_payment_tx.to_owned(); - let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); + let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); let secret_hash = secret_hash.to_owned(); - let keypair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let keypair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { - let tx = try_fs_s!( + let tx = try_fstx_s!( coin.refund_htlc(&tx, &taker_pub, time_lock, &secret_hash, &keypair) .await ); diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index b43b0c4461..a95bbfa5eb 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1018,7 +1018,7 @@ pub fn send_taker_fee(coin: T, fee_pub_key: &[u8], amount: BigDecimal) -> Tra where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let address = try_fs_fus!(address_from_raw_pubkey( + let address = try_fstx_fus!(address_from_raw_pubkey( fee_pub_key, coin.as_ref().conf.pub_addr_prefix, coin.as_ref().conf.pub_t_addr_prefix, @@ -1026,7 +1026,7 @@ where coin.as_ref().conf.bech32_hrp.clone(), coin.addr_format().clone(), )); - let amount = try_fs_fus!(sat_from_big_decimal(&amount, coin.as_ref().decimals)); + let amount = try_fstx_fus!(sat_from_big_decimal(&amount, coin.as_ref().decimals)); let output = TransactionOutput { value: amount, script_pubkey: Builder::build_p2pkh(&address.hash).to_bytes(), @@ -1048,7 +1048,7 @@ where let SwapPaymentOutputsResult { payment_address, outputs, - } = try_fs_fus!(generate_swap_payment_outputs( + } = try_fstx_fus!(generate_swap_payment_outputs( &coin, time_lock, maker_pub, @@ -1059,7 +1059,7 @@ where let send_fut = match &coin.as_ref().rpc_client { UtxoRpcClientEnum::Electrum(_) => Either::A(send_outputs_from_my_address(coin, outputs)), UtxoRpcClientEnum::Native(client) => { - let addr_string = try_fs_fus!(payment_address.display_address()); + let addr_string = try_fstx_fus!(payment_address.display_address()); Either::B( client .import_address(&addr_string, &addr_string, false) @@ -1085,7 +1085,7 @@ where let SwapPaymentOutputsResult { payment_address, outputs, - } = try_fs_fus!(generate_swap_payment_outputs( + } = try_fstx_fus!(generate_swap_payment_outputs( &coin, time_lock, taker_pub, @@ -1097,7 +1097,7 @@ where let send_fut = match &coin.as_ref().rpc_client { UtxoRpcClientEnum::Electrum(_) => Either::A(send_outputs_from_my_address(coin, outputs)), UtxoRpcClientEnum::Native(client) => { - let addr_string = try_fs_fus!(payment_address.display_address()); + let addr_string = try_fstx_fus!(payment_address.display_address()); Either::B( client .import_address(&addr_string, &addr_string, false) @@ -1120,10 +1120,10 @@ pub fn send_maker_spends_taker_payment( where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fs_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_fstx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = try_fstx_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default() .push_data(secret) @@ -1132,11 +1132,11 @@ where let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fs_fus!(Public::from_slice(taker_pub)), + &try_fstx_fus!(Public::from_slice(taker_pub)), key_pair.public(), ); let fut = async move { - let fee = try_fs_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = try_fstx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, @@ -1185,10 +1185,10 @@ pub fn send_taker_spends_maker_payment( where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fs_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_fstx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = try_fstx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default() .push_data(secret) @@ -1197,11 +1197,11 @@ where let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fs_fus!(Public::from_slice(maker_pub)), + &try_fstx_fus!(Public::from_slice(maker_pub)), key_pair.public(), ); let fut = async move { - let fee = try_fs_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = try_fstx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, @@ -1249,18 +1249,18 @@ pub fn send_taker_refunds_payment( where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fs_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_fstx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); let mut prev_tx: UtxoTx = - try_fs_fus!(deserialize(taker_payment_tx).map_err(|e| FailSafeTxErr::Error(format!("{:?}", e)))); + try_fstx_fus!(deserialize(taker_payment_tx).map_err(|e| FailSafeTxErr::Error(format!("{:?}", e)))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default().push_opcode(Opcode::OP_1).into_script(); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fs_fus!(Public::from_slice(maker_pub)), + &try_fstx_fus!(Public::from_slice(maker_pub)), ); let fut = async move { let fee = match coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await { @@ -1316,20 +1316,20 @@ pub fn send_maker_refunds_payment( where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fs_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_fstx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fs_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = try_fstx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default().push_opcode(Opcode::OP_1).into_script(); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fs_fus!(Public::from_slice(taker_pub)), + &try_fstx_fus!(Public::from_slice(taker_pub)), ); let fut = async move { - let fee = try_fs_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = try_fstx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, @@ -1794,7 +1794,7 @@ pub fn wait_for_output_spend( from_block: u64, wait_until: u64, ) -> TransactionFut { - let mut tx: UtxoTx = try_fs_fus!(deserialize(tx_bytes).map_err(|e| ERRL!("{:?}", e))); + let mut tx: UtxoTx = try_fstx_fus!(deserialize(tx_bytes).map_err(|e| ERRL!("{:?}", e))); tx.tx_hash_algo = coin.tx_hash_algo; let client = coin.rpc_client.clone(); let tx_hash_algo = coin.tx_hash_algo; diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index 0dd6494701..831856f196 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -795,7 +795,7 @@ impl SwapOps for ZCoin { let selfi = self.clone(); let uuid = uuid.to_owned(); let fut = async move { - let tx = try_fs_s!(z_send_dex_fee(&selfi, amount, &uuid).await); + let tx = try_fstx_s!(z_send_dex_fee(&selfi, amount, &uuid).await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -811,11 +811,12 @@ impl SwapOps for ZCoin { _swap_contract_address: &Option, ) -> TransactionFut { let selfi = self.clone(); - let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); - let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); + let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); + let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); let secret_hash = secret_hash.to_vec(); let fut = async move { - let utxo_tx = try_fs_s!(z_send_htlc(&selfi, time_lock, &maker_pub, &taker_pub, &secret_hash, amount).await); + let utxo_tx = + try_fstx_s!(z_send_htlc(&selfi, time_lock, &maker_pub, &taker_pub, &secret_hash, amount).await); Ok(utxo_tx.into()) }; Box::new(fut.boxed().compat()) @@ -831,11 +832,12 @@ impl SwapOps for ZCoin { _swap_contract_address: &Option, ) -> TransactionFut { let selfi = self.clone(); - let taker_pub = try_fs_fus!(Public::from_slice(taker_pub)); - let maker_pub = try_fs_fus!(Public::from_slice(maker_pub)); + let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); + let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); let secret_hash = secret_hash.to_vec(); let fut = async move { - let utxo_tx = try_fs_s!(z_send_htlc(&selfi, time_lock, &taker_pub, &maker_pub, &secret_hash, amount).await); + let utxo_tx = + try_fstx_s!(z_send_htlc(&selfi, time_lock, &taker_pub, &maker_pub, &secret_hash, amount).await); Ok(utxo_tx.into()) }; Box::new(fut.boxed().compat()) @@ -850,12 +852,12 @@ impl SwapOps for ZCoin { htlc_privkey: &[u8], _swap_contract_address: &Option, ) -> TransactionFut { - let tx = try_fs_fus!(ZTransaction::read(taker_payment_tx)); - let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let tx = try_fstx_fus!(ZTransaction::read(taker_payment_tx)); + let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fs_fus!(Public::from_slice(taker_pub)), + &try_fstx_fus!(Public::from_slice(taker_pub)), key_pair.public(), ); let script_data = ScriptBuilder::default() @@ -873,7 +875,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_fs_s!(tx_fut.await); + let tx = try_fstx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -888,12 +890,12 @@ impl SwapOps for ZCoin { htlc_privkey: &[u8], _swap_contract_address: &Option, ) -> TransactionFut { - let tx = try_fs_fus!(ZTransaction::read(maker_payment_tx)); - let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let tx = try_fstx_fus!(ZTransaction::read(maker_payment_tx)); + let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fs_fus!(Public::from_slice(maker_pub)), + &try_fstx_fus!(Public::from_slice(maker_pub)), key_pair.public(), ); let script_data = ScriptBuilder::default() @@ -911,7 +913,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_fs_s!(tx_fut.await); + let tx = try_fstx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -926,13 +928,13 @@ impl SwapOps for ZCoin { htlc_privkey: &[u8], _swap_contract_address: &Option, ) -> TransactionFut { - let tx = try_fs_fus!(ZTransaction::read(taker_payment_tx)); - let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let tx = try_fstx_fus!(ZTransaction::read(taker_payment_tx)); + let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fs_fus!(Public::from_slice(maker_pub)), + &try_fstx_fus!(Public::from_slice(maker_pub)), ); let script_data = ScriptBuilder::default().push_opcode(Opcode::OP_1).into_script(); let selfi = self.clone(); @@ -946,7 +948,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_fs_s!(tx_fut.await); + let tx = try_fstx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -961,13 +963,13 @@ impl SwapOps for ZCoin { htlc_privkey: &[u8], _swap_contract_address: &Option, ) -> TransactionFut { - let tx = try_fs_fus!(ZTransaction::read(maker_payment_tx)); - let key_pair = try_fs_fus!(key_pair_from_secret(htlc_privkey)); + let tx = try_fstx_fus!(ZTransaction::read(maker_payment_tx)); + let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fs_fus!(Public::from_slice(taker_pub)), + &try_fstx_fus!(Public::from_slice(taker_pub)), ); let script_data = ScriptBuilder::default().push_opcode(Opcode::OP_1).into_script(); let selfi = self.clone(); @@ -981,7 +983,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_fs_s!(tx_fut.await); + let tx = try_fstx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) From 3a2b0e9b1ecd2700876a572af22b4e1dfc5580de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Wed, 13 Apr 2022 23:20:15 +0300 Subject: [PATCH 28/48] replace `format!` with `ERRL!` in `FailSafeTxErr::RpcCallFailed` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/qrc20.rs | 2 +- mm2src/coins/utxo.rs | 2 +- mm2src/coins/utxo/utxo_common.rs | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 67173c6f2d..a7ec8efe4b 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -463,7 +463,7 @@ impl Qrc20Coin { Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( Box::new(TransactionEnum::from(signed)), - format!("{:?}", err), + ERRL!("{:?}", err), )); }, }; diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 19775a9733..2a882b0fe7 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -1520,7 +1520,7 @@ where Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( Box::new(TransactionEnum::from(signed)), - format!("{:?}", err), + ERRL!("{:?}", err), )); }, }; diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index a95bbfa5eb..96597e2ebd 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1165,7 +1165,7 @@ where Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( Box::new(TransactionEnum::from(transaction)), - format!("{:?}", err), + ERRL!("{:?}", err), )); }, }; @@ -1229,7 +1229,7 @@ where Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( Box::new(TransactionEnum::from(transaction)), - format!("{:?}", err), + ERRL!("{:?}", err), )); }, }; @@ -1295,7 +1295,7 @@ where Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( Box::new(TransactionEnum::from(transaction)), - format!("{:?}", err), + ERRL!("{:?}", err), )); }, } @@ -1358,7 +1358,7 @@ where Err(err) => { return Err(FailSafeTxErr::RpcCallFailed( Box::new(TransactionEnum::from(transaction)), - format!("{:?}", err), + ERRL!("{:?}", err), )); }, } From 3299524afb83faacfd90172860488427a623672d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Thu, 14 Apr 2022 02:14:52 +0300 Subject: [PATCH 29/48] optimize PR diffs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/eth.rs | 70 ++++++++-------- mm2src/coins/lp_coins.rs | 43 ++++++---- mm2src/coins/qrc20.rs | 52 ++++++------ mm2src/coins/qrc20/swap.rs | 30 +++---- mm2src/coins/utxo.rs | 23 +++--- mm2src/coins/utxo/slp.rs | 66 +++++++-------- mm2src/coins/utxo/utxo_common.rs | 80 +++++++++--------- mm2src/coins/z_coin.rs | 57 +++++++------ mm2src/docker_tests/qrc20_tests.rs | 8 +- mm2src/lp_swap.rs | 5 +- mm2src/lp_swap/maker_swap.rs | 69 ++++++++-------- mm2src/lp_swap/taker_swap.rs | 125 ++++++++++++++--------------- 12 files changed, 316 insertions(+), 312 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index a820a6599a..14eaf106dc 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -65,7 +65,7 @@ pub use ethcore_transaction::SignedTransaction as SignedEthTx; pub use rlp; mod web3_transport; -use crate::{FailSafeTxErr, TransactionFut, ValidatePaymentInput}; +use crate::{TransactionErr, TransactionFut, ValidatePaymentInput}; use common::mm_number::MmNumber; use common::privkey::key_pair_from_secret; use web3_transport::{EthFeeHistoryNamespace, Web3Transport}; @@ -666,11 +666,11 @@ impl Deref for EthCoin { #[async_trait] impl SwapOps for EthCoin { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { - let address = try_fstx_fus!(addr_from_raw_pubkey(fee_addr)); + let address = try_tx_fus!(addr_from_raw_pubkey(fee_addr)); Box::new( - self.send_to_address(address, try_fstx_fus!(wei_from_big_decimal(&amount, self.decimals))) - .map_err(FailSafeTxErr::Error) + self.send_to_address(address, try_tx_fus!(wei_from_big_decimal(&amount, self.decimals))) + .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -684,19 +684,19 @@ impl SwapOps for EthCoin { amount: BigDecimal, swap_contract_address: &Option, ) -> TransactionFut { - let taker_addr = try_fstx_fus!(addr_from_raw_pubkey(taker_pub)); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let taker_addr = try_tx_fus!(addr_from_raw_pubkey(taker_pub)); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); Box::new( self.send_hash_time_locked_payment( self.etomic_swap_id(time_lock, secret_hash), - try_fstx_fus!(wei_from_big_decimal(&amount, self.decimals)), + try_tx_fus!(wei_from_big_decimal(&amount, self.decimals)), time_lock, secret_hash, taker_addr, swap_contract_address, ) - .map_err(FailSafeTxErr::Error) + .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -710,19 +710,19 @@ impl SwapOps for EthCoin { amount: BigDecimal, swap_contract_address: &Option, ) -> TransactionFut { - let maker_addr = try_fstx_fus!(addr_from_raw_pubkey(maker_pub)); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let maker_addr = try_tx_fus!(addr_from_raw_pubkey(maker_pub)); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); Box::new( self.send_hash_time_locked_payment( self.etomic_swap_id(time_lock, secret_hash), - try_fstx_fus!(wei_from_big_decimal(&amount, self.decimals)), + try_tx_fus!(wei_from_big_decimal(&amount, self.decimals)), time_lock, secret_hash, maker_addr, swap_contract_address, ) - .map_err(FailSafeTxErr::Error) + .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -736,13 +736,13 @@ impl SwapOps for EthCoin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fstx_fus!(rlp::decode(taker_payment_tx)); - let signed = try_fstx_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let tx: UnverifiedTransaction = try_tx_fus!(rlp::decode(taker_payment_tx)); + let signed = try_tx_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) - .map_err(FailSafeTxErr::Error) + .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -756,12 +756,12 @@ impl SwapOps for EthCoin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fstx_fus!(rlp::decode(maker_payment_tx)); - let signed = try_fstx_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let tx: UnverifiedTransaction = try_tx_fus!(rlp::decode(maker_payment_tx)); + let signed = try_tx_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) - .map_err(FailSafeTxErr::Error) + .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -775,13 +775,13 @@ impl SwapOps for EthCoin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fstx_fus!(rlp::decode(taker_payment_tx)); - let signed = try_fstx_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let tx: UnverifiedTransaction = try_tx_fus!(rlp::decode(taker_payment_tx)); + let signed = try_tx_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) - .map_err(FailSafeTxErr::Error) + .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -795,13 +795,13 @@ impl SwapOps for EthCoin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let tx: UnverifiedTransaction = try_fstx_fus!(rlp::decode(maker_payment_tx)); - let signed = try_fstx_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let tx: UnverifiedTransaction = try_tx_fus!(rlp::decode(maker_payment_tx)); + let signed = try_tx_fus!(SignedEthTx::new(tx)); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) - .map_err(FailSafeTxErr::Error) + .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -1214,17 +1214,17 @@ impl MarketCoinOps for EthCoin { from_block: u64, swap_contract_address: &Option, ) -> TransactionFut { - let unverified: UnverifiedTransaction = try_fstx_fus!(rlp::decode(tx_bytes)); - let tx = try_fstx_fus!(SignedEthTx::new(unverified)); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let unverified: UnverifiedTransaction = try_tx_fus!(rlp::decode(tx_bytes)); + let tx = try_tx_fus!(SignedEthTx::new(unverified)); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); let func_name = match self.coin_type { EthCoinType::Eth => "ethPayment", EthCoinType::Erc20 { .. } => "erc20Payment", }; - let payment_func = try_fstx_fus!(SWAP_CONTRACT.function(func_name)); - let decoded = try_fstx_fus!(payment_func.decode_input(&tx.data)); + let payment_func = try_tx_fus!(SWAP_CONTRACT.function(func_name)); + let decoded = try_tx_fus!(payment_func.decode_input(&tx.data)); let id = match &decoded[0] { Token::FixedBytes(bytes) => bytes.clone(), _ => panic!(), @@ -1279,12 +1279,12 @@ impl MarketCoinOps for EthCoin { }, }; - return Ok(TransactionEnum::from(try_fstx_s!(signed_tx_from_web3_tx(transaction)))); + return Ok(TransactionEnum::from(try_tx_s!(signed_tx_from_web3_tx(transaction)))); } } if now_ms() / 1000 > wait_until { - return FSTX_ERR!( + return TX_ERR!( "Waited too long until {} for transaction {:?} to be spent ", wait_until, tx, diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 124c365e85..16111d2c96 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -88,38 +88,48 @@ macro_rules! try_fus { }; } -macro_rules! try_fstx_fus { +macro_rules! try_f { ($e: expr) => { match $e { Ok(ok) => ok, - Err(err) => return Box::new(futures01::future::err(FailSafeTxErr::Error(ERRL!("{:?}", err)))), + Err(e) => return Box::new(futures01::future::err(e)), } }; } -macro_rules! FSTX_ERR { - ($format: expr, $($args: tt)+) => { Err(FailSafeTxErr::Error((ERRL!($format, $($args)+)))) }; - ($format: expr) => { Err(FailSafeTxErr::Error(ERRL!($format))) } -} - -macro_rules! try_fstx_s { +/// `TransactionErr:PlainError` compatible `try_fus` macro. +macro_rules! try_tx_fus { ($e: expr) => { match $e { Ok(ok) => ok, - Err(err) => return Err(FailSafeTxErr::Error(format!("{}:{}] {:?}", file!(), line!(), err))), + Err(err) => return Box::new(futures01::future::err(TransactionErr::PlainError(ERRL!("{:?}", err)))), } }; } -macro_rules! try_f { +/// `TransactionErr:PlainError` compatible `try_s` macro. +macro_rules! try_tx_s { ($e: expr) => { match $e { Ok(ok) => ok, - Err(e) => return Box::new(futures01::future::err(e)), + Err(err) => { + return Err(TransactionErr::PlainError(format!( + "{}:{}] {:?}", + file!(), + line!(), + err + ))) + }, } }; } +/// `TransactionErr:PlainError` compatible `ERR` macro. +macro_rules! TX_ERR { + ($format: expr, $($args: tt)+) => { Err(TransactionErr::PlainError((ERRL!($format, $($args)+)))) }; + ($format: expr) => { Err(TransactionErr::PlainError(ERRL!($format))) } +} + pub mod coin_balance; #[doc(hidden)] #[cfg(test)] @@ -249,13 +259,14 @@ impl Deref for TransactionEnum { } #[derive(Debug, PartialEq)] -pub enum FailSafeTxErr { - /// Tx and Error - RpcCallFailed(Box, String), - Error(String), +pub enum TransactionErr { + /// Keeps transactions while throwing errors. + TxRecoverableError(Box, String), + /// Simply for plain error messages. + PlainError(String), } -pub type TransactionFut = Box + Send>; +pub type TransactionFut = Box + Send>; #[derive(Debug, PartialEq)] pub enum FoundSwapTxSpend { diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index a7ec8efe4b..7bbc699804 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -11,10 +11,10 @@ use crate::utxo::{qtum, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy HistoryUtxoTxMap, RecentlySpentOutPoints, UtxoActivationParams, UtxoAddressFormat, UtxoCoinFields, UtxoCommonOps, UtxoFromLegacyReqErr, UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps, VerboseTransactionFrom, UTXO_LOCK}; -use crate::{BalanceError, BalanceFut, CoinBalance, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, - MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, SwapOps, TradeFee, - TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, - TransactionEnum, TransactionFut, TransactionType, UnexpectedDerivationMethod, ValidateAddressResult, +use crate::{BalanceError, BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, + MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, SwapOps, TradeFee, TradePreimageError, + TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionEnum, + TransactionErr, TransactionFut, TransactionType, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, WithdrawResult}; use async_trait::async_trait; use bigdecimal::BigDecimal; @@ -446,7 +446,7 @@ impl Qrc20Coin { pub async fn send_contract_calls( &self, outputs: Vec, - ) -> Result { + ) -> Result { // TODO: we need to somehow refactor it using RecentlySpentOutpoints cache // Move over all QRC20 tokens should share the same cache with each other and base QTUM coin let _utxo_lock = UTXO_LOCK.lock().await; @@ -457,11 +457,11 @@ impl Qrc20Coin { .generate_qrc20_transaction(outputs) .await .mm_err(|e| e.into_withdraw_error(platform, decimals)) - .map_err(|e| FailSafeTxErr::Error(ERRL!("{}", e)))?; + .map_err(|e| TransactionErr::PlainError(ERRL!("{}", e)))?; let _tx = match self.utxo.rpc_client.send_transaction(&signed).compat().await { Ok(tx) => tx, Err(err) => { - return Err(FailSafeTxErr::RpcCallFailed( + return Err(TransactionErr::TxRecoverableError( Box::new(TransactionEnum::from(signed)), ERRL!("{:?}", err), )); @@ -720,10 +720,10 @@ impl UtxoCommonOps for Qrc20Coin { #[async_trait] impl SwapOps for Qrc20Coin { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { - let to_address = try_fstx_fus!(self.contract_address_from_raw_pubkey(fee_addr)); - let amount = try_fstx_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); + let to_address = try_tx_fus!(self.contract_address_from_raw_pubkey(fee_addr)); + let amount = try_tx_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let transfer_output = - try_fstx_fus!(self.transfer_output(to_address, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT)); + try_tx_fus!(self.transfer_output(to_address, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT)); let outputs = vec![transfer_output]; let selfi = self.clone(); @@ -741,11 +741,11 @@ impl SwapOps for Qrc20Coin { amount: BigDecimal, swap_contract_address: &Option, ) -> TransactionFut { - let taker_addr = try_fstx_fus!(self.contract_address_from_raw_pubkey(taker_pub)); + let taker_addr = try_tx_fus!(self.contract_address_from_raw_pubkey(taker_pub)); let id = qrc20_swap_id(time_lock, secret_hash); - let value = try_fstx_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); + let value = try_tx_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let secret_hash = Vec::from(secret_hash); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -765,11 +765,11 @@ impl SwapOps for Qrc20Coin { amount: BigDecimal, swap_contract_address: &Option, ) -> TransactionFut { - let maker_addr = try_fstx_fus!(self.contract_address_from_raw_pubkey(maker_pub)); + let maker_addr = try_tx_fus!(self.contract_address_from_raw_pubkey(maker_pub)); let id = qrc20_swap_id(time_lock, secret_hash); - let value = try_fstx_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); + let value = try_tx_fus!(wei_from_big_decimal(&amount, self.utxo.decimals)); let secret_hash = Vec::from(secret_hash); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -789,8 +789,8 @@ impl SwapOps for Qrc20Coin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let payment_tx: UtxoTx = try_fstx_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let payment_tx: UtxoTx = try_tx_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); let secret = secret.to_vec(); let selfi = self.clone(); @@ -811,9 +811,9 @@ impl SwapOps for Qrc20Coin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let payment_tx: UtxoTx = try_fstx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let payment_tx: UtxoTx = try_tx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); let secret = secret.to_vec(); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -833,8 +833,8 @@ impl SwapOps for Qrc20Coin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let payment_tx: UtxoTx = try_fstx_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let payment_tx: UtxoTx = try_tx_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -854,8 +854,8 @@ impl SwapOps for Qrc20Coin { _htlc_privkey: &[u8], swap_contract_address: &Option, ) -> TransactionFut { - let payment_tx: UtxoTx = try_fstx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); - let swap_contract_address = try_fstx_fus!(swap_contract_address.try_to_address()); + let payment_tx: UtxoTx = try_tx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); let selfi = self.clone(); let fut = async move { @@ -1099,13 +1099,13 @@ impl MarketCoinOps for Qrc20Coin { from_block: u64, _swap_contract_address: &Option, ) -> TransactionFut { - let tx: UtxoTx = try_fstx_fus!(deserialize(transaction).map_err(|e| ERRL!("{:?}", e))); + let tx: UtxoTx = try_tx_fus!(deserialize(transaction).map_err(|e| ERRL!("{:?}", e))); let selfi = self.clone(); let fut = async move { selfi .wait_for_tx_spend_impl(tx, wait_until, from_block) - .map_err(FailSafeTxErr::Error) + .map_err(TransactionErr::PlainError) .await }; Box::new(fut.boxed().compat()) diff --git a/mm2src/coins/qrc20/swap.rs b/mm2src/coins/qrc20/swap.rs index 3dcbf20659..1d22d513c4 100644 --- a/mm2src/coins/qrc20/swap.rs +++ b/mm2src/coins/qrc20/swap.rs @@ -37,16 +37,16 @@ impl Qrc20Coin { secret_hash: Vec, receiver_addr: H160, swap_contract_address: H160, - ) -> Result { - let balance = try_fstx_s!(self.my_spendable_balance().compat().await); - let balance = try_fstx_s!(wei_from_big_decimal(&balance, self.utxo.decimals)); + ) -> Result { + let balance = try_tx_s!(self.my_spendable_balance().compat().await); + let balance = try_tx_s!(wei_from_big_decimal(&balance, self.utxo.decimals)); // Check the balance to avoid unnecessary burning of gas if balance < value { - return FSTX_ERR!("Balance {} is less than value {}", balance, value); + return TX_ERR!("Balance {} is less than value {}", balance, value); } - let outputs = try_fstx_s!( + let outputs = try_tx_s!( self.generate_swap_payment_outputs( balance, id, @@ -67,18 +67,18 @@ impl Qrc20Coin { payment_tx: UtxoTx, swap_contract_address: H160, secret: Vec, - ) -> Result { + ) -> Result { let Erc20PaymentDetails { swap_id, value, sender, .. - } = try_fstx_s!(self.erc20_payment_details_from_tx(&payment_tx).await); + } = try_tx_s!(self.erc20_payment_details_from_tx(&payment_tx).await); - let status = try_fstx_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); + let status = try_tx_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { - return FSTX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); + return TX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); } let spend_output = - try_fstx_s!(self.receiver_spend_output(&swap_contract_address, swap_id, value, secret, sender)); + try_tx_s!(self.receiver_spend_output(&swap_contract_address, swap_id, value, secret, sender)); self.send_contract_calls(vec![spend_output]).await } @@ -86,22 +86,22 @@ impl Qrc20Coin { &self, swap_contract_address: H160, payment_tx: UtxoTx, - ) -> Result { + ) -> Result { let Erc20PaymentDetails { swap_id, value, receiver, secret_hash, .. - } = try_fstx_s!(self.erc20_payment_details_from_tx(&payment_tx).await); + } = try_tx_s!(self.erc20_payment_details_from_tx(&payment_tx).await); - let status = try_fstx_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); + let status = try_tx_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { - return FSTX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); + return TX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); } let refund_output = - try_fstx_s!(self.sender_refund_output(&swap_contract_address, swap_id, value, secret_hash, receiver)); + try_tx_s!(self.sender_refund_output(&swap_contract_address, swap_id, value, secret_hash, receiver)); self.send_contract_calls(vec![refund_output]).await } diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 2a882b0fe7..e7d3b78302 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -96,7 +96,7 @@ use crate::coin_balance::{EnableCoinScanPolicy, HDAddressBalanceScanner}; use crate::hd_wallet::{HDAccountOps, HDAccountsMutex, HDAddress, HDWalletCoinOps, HDWalletOps, InvalidBip44ChainError}; use crate::hd_wallet_storage::{HDAccountStorageItem, HDWalletCoinStorage, HDWalletStorageError, HDWalletStorageResult}; use crate::utxo::utxo_block_header_storage::BlockHeaderStorageError; -use crate::FailSafeTxErr; +use crate::TransactionErr; use utxo_block_header_storage::BlockHeaderStorage; #[cfg(not(target_arch = "wasm32"))] pub mod tx_cache; #[cfg(target_arch = "wasm32")] @@ -1458,12 +1458,15 @@ pub fn sat_from_big_decimal(amount: &BigDecimal, decimals: u8) -> NumConversResu }) } -async fn send_outputs_from_my_address_impl(coin: T, outputs: Vec) -> Result +async fn send_outputs_from_my_address_impl( + coin: T, + outputs: Vec, +) -> Result where T: AsRef + UtxoCommonOps, { - let my_address = try_fstx_s!(coin.as_ref().derivation_method.iguana_or_err()); - let (unspents, recently_sent_txs) = try_fstx_s!(coin.list_unspent_ordered(my_address).await); + let my_address = try_tx_s!(coin.as_ref().derivation_method.iguana_or_err()); + let (unspents, recently_sent_txs) = try_tx_s!(coin.list_unspent_ordered(my_address).await); generate_and_send_tx(&coin, unspents, None, FeePolicy::SendExact, recently_sent_txs, outputs).await } @@ -1475,12 +1478,12 @@ async fn generate_and_send_tx( fee_policy: FeePolicy, mut recently_spent: AsyncMutexGuard<'_, RecentlySpentOutPoints>, outputs: Vec, -) -> Result +) -> Result where T: AsRef + UtxoTxGenerationOps + UtxoTxBroadcastOps, { - let my_address = try_fstx_s!(coin.as_ref().derivation_method.iguana_or_err()); - let key_pair = try_fstx_s!(coin.as_ref().priv_key_policy.key_pair_or_err()); + let my_address = try_tx_s!(coin.as_ref().derivation_method.iguana_or_err()); + let key_pair = try_tx_s!(coin.as_ref().priv_key_policy.key_pair_or_err()); let mut builder = UtxoTxBuilder::new(coin) .add_available_inputs(unspents) @@ -1489,7 +1492,7 @@ where if let Some(required) = required_inputs { builder = builder.add_required_inputs(required); } - let (unsigned, _) = try_fstx_s!(builder.build().await); + let (unsigned, _) = try_tx_s!(builder.build().await); let spent_unspents = unsigned .inputs @@ -1507,7 +1510,7 @@ where }; let prev_script = Builder::build_p2pkh(&my_address.hash); - let signed = try_fstx_s!(sign_tx( + let signed = try_tx_s!(sign_tx( unsigned, key_pair, prev_script, @@ -1518,7 +1521,7 @@ where match coin.broadcast_tx(&signed).await { Ok(_) => (), Err(err) => { - return Err(FailSafeTxErr::RpcCallFailed( + return Err(TransactionErr::TxRecoverableError( Box::new(TransactionEnum::from(signed)), ERRL!("{:?}", err), )); diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index e60832509d..59da54bda6 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -10,10 +10,10 @@ use crate::utxo::utxo_common::{self, big_decimal_from_sat_unsigned, payment_scri use crate::utxo::{generate_and_send_tx, sat_from_big_decimal, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy, GenerateTxError, RecentlySpentOutPoints, UtxoCoinConf, UtxoCoinFields, UtxoCommonOps, UtxoTx, UtxoTxBroadcastOps, UtxoTxGenerationOps}; -use crate::{BalanceFut, CoinBalance, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, - MmCoin, NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, SwapOps, TradeFee, - TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, - TransactionEnum, TransactionFut, TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, +use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, + NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, SwapOps, TradeFee, TradePreimageError, + TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionEnum, + TransactionErr, TransactionFut, TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; use async_trait::async_trait; @@ -408,8 +408,8 @@ impl SlpToken { Ok((preimage, recently_spent)) } - pub async fn send_slp_outputs(&self, slp_outputs: Vec) -> Result { - let (preimage, recently_spent) = try_fstx_s!(self.generate_slp_tx_preimage(slp_outputs).await); + pub async fn send_slp_outputs(&self, slp_outputs: Vec) -> Result { + let (preimage, recently_spent) = try_tx_s!(self.generate_slp_tx_preimage(slp_outputs).await); generate_and_send_tx( self, preimage.available_bch_inputs, @@ -428,11 +428,11 @@ impl SlpToken { time_lock: u32, secret_hash: &[u8], amount: u64, - ) -> Result { + ) -> Result { let payment_script = payment_script(time_lock, secret_hash, my_pub, other_pub); let script_pubkey = ScriptBuilder::build_p2sh(&dhash160(&payment_script).into()).to_bytes(); let slp_out = SlpOutput { amount, script_pubkey }; - let (preimage, recently_spent) = try_fstx_s!(self.generate_slp_tx_preimage(vec![slp_out]).await); + let (preimage, recently_spent) = try_tx_s!(self.generate_slp_tx_preimage(vec![slp_out]).await); generate_and_send_tx( self, preimage.available_bch_inputs, @@ -1152,13 +1152,13 @@ impl MarketCoinOps for SlpToken { impl SwapOps for SlpToken { fn send_taker_fee(&self, fee_addr: &[u8], amount: BigDecimal, _uuid: &[u8]) -> TransactionFut { let coin = self.clone(); - let fee_pubkey = try_fstx_fus!(Public::from_slice(fee_addr)); + let fee_pubkey = try_tx_fus!(Public::from_slice(fee_addr)); let script_pubkey = ScriptBuilder::build_p2pkh(&fee_pubkey.address_hash().into()).into(); - let amount = try_fstx_fus!(sat_from_big_decimal(&amount, self.decimals())); + let amount = try_tx_fus!(sat_from_big_decimal(&amount, self.decimals())); let fut = async move { let slp_out = SlpOutput { amount, script_pubkey }; - let (preimage, recently_spent) = try_fstx_s!(coin.generate_slp_tx_preimage(vec![slp_out]).await); + let (preimage, recently_spent) = try_tx_s!(coin.generate_slp_tx_preimage(vec![slp_out]).await); generate_and_send_tx( &coin, preimage.available_bch_inputs, @@ -1181,14 +1181,14 @@ impl SwapOps for SlpToken { amount: BigDecimal, _swap_contract_address: &Option, ) -> TransactionFut { - let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); - let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); - let amount = try_fstx_fus!(sat_from_big_decimal(&amount, self.decimals())); + let maker_pub = try_tx_fus!(Public::from_slice(maker_pub)); + let taker_pub = try_tx_fus!(Public::from_slice(taker_pub)); + let amount = try_tx_fus!(sat_from_big_decimal(&amount, self.decimals())); let secret_hash = secret_hash.to_owned(); let coin = self.clone(); let fut = async move { - let tx = try_fstx_s!( + let tx = try_tx_s!( coin.send_htlc(&maker_pub, &taker_pub, time_lock, &secret_hash, amount) .await ); @@ -1206,14 +1206,14 @@ impl SwapOps for SlpToken { amount: BigDecimal, _swap_contract_address: &Option, ) -> TransactionFut { - let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); - let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); - let amount = try_fstx_fus!(sat_from_big_decimal(&amount, self.decimals())); + let taker_pub = try_tx_fus!(Public::from_slice(taker_pub)); + let maker_pub = try_tx_fus!(Public::from_slice(maker_pub)); + let amount = try_tx_fus!(sat_from_big_decimal(&amount, self.decimals())); let secret_hash = secret_hash.to_owned(); let coin = self.clone(); let fut = async move { - let tx = try_fstx_s!( + let tx = try_tx_s!( coin.send_htlc(&taker_pub, &maker_pub, time_lock, &secret_hash, amount) .await ); @@ -1232,13 +1232,13 @@ impl SwapOps for SlpToken { _swap_contract_address: &Option, ) -> TransactionFut { let tx = taker_payment_tx.to_owned(); - let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); + let taker_pub = try_tx_fus!(Public::from_slice(taker_pub)); let secret = secret.to_owned(); - let htlc_keypair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let htlc_keypair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { - let tx = try_fstx_s!( + let tx = try_tx_s!( coin.spend_htlc(&tx, &taker_pub, time_lock, &secret, &htlc_keypair) .await ); @@ -1257,13 +1257,13 @@ impl SwapOps for SlpToken { _swap_contract_address: &Option, ) -> TransactionFut { let tx = maker_payment_tx.to_owned(); - let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); + let maker_pub = try_tx_fus!(Public::from_slice(maker_pub)); let secret = secret.to_owned(); - let htlc_keypair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let htlc_keypair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { - let tx = try_fstx_s!( + let tx = try_tx_s!( coin.spend_htlc(&tx, &maker_pub, time_lock, &secret, &htlc_keypair) .await ); @@ -1282,9 +1282,9 @@ impl SwapOps for SlpToken { _swap_contract_address: &Option, ) -> TransactionFut { let tx = taker_payment_tx.to_owned(); - let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); + let maker_pub = try_tx_fus!(Public::from_slice(maker_pub)); let secret_hash = secret_hash.to_owned(); - let keypair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let keypair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { @@ -1294,7 +1294,7 @@ impl SwapOps for SlpToken { ); Ok(tx.into()) }; - Box::new(fut.boxed().compat().map_err(FailSafeTxErr::Error)) + Box::new(fut.boxed().compat().map_err(TransactionErr::PlainError)) } fn send_maker_refunds_payment( @@ -1307,13 +1307,13 @@ impl SwapOps for SlpToken { _swap_contract_address: &Option, ) -> TransactionFut { let tx = maker_payment_tx.to_owned(); - let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); + let taker_pub = try_tx_fus!(Public::from_slice(taker_pub)); let secret_hash = secret_hash.to_owned(); - let keypair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let keypair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); let coin = self.clone(); let fut = async move { - let tx = try_fstx_s!( + let tx = try_tx_s!( coin.refund_htlc(&tx, &taker_pub, time_lock, &secret_hash, &keypair) .await ); @@ -2012,8 +2012,8 @@ mod slp_tests { .unwrap_err(); let err = match tx_err { - FailSafeTxErr::RpcCallFailed(_tx, err) => err, - FailSafeTxErr::Error(err) => err, + TransactionErr::TxRecoverableError(_tx, err) => err, + TransactionErr::PlainError(err) => err, }; println!("{:?}", err); diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 96597e2ebd..8a03997a36 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -8,8 +8,8 @@ use crate::init_withdraw::WithdrawTaskHandle; use crate::utxo::rpc_clients::{electrum_script_hash, BlockHashOrHeight, UnspentInfo, UtxoRpcClientEnum, UtxoRpcClientOps, UtxoRpcResult}; use crate::utxo::utxo_withdraw::{InitUtxoWithdraw, StandardUtxoWithdraw, UtxoWithdraw}; -use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, FailSafeTxErr, GetWithdrawSenderAddress, - HDAddressId, TradePreimageValue, TransactionFut, TxFeeDetails, ValidateAddressResult, +use crate::{CanRefundHtlc, CoinBalance, CoinWithDerivationMethod, GetWithdrawSenderAddress, HDAddressId, + TradePreimageValue, TransactionErr, TransactionFut, TxFeeDetails, ValidateAddressResult, ValidatePaymentInput, WithdrawFrom, WithdrawResult, WithdrawSenderAddress}; use bigdecimal::{BigDecimal, Zero}; pub use bitcrypto::{dhash160, sha256, ChecksumType}; @@ -1018,7 +1018,7 @@ pub fn send_taker_fee(coin: T, fee_pub_key: &[u8], amount: BigDecimal) -> Tra where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let address = try_fstx_fus!(address_from_raw_pubkey( + let address = try_tx_fus!(address_from_raw_pubkey( fee_pub_key, coin.as_ref().conf.pub_addr_prefix, coin.as_ref().conf.pub_t_addr_prefix, @@ -1026,7 +1026,7 @@ where coin.as_ref().conf.bech32_hrp.clone(), coin.addr_format().clone(), )); - let amount = try_fstx_fus!(sat_from_big_decimal(&amount, coin.as_ref().decimals)); + let amount = try_tx_fus!(sat_from_big_decimal(&amount, coin.as_ref().decimals)); let output = TransactionOutput { value: amount, script_pubkey: Builder::build_p2pkh(&address.hash).to_bytes(), @@ -1048,7 +1048,7 @@ where let SwapPaymentOutputsResult { payment_address, outputs, - } = try_fstx_fus!(generate_swap_payment_outputs( + } = try_tx_fus!(generate_swap_payment_outputs( &coin, time_lock, maker_pub, @@ -1059,11 +1059,11 @@ where let send_fut = match &coin.as_ref().rpc_client { UtxoRpcClientEnum::Electrum(_) => Either::A(send_outputs_from_my_address(coin, outputs)), UtxoRpcClientEnum::Native(client) => { - let addr_string = try_fstx_fus!(payment_address.display_address()); + let addr_string = try_tx_fus!(payment_address.display_address()); Either::B( client .import_address(&addr_string, &addr_string, false) - .map_err(|e| FailSafeTxErr::Error(ERRL!("{}", e))) + .map_err(|e| TransactionErr::PlainError(ERRL!("{}", e))) .and_then(move |_| send_outputs_from_my_address(coin, outputs)), ) }, @@ -1085,7 +1085,7 @@ where let SwapPaymentOutputsResult { payment_address, outputs, - } = try_fstx_fus!(generate_swap_payment_outputs( + } = try_tx_fus!(generate_swap_payment_outputs( &coin, time_lock, taker_pub, @@ -1097,11 +1097,11 @@ where let send_fut = match &coin.as_ref().rpc_client { UtxoRpcClientEnum::Electrum(_) => Either::A(send_outputs_from_my_address(coin, outputs)), UtxoRpcClientEnum::Native(client) => { - let addr_string = try_fstx_fus!(payment_address.display_address()); + let addr_string = try_tx_fus!(payment_address.display_address()); Either::B( client .import_address(&addr_string, &addr_string, false) - .map_err(|e| FailSafeTxErr::Error(ERRL!("{}", e))) + .map_err(|e| TransactionErr::PlainError(ERRL!("{}", e))) .and_then(move |_| send_outputs_from_my_address(coin, outputs)), ) }, @@ -1120,10 +1120,10 @@ pub fn send_maker_spends_taker_payment( where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fstx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_tx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fstx_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = try_tx_fus!(deserialize(taker_payment_tx).map_err(|e| ERRL!("{:?}", e))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default() .push_data(secret) @@ -1132,11 +1132,11 @@ where let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fstx_fus!(Public::from_slice(taker_pub)), + &try_tx_fus!(Public::from_slice(taker_pub)), key_pair.public(), ); let fut = async move { - let fee = try_fstx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = try_tx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, @@ -1156,14 +1156,14 @@ where .await { Ok(tx) => tx, - Err(err) => return FSTX_ERR!("{:?}", err), + Err(err) => return TX_ERR!("{:?}", err), }; let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { Ok(_) => (), Err(err) => { - return Err(FailSafeTxErr::RpcCallFailed( + return Err(TransactionErr::TxRecoverableError( Box::new(TransactionEnum::from(transaction)), ERRL!("{:?}", err), )); @@ -1185,10 +1185,10 @@ pub fn send_taker_spends_maker_payment( where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fstx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_tx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fstx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = try_tx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default() .push_data(secret) @@ -1197,11 +1197,11 @@ where let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fstx_fus!(Public::from_slice(maker_pub)), + &try_tx_fus!(Public::from_slice(maker_pub)), key_pair.public(), ); let fut = async move { - let fee = try_fstx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = try_tx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, @@ -1220,14 +1220,14 @@ where .await { Ok(tx) => tx, - Err(err) => return FSTX_ERR!("{:?}", err), + Err(err) => return TX_ERR!("{:?}", err), }; let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { Ok(_) => (), Err(err) => { - return Err(FailSafeTxErr::RpcCallFailed( + return Err(TransactionErr::TxRecoverableError( Box::new(TransactionEnum::from(transaction)), ERRL!("{:?}", err), )); @@ -1249,23 +1249,23 @@ pub fn send_taker_refunds_payment( where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fstx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_tx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); let mut prev_tx: UtxoTx = - try_fstx_fus!(deserialize(taker_payment_tx).map_err(|e| FailSafeTxErr::Error(format!("{:?}", e)))); + try_tx_fus!(deserialize(taker_payment_tx).map_err(|e| TransactionErr::PlainError(format!("{:?}", e)))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default().push_opcode(Opcode::OP_1).into_script(); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fstx_fus!(Public::from_slice(maker_pub)), + &try_tx_fus!(Public::from_slice(maker_pub)), ); let fut = async move { let fee = match coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await { Ok(f) => f, - Err(err) => return FSTX_ERR!("{:?}", err), + Err(err) => return TX_ERR!("{:?}", err), }; let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); @@ -1286,14 +1286,14 @@ where .await { Ok(tx) => tx, - Err(err) => return FSTX_ERR!("{:?}", err), + Err(err) => return TX_ERR!("{:?}", err), }; let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { Ok(_) => (), Err(err) => { - return Err(FailSafeTxErr::RpcCallFailed( + return Err(TransactionErr::TxRecoverableError( Box::new(TransactionEnum::from(transaction)), ERRL!("{:?}", err), )); @@ -1316,20 +1316,20 @@ pub fn send_maker_refunds_payment( where T: AsRef + UtxoCommonOps + Send + Sync + 'static, { - let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); - let my_address = try_fstx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); + let key_pair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); + let my_address = try_tx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); - let mut prev_tx: UtxoTx = try_fstx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); + let mut prev_tx: UtxoTx = try_tx_fus!(deserialize(maker_payment_tx).map_err(|e| ERRL!("{:?}", e))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default().push_opcode(Opcode::OP_1).into_script(); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fstx_fus!(Public::from_slice(taker_pub)), + &try_tx_fus!(Public::from_slice(taker_pub)), ); let fut = async move { - let fee = try_fstx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); + let fee = try_tx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, @@ -1348,7 +1348,7 @@ where .await { Ok(tx) => tx, - Err(err) => return FSTX_ERR!("{:?}", err), + Err(err) => return TX_ERR!("{:?}", err), }; let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); @@ -1356,7 +1356,7 @@ where match tx_fut.await { Ok(_) => (), Err(err) => { - return Err(FailSafeTxErr::RpcCallFailed( + return Err(TransactionErr::TxRecoverableError( Box::new(TransactionEnum::from(transaction)), ERRL!("{:?}", err), )); @@ -1794,7 +1794,7 @@ pub fn wait_for_output_spend( from_block: u64, wait_until: u64, ) -> TransactionFut { - let mut tx: UtxoTx = try_fstx_fus!(deserialize(tx_bytes).map_err(|e| ERRL!("{:?}", e))); + let mut tx: UtxoTx = try_tx_fus!(deserialize(tx_bytes).map_err(|e| ERRL!("{:?}", e))); tx.tx_hash_algo = coin.tx_hash_algo; let client = coin.rpc_client.clone(); let tx_hash_algo = coin.tx_hash_algo; @@ -1822,7 +1822,7 @@ pub fn wait_for_output_spend( }; if now_ms() / 1000 > wait_until { - return FSTX_ERR!( + return TX_ERR!( "Waited too long until {} for transaction {:?} {} to be spent ", wait_until, tx, diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index 831856f196..c120e84f51 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -7,11 +7,10 @@ use crate::utxo::{sat_from_big_decimal, utxo_common, ActualTxFee, AdditionalTxDa FeePolicy, HistoryUtxoTx, HistoryUtxoTxMap, RecentlySpentOutPoints, UtxoActivationParams, UtxoAddressFormat, UtxoArc, UtxoCoinFields, UtxoCommonOps, UtxoFeeDetails, UtxoTxBroadcastOps, UtxoTxGenerationOps, UtxoWeak, VerboseTransactionFrom}; -use crate::{BalanceFut, CoinBalance, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, - MmCoin, NegotiateSwapContractAddrErr, NumConversError, SwapOps, TradeFee, TradePreimageFut, - TradePreimageResult, TradePreimageValue, TransactionDetails, TransactionEnum, TransactionFut, - TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, - WithdrawRequest}; +use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, + NegotiateSwapContractAddrErr, NumConversError, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, + TradePreimageValue, TransactionDetails, TransactionEnum, TransactionErr, TransactionFut, TxFeeDetails, + UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawRequest}; use crate::{Transaction, WithdrawError}; use async_trait::async_trait; use bitcrypto::dhash160; @@ -795,7 +794,7 @@ impl SwapOps for ZCoin { let selfi = self.clone(); let uuid = uuid.to_owned(); let fut = async move { - let tx = try_fstx_s!(z_send_dex_fee(&selfi, amount, &uuid).await); + let tx = try_tx_s!(z_send_dex_fee(&selfi, amount, &uuid).await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -811,12 +810,11 @@ impl SwapOps for ZCoin { _swap_contract_address: &Option, ) -> TransactionFut { let selfi = self.clone(); - let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); - let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); + let maker_pub = try_tx_fus!(Public::from_slice(maker_pub)); + let taker_pub = try_tx_fus!(Public::from_slice(taker_pub)); let secret_hash = secret_hash.to_vec(); let fut = async move { - let utxo_tx = - try_fstx_s!(z_send_htlc(&selfi, time_lock, &maker_pub, &taker_pub, &secret_hash, amount).await); + let utxo_tx = try_tx_s!(z_send_htlc(&selfi, time_lock, &maker_pub, &taker_pub, &secret_hash, amount).await); Ok(utxo_tx.into()) }; Box::new(fut.boxed().compat()) @@ -832,12 +830,11 @@ impl SwapOps for ZCoin { _swap_contract_address: &Option, ) -> TransactionFut { let selfi = self.clone(); - let taker_pub = try_fstx_fus!(Public::from_slice(taker_pub)); - let maker_pub = try_fstx_fus!(Public::from_slice(maker_pub)); + let taker_pub = try_tx_fus!(Public::from_slice(taker_pub)); + let maker_pub = try_tx_fus!(Public::from_slice(maker_pub)); let secret_hash = secret_hash.to_vec(); let fut = async move { - let utxo_tx = - try_fstx_s!(z_send_htlc(&selfi, time_lock, &taker_pub, &maker_pub, &secret_hash, amount).await); + let utxo_tx = try_tx_s!(z_send_htlc(&selfi, time_lock, &taker_pub, &maker_pub, &secret_hash, amount).await); Ok(utxo_tx.into()) }; Box::new(fut.boxed().compat()) @@ -852,12 +849,12 @@ impl SwapOps for ZCoin { htlc_privkey: &[u8], _swap_contract_address: &Option, ) -> TransactionFut { - let tx = try_fstx_fus!(ZTransaction::read(taker_payment_tx)); - let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let tx = try_tx_fus!(ZTransaction::read(taker_payment_tx)); + let key_pair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fstx_fus!(Public::from_slice(taker_pub)), + &try_tx_fus!(Public::from_slice(taker_pub)), key_pair.public(), ); let script_data = ScriptBuilder::default() @@ -875,7 +872,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_fstx_s!(tx_fut.await); + let tx = try_tx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -890,12 +887,12 @@ impl SwapOps for ZCoin { htlc_privkey: &[u8], _swap_contract_address: &Option, ) -> TransactionFut { - let tx = try_fstx_fus!(ZTransaction::read(maker_payment_tx)); - let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let tx = try_tx_fus!(ZTransaction::read(maker_payment_tx)); + let key_pair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, &*dhash160(secret), - &try_fstx_fus!(Public::from_slice(maker_pub)), + &try_tx_fus!(Public::from_slice(maker_pub)), key_pair.public(), ); let script_data = ScriptBuilder::default() @@ -913,7 +910,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_fstx_s!(tx_fut.await); + let tx = try_tx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -928,13 +925,13 @@ impl SwapOps for ZCoin { htlc_privkey: &[u8], _swap_contract_address: &Option, ) -> TransactionFut { - let tx = try_fstx_fus!(ZTransaction::read(taker_payment_tx)); - let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let tx = try_tx_fus!(ZTransaction::read(taker_payment_tx)); + let key_pair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fstx_fus!(Public::from_slice(maker_pub)), + &try_tx_fus!(Public::from_slice(maker_pub)), ); let script_data = ScriptBuilder::default().push_opcode(Opcode::OP_1).into_script(); let selfi = self.clone(); @@ -948,7 +945,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_fstx_s!(tx_fut.await); + let tx = try_tx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -963,13 +960,13 @@ impl SwapOps for ZCoin { htlc_privkey: &[u8], _swap_contract_address: &Option, ) -> TransactionFut { - let tx = try_fstx_fus!(ZTransaction::read(maker_payment_tx)); - let key_pair = try_fstx_fus!(key_pair_from_secret(htlc_privkey)); + let tx = try_tx_fus!(ZTransaction::read(maker_payment_tx)); + let key_pair = try_tx_fus!(key_pair_from_secret(htlc_privkey)); let redeem_script = payment_script( time_lock, secret_hash, key_pair.public(), - &try_fstx_fus!(Public::from_slice(taker_pub)), + &try_tx_fus!(Public::from_slice(taker_pub)), ); let script_data = ScriptBuilder::default().push_opcode(Opcode::OP_1).into_script(); let selfi = self.clone(); @@ -983,7 +980,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_fstx_s!(tx_fut.await); + let tx = try_tx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) diff --git a/mm2src/docker_tests/qrc20_tests.rs b/mm2src/docker_tests/qrc20_tests.rs index 47ca4d7a0e..e854cd7043 100644 --- a/mm2src/docker_tests/qrc20_tests.rs +++ b/mm2src/docker_tests/qrc20_tests.rs @@ -7,8 +7,8 @@ use coins::utxo::qtum::{qtum_coin_with_priv_key, QtumCoin}; use coins::utxo::rpc_clients::UtxoRpcClientEnum; use coins::utxo::utxo_common::big_decimal_from_sat; use coins::utxo::{UtxoActivationParams, UtxoCommonOps}; -use coins::{FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, MarketCoinOps, MmCoin, SwapOps, TradePreimageValue, - TransactionEnum, ValidatePaymentInput}; +use coins::{FeeApproxStage, FoundSwapTxSpend, MarketCoinOps, MmCoin, SwapOps, TradePreimageValue, TransactionEnum, + TransactionErr, ValidatePaymentInput}; use common::log::debug; use common::mm_ctx::{MmArc, MmCtxBuilder}; use common::{temp_dir, DEX_FEE_ADDR_RAW_PUBKEY}; @@ -738,8 +738,8 @@ fn test_wait_for_tx_spend() { .expect_err("Expected 'Waited too long' error"); let err = match tx_err { - FailSafeTxErr::RpcCallFailed(_tx, err) => err, - FailSafeTxErr::Error(err) => err, + TransactionErr::TxRecoverableError(_tx, err) => err, + TransactionErr::PlainError(err) => err, }; log!("error: "[err]); assert!(err.contains("Waited too long")); diff --git a/mm2src/lp_swap.rs b/mm2src/lp_swap.rs index 336700ff6f..57c0faaad6 100644 --- a/mm2src/lp_swap.rs +++ b/mm2src/lp_swap.rs @@ -190,13 +190,14 @@ pub fn broadcast_swap_message(ctx: &MmArc, topic: String, msg: SwapMsg, p2p_priv broadcast_p2p_msg(ctx, vec![topic], encoded_msg); } -pub fn broadcast_p2p_tx_helper(ctx: &MmArc, topic: String, msg: Vec, p2p_privkey: &Option) { +/// Broadcast the tx message once +pub fn broadcast_p2p_tx_msg(ctx: &MmArc, topic: String, msg: &TransactionEnum, p2p_privkey: &Option) { let p2p_private = match p2p_privkey { Some(privkey) => privkey.0, None => ctx.secp256k1_key_pair.or(&&|| panic!()).private().secret.take(), }; - let encoded_msg = encode_and_sign(&msg, &p2p_private).unwrap(); + let encoded_msg = encode_and_sign(&msg.tx_hex(), &p2p_private).unwrap(); broadcast_p2p_msg(ctx, vec![topic], encoded_msg); } diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index 60a4cbf77e..78db604c15 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -11,12 +11,12 @@ use super::{broadcast_my_swap_status, broadcast_swap_message_every, check_other_ use crate::mm2::lp_dispatcher::{DispatcherContext, LpEvents}; use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{MakerOrderBuilder, OrderConfirmationsSettings}; -use crate::mm2::lp_swap::{broadcast_p2p_tx_helper, tx_helper_topic}; +use crate::mm2::lp_swap::{broadcast_p2p_tx_msg, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use bitcrypto::dhash160; -use coins::{CanRefundHtlc, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, - TransactionEnum, ValidatePaymentInput}; +use coins::{CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, + TransactionEnum, TransactionErr, ValidatePaymentInput}; use common::log::{debug, error, warn}; use common::mm_error::prelude::*; use common::privkey::key_pair_from_secret; @@ -668,11 +668,11 @@ impl MakerSwap { match payment_fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); @@ -680,7 +680,7 @@ impl MakerSwap { MakerSwapEvent::MakerPaymentTransactionFailed(ERRL!("{}", err).into()), ])); }, - FailSafeTxErr::Error(err) => { + TransactionErr::PlainError(err) => { return Ok((Some(MakerSwapCommand::Finish), vec![ MakerSwapEvent::MakerPaymentTransactionFailed(ERRL!("{}", err).into()), ])) @@ -858,11 +858,11 @@ impl MakerSwap { let transaction = match spend_fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); @@ -875,7 +875,7 @@ impl MakerSwap { }, ])); }, - FailSafeTxErr::Error(err) => { + TransactionErr::PlainError(err) => { return Ok((Some(MakerSwapCommand::RefundMakerPayment), vec![ MakerSwapEvent::TakerPaymentSpendFailed( ERRL!("!taker_coin.send_maker_spends_taker_payment: {}", err).into(), @@ -888,10 +888,10 @@ impl MakerSwap { }, }; - broadcast_p2p_tx_helper( + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - transaction.tx_hex(), + &transaction, &self.p2p_privkey, ); @@ -960,11 +960,11 @@ impl MakerSwap { let transaction = match spend_fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); @@ -974,7 +974,7 @@ impl MakerSwap { ), ])); }, - FailSafeTxErr::Error(err) => { + TransactionErr::PlainError(err) => { return Ok((Some(MakerSwapCommand::Finish), vec![ MakerSwapEvent::MakerPaymentRefundFailed( ERRL!("!maker_coin.send_maker_refunds_payment: {}", err).into(), @@ -984,10 +984,10 @@ impl MakerSwap { }, }; - broadcast_p2p_tx_helper( + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - transaction.tx_hex(), + &transaction, &self.p2p_privkey, ); @@ -1231,32 +1231,29 @@ impl MakerSwap { self.r().data.maker_payment_lock + 3700 ); } - let transaction = match self - .maker_coin - .send_maker_refunds_payment( - &maker_payment, - maker_payment_lock, - other_maker_coin_htlc_pub.as_slice(), - &secret_hash.0, - maker_coin_htlc_keypair.private().secret.as_slice(), - &maker_coin_swap_contract_address, - ) - .compat() - .await - { + let fut = self.maker_coin.send_maker_refunds_payment( + &maker_payment, + maker_payment_lock, + other_maker_coin_htlc_pub.as_slice(), + &secret_hash.0, + maker_coin_htlc_keypair.private().secret.as_slice(), + &maker_coin_swap_contract_address, + ); + + let transaction = match fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); return ERR!("{}", err); }, - FailSafeTxErr::Error(err) => return ERR!("{}", err), + TransactionErr::PlainError(err) => return ERR!("{}", err), }, }; diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index 798538d156..ec90aa9dc3 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -10,11 +10,11 @@ use super::{broadcast_my_swap_status, broadcast_swap_message_every, check_other_ SwapConfirmationsSettings, SwapError, SwapMsg, SwapsContext, TransactionIdentifier, WAIT_CONFIRM_INTERVAL}; use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{MatchBy, OrderConfirmationsSettings, TakerAction, TakerOrderBuilder}; -use crate::mm2::lp_swap::{broadcast_p2p_tx_helper, tx_helper_topic}; +use crate::mm2::lp_swap::{broadcast_p2p_tx_msg, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; -use coins::{lp_coinfind, CanRefundHtlc, FailSafeTxErr, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, - TradePreimageValue, ValidatePaymentInput}; +use coins::{lp_coinfind, CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, + TransactionErr, ValidatePaymentInput}; use common::executor::Timer; use common::log::{debug, error, warn}; use common::mm_ctx::MmArc; @@ -1025,11 +1025,11 @@ impl TakerSwap { let transaction = match fee_tx { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); @@ -1037,7 +1037,7 @@ impl TakerSwap { TakerSwapEvent::TakerFeeSendFailed(ERRL!("{}", err).into()), ])); }, - FailSafeTxErr::Error(err) => { + TransactionErr::PlainError(err) => { return Ok((Some(TakerSwapCommand::Finish), vec![ TakerSwapEvent::TakerFeeSendFailed(ERRL!("{}", err).into()), ])) @@ -1185,11 +1185,11 @@ impl TakerSwap { match payment_fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); @@ -1197,7 +1197,7 @@ impl TakerSwap { TakerSwapEvent::TakerPaymentTransactionFailed(ERRL!("{}", err).into()), ])); }, - FailSafeTxErr::Error(err) => { + TransactionErr::PlainError(err) => { return Ok((Some(TakerSwapCommand::Finish), vec![ TakerSwapEvent::TakerPaymentTransactionFailed(ERRL!("{}", err).into()), ])) @@ -1263,11 +1263,11 @@ impl TakerSwap { let tx = match f.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); @@ -1278,7 +1278,7 @@ impl TakerSwap { }, ])); }, - FailSafeTxErr::Error(err) => { + TransactionErr::PlainError(err) => { return Ok((Some(TakerSwapCommand::RefundTakerPayment), vec![ TakerSwapEvent::TakerPaymentWaitForSpendFailed(err.into()), TakerSwapEvent::TakerPaymentWaitRefundStarted { @@ -1327,11 +1327,11 @@ impl TakerSwap { let transaction = match spend_fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); @@ -1339,7 +1339,7 @@ impl TakerSwap { TakerSwapEvent::MakerPaymentSpendFailed(ERRL!("{}", err).into()), ])); }, - FailSafeTxErr::Error(err) => { + TransactionErr::PlainError(err) => { return Ok((Some(TakerSwapCommand::Finish), vec![ TakerSwapEvent::MakerPaymentSpendFailed(ERRL!("{}", err).into()), ])) @@ -1347,10 +1347,10 @@ impl TakerSwap { }, }; - broadcast_p2p_tx_helper( + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - transaction.tx_hex(), + &transaction, &self.p2p_privkey, ); @@ -1391,11 +1391,11 @@ impl TakerSwap { let transaction = match refund_fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); @@ -1403,7 +1403,7 @@ impl TakerSwap { TakerSwapEvent::TakerPaymentRefundFailed(ERRL!("{:?}", err).into()), ])); }, - FailSafeTxErr::Error(err) => { + TransactionErr::PlainError(err) => { return Ok((Some(TakerSwapCommand::Finish), vec![ TakerSwapEvent::TakerPaymentRefundFailed(ERRL!("{:?}", err).into()), ])); @@ -1411,10 +1411,10 @@ impl TakerSwap { }, }; - broadcast_p2p_tx_helper( + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - transaction.tx_hex(), + &transaction, &self.p2p_privkey, ); @@ -1605,32 +1605,29 @@ impl TakerSwap { let secret = self.r().secret.0; let maker_coin_swap_contract_address = self.r().data.maker_coin_swap_contract_address.clone(); - let transaction = match self - .maker_coin - .send_taker_spends_maker_payment( - &maker_payment, - self.maker_payment_lock.load(Ordering::Relaxed) as u32, - other_maker_coin_htlc_pub.as_slice(), - &secret, - maker_coin_htlc_keypair.private().secret.as_slice(), - &maker_coin_swap_contract_address, - ) - .compat() - .await - { + let fut = self.maker_coin.send_taker_spends_maker_payment( + &maker_payment, + self.maker_payment_lock.load(Ordering::Relaxed) as u32, + other_maker_coin_htlc_pub.as_slice(), + &secret, + maker_coin_htlc_keypair.private().secret.as_slice(), + &maker_coin_swap_contract_address, + ); + + let transaction = match fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); return ERR!("{}", err); }, - FailSafeTxErr::Error(err) => return ERR!("{}", err), + TransactionErr::PlainError(err) => return ERR!("{}", err), }, }; @@ -1659,32 +1656,30 @@ impl TakerSwap { FoundSwapTxSpend::Spent(tx) => { check_maker_payment_is_not_spent!(); let secret = try_s!(self.taker_coin.extract_secret(&self.r().secret_hash.0, &tx.tx_hex())); - let transaction = match self - .maker_coin - .send_taker_spends_maker_payment( - &maker_payment, - self.maker_payment_lock.load(Ordering::Relaxed) as u32, - other_maker_coin_htlc_pub.as_slice(), - &secret, - maker_coin_htlc_keypair.private().secret.as_slice(), - &maker_coin_swap_contract_address, - ) - .compat() - .await - { + + let fut = self.maker_coin.send_taker_spends_maker_payment( + &maker_payment, + self.maker_payment_lock.load(Ordering::Relaxed) as u32, + other_maker_coin_htlc_pub.as_slice(), + &secret, + maker_coin_htlc_keypair.private().secret.as_slice(), + &maker_coin_swap_contract_address, + ); + + let transaction = match fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); return ERR!("{}", err); }, - FailSafeTxErr::Error(err) => return ERR!("{}", err), + TransactionErr::PlainError(err) => return ERR!("{}", err), }, }; @@ -1719,17 +1714,17 @@ impl TakerSwap { let transaction = match fut.compat().await { Ok(t) => t, Err(err_enum) => match err_enum { - FailSafeTxErr::RpcCallFailed(tx, err) => { - broadcast_p2p_tx_helper( + TransactionErr::TxRecoverableError(tx, err) => { + broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), - tx.tx_hex(), + &tx, &self.p2p_privkey, ); return ERR!("{:?}", err); }, - FailSafeTxErr::Error(err) => return ERR!("{:?}", err), + TransactionErr::PlainError(err) => return ERR!("{:?}", err), }, }; From d2cbe7b590bfdc5c90fde56500a32294577fe42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Thu, 14 Apr 2022 02:18:24 +0300 Subject: [PATCH 30/48] doc comment `send_raw_tx_bytes` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/lp_coins.rs | 1 + mm2src/coins/utxo/utxo_common.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 16111d2c96..043f493ad9 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -463,6 +463,7 @@ pub trait MarketCoinOps { /// Receives raw transaction bytes in hexadecimal format as input and returns tx hash in hexadecimal format fn send_raw_tx(&self, tx: &str) -> Box + Send>; + /// Receives raw transaction bytes as input and returns tx hash in hexadecimal format fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send>; fn wait_for_confirmations( diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 8a03997a36..5e30cf836d 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1754,6 +1754,7 @@ where Box::new(fut.boxed().compat()) } +/// Receives raw transaction bytes as input and returns tx hash in hexadecimal format pub fn send_raw_tx>( coin: &UtxoCoinFields, tx: T, From 65349131e5f9019ec6df0e3a8305be7d02f12bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Thu, 14 Apr 2022 02:37:06 +0300 Subject: [PATCH 31/48] optimize `mm2src/coins/utxo/utxo_common.rs` diffs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/utxo/utxo_common.rs | 54 +++++++++++++------------------- 1 file changed, 21 insertions(+), 33 deletions(-) diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 5e30cf836d..7874a547d7 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1143,8 +1143,8 @@ where script_pubkey, }; - let transaction = match coin - .p2sh_spending_tx( + let transaction = try_tx_s!( + coin.p2sh_spending_tx( prev_tx, redeem_script.into(), vec![output], @@ -1154,10 +1154,7 @@ where &key_pair, ) .await - { - Ok(tx) => tx, - Err(err) => return TX_ERR!("{:?}", err), - }; + ); let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { @@ -1169,6 +1166,7 @@ where )); }, }; + Ok(transaction.into()) }; Box::new(fut.boxed().compat()) @@ -1207,8 +1205,9 @@ where value: prev_tx.outputs[0].value - fee, script_pubkey, }; - let transaction = match coin - .p2sh_spending_tx( + + let transaction = try_tx_s!( + coin.p2sh_spending_tx( prev_tx, redeem_script.into(), vec![output], @@ -1218,10 +1217,7 @@ where &key_pair, ) .await - { - Ok(tx) => tx, - Err(err) => return TX_ERR!("{:?}", err), - }; + ); let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { @@ -1233,6 +1229,7 @@ where )); }, }; + Ok(transaction.into()) }; Box::new(fut.boxed().compat()) @@ -1263,18 +1260,15 @@ where &try_tx_fus!(Public::from_slice(maker_pub)), ); let fut = async move { - let fee = match coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await { - Ok(f) => f, - Err(err) => return TX_ERR!("{:?}", err), - }; - + let fee = try_tx_s!(coin.get_htlc_spend_fee(DEFAULT_SWAP_TX_SPEND_SIZE).await); let script_pubkey = output_script(&my_address, ScriptType::P2PKH).to_bytes(); let output = TransactionOutput { value: prev_tx.outputs[0].value - fee, script_pubkey, }; - let transaction = match coin - .p2sh_spending_tx( + + let transaction = try_tx_s!( + coin.p2sh_spending_tx( prev_tx, redeem_script.into(), vec![output], @@ -1284,12 +1278,9 @@ where &key_pair, ) .await - { - Ok(tx) => tx, - Err(err) => return TX_ERR!("{:?}", err), - }; - let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); + ); + let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { Ok(_) => (), Err(err) => { @@ -1298,7 +1289,7 @@ where ERRL!("{:?}", err), )); }, - } + }; Ok(transaction.into()) }; @@ -1335,8 +1326,9 @@ where value: prev_tx.outputs[0].value - fee, script_pubkey, }; - let transaction = match coin - .p2sh_spending_tx( + + let transaction = try_tx_s!( + coin.p2sh_spending_tx( prev_tx, redeem_script.into(), vec![output], @@ -1346,13 +1338,9 @@ where &key_pair, ) .await - { - Ok(tx) => tx, - Err(err) => return TX_ERR!("{:?}", err), - }; + ); let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); - match tx_fut.await { Ok(_) => (), Err(err) => { @@ -1361,7 +1349,7 @@ where ERRL!("{:?}", err), )); }, - } + }; Ok(transaction.into()) }; From 1778350ae52f9f95bdbe530c606daff513c11957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Thu, 14 Apr 2022 03:02:52 +0300 Subject: [PATCH 32/48] use full path for tx macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/lp_coins.rs | 12 ++++++++---- mm2src/coins/z_coin.rs | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 043f493ad9..2f1480322a 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -102,7 +102,11 @@ macro_rules! try_tx_fus { ($e: expr) => { match $e { Ok(ok) => ok, - Err(err) => return Box::new(futures01::future::err(TransactionErr::PlainError(ERRL!("{:?}", err)))), + Err(err) => { + return Box::new(futures01::future::err(crate::TransactionErr::PlainError(ERRL!( + "{:?}", err + )))) + }, } }; } @@ -113,7 +117,7 @@ macro_rules! try_tx_s { match $e { Ok(ok) => ok, Err(err) => { - return Err(TransactionErr::PlainError(format!( + return Err(crate::TransactionErr::PlainError(format!( "{}:{}] {:?}", file!(), line!(), @@ -126,8 +130,8 @@ macro_rules! try_tx_s { /// `TransactionErr:PlainError` compatible `ERR` macro. macro_rules! TX_ERR { - ($format: expr, $($args: tt)+) => { Err(TransactionErr::PlainError((ERRL!($format, $($args)+)))) }; - ($format: expr) => { Err(TransactionErr::PlainError(ERRL!($format))) } + ($format: expr, $($args: tt)+) => { Err(crate::TransactionErr::PlainError((ERRL!($format, $($args)+)))) }; + ($format: expr) => { Err(crate::TransactionErr::PlainError(ERRL!($format))) } } pub mod coin_balance; diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index c120e84f51..e9bf47ba02 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -9,7 +9,7 @@ use crate::utxo::{sat_from_big_decimal, utxo_common, ActualTxFee, AdditionalTxDa UtxoTxGenerationOps, UtxoWeak, VerboseTransactionFrom}; use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, SwapOps, TradeFee, TradePreimageFut, TradePreimageResult, - TradePreimageValue, TransactionDetails, TransactionEnum, TransactionErr, TransactionFut, TxFeeDetails, + TradePreimageValue, TransactionDetails, TransactionEnum, TransactionFut, TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawFut, WithdrawRequest}; use crate::{Transaction, WithdrawError}; use async_trait::async_trait; From 6b9e57920b8412a5916fc50df489f5c3c449fac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Mon, 18 Apr 2022 16:55:43 +0300 Subject: [PATCH 33/48] save development state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/lp_coins.rs | 2 +- mm2src/coins/qrc20/qrc20_tests.rs | 34 +++++++++++++++++++++++++++++++ mm2src/coins/utxo/slp.rs | 12 ++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 1a9958753b..e744dd9085 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -313,7 +313,7 @@ impl Deref for TransactionEnum { } } -#[derive(Debug, PartialEq)] +#[derive(Debug, Clone)] pub enum TransactionErr { /// Keeps transactions while throwing errors. TxRecoverableError(Box, String), diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index 6a228636b3..cd61b784b7 100644 --- a/mm2src/coins/qrc20/qrc20_tests.rs +++ b/mm2src/coins/qrc20/qrc20_tests.rs @@ -1,3 +1,5 @@ +use std::mem::discriminant; + use super::*; use crate::TxFeeDetails; use bigdecimal::Zero; @@ -923,3 +925,35 @@ fn test_negotiate_swap_contract_addr_has_fallback() { let result = coin.negotiate_swap_contract_addr(Some(slice)).unwrap(); assert_eq!(Some(fallback_addr.to_vec().into()), result); } + +#[test] +fn test_send_contract_calls_recoverable_tx() { + let priv_key = [ + 3, 98, 177, 3, 108, 39, 234, 144, 131, 178, 103, 103, 127, 80, 230, 166, 53, 68, 147, 215, 42, 216, 144, 72, + 172, 110, 180, 13, 123, 179, 10, 49, + ]; + let (_ctx, coin) = qrc20_coin_for_test(&priv_key, None); + + let tx = TransactionEnum::UtxoTx("010000000160fd74b5714172f285db2b36f0b391cd6883e7291441631c8b18f165b0a4635d020000006a47304402205d409e141111adbc4f185ae856997730de935ac30a0d2b1ccb5a6c4903db8171022024fc59bbcfdbba283556d7eeee4832167301dc8e8ad9739b7865f67b9676b226012103693bff1b39e8b5a306810023c29b95397eb395530b106b1820ea235fd81d9ce9ffffffff020000000000000000625403a08601012844a9059cbb000000000000000000000000ca1e04745e8ca0c60d8c5881531d51bec470743f00000000000000000000000000000000000000000000000000000000000f424014d362e096e873eb7907e205fadc6175c6fec7bc44c200ada205000000001976a9149e032d4b0090a11dc40fe6c47601499a35d55fbb88acfe967d5f".into()); + + let fee_addr = hex::decode("03bc2c7ba671bae4a6fc835244c9762b41647b9827d4780a89a949b984a8ddcc05").unwrap(); + let to_address = coin.contract_address_from_raw_pubkey(&fee_addr).unwrap(); + let amount = BigDecimal::from(0.2); + let amount = wei_from_big_decimal(&amount, coin.utxo.decimals).unwrap(); + let mut transfer_output = coin + .transfer_output(to_address, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT) + .unwrap(); + + transfer_output.value = 777; + + let tx_err = block_on(coin.send_contract_calls(vec![transfer_output])).unwrap_err(); + + // The error variant should equal to `TxRecoverableError` + assert_eq!( + discriminant(&tx_err), + discriminant(&TransactionErr::TxRecoverableError( + Box::new(TransactionEnum::from(tx)), + String::new() + )) + ); +} diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index da525a8f2d..7750181648 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -1793,6 +1793,7 @@ pub fn slp_addr_from_pubkey_str(pubkey: &str, prefix: &str) -> Result err, TransactionErr::PlainError(err) => err, }; @@ -2061,6 +2062,15 @@ mod slp_tests { BroadcastTxErr::Other(err) => assert!(err.contains("is not valid with reason outputs greater than inputs")), e @ _ => panic!("Unexpected err {:?}", e), }; + + // The error variant should equal to `TxRecoverableError` + assert_eq!( + discriminant(&tx_err), + discriminant(&TransactionErr::TxRecoverableError( + Box::new(TransactionEnum::from(utxo_tx)), + String::new() + )) + ); } #[test] From 19a493dced3ae574293175f84f58a14ca96e650c Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Mon, 18 Apr 2022 18:21:14 +0300 Subject: [PATCH 34/48] add test fn for `send_maker_spends_taker_payment` Signed-off-by: ozkanonur --- mm2src/coins/utxo/slp.rs | 2 +- mm2src/coins/utxo/utxo_tests.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 7750181648..714451d552 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -1793,10 +1793,10 @@ pub fn slp_addr_from_pubkey_str(pubkey: &str, prefix: &str) -> Result Date: Mon, 18 Apr 2022 18:26:20 +0300 Subject: [PATCH 35/48] update `test_send_contract_calls_recoverable_tx` Signed-off-by: ozkanonur --- mm2src/coins/qrc20/qrc20_tests.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index cd61b784b7..1bd225430f 100644 --- a/mm2src/coins/qrc20/qrc20_tests.rs +++ b/mm2src/coins/qrc20/qrc20_tests.rs @@ -944,7 +944,10 @@ fn test_send_contract_calls_recoverable_tx() { .transfer_output(to_address, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT) .unwrap(); + // brake the transfer output transfer_output.value = 777; + transfer_output.gas_limit = 777; + transfer_output.gas_price = 777; let tx_err = block_on(coin.send_contract_calls(vec![transfer_output])).unwrap_err(); From 21f2b6af2e0a735b8f2eec6d8a957ecdf1833aca Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Mon, 18 Apr 2022 18:37:30 +0300 Subject: [PATCH 36/48] fix typo Signed-off-by: ozkanonur --- mm2src/coins/qrc20/qrc20_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index 1bd225430f..8219fde3b8 100644 --- a/mm2src/coins/qrc20/qrc20_tests.rs +++ b/mm2src/coins/qrc20/qrc20_tests.rs @@ -944,7 +944,7 @@ fn test_send_contract_calls_recoverable_tx() { .transfer_output(to_address, amount, QRC20_GAS_LIMIT_DEFAULT, QRC20_GAS_PRICE_DEFAULT) .unwrap(); - // brake the transfer output + // break the transfer output transfer_output.value = 777; transfer_output.gas_limit = 777; transfer_output.gas_price = 777; From 781110655c3b17aa5135b27fd1c7722f83916f13 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Tue, 19 Apr 2022 14:35:47 +0300 Subject: [PATCH 37/48] impl helper functions for `enum TransactionErr` Signed-off-by: ozkanonur --- mm2src/coins/lp_coins.rs | 20 ++++++ mm2src/lp_swap/maker_swap.rs | 93 +++++++++++--------------- mm2src/lp_swap/taker_swap.rs | 125 ++++++++++++++--------------------- 3 files changed, 108 insertions(+), 130 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index e744dd9085..d3e2eac3b7 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -321,6 +321,26 @@ pub enum TransactionErr { PlainError(String), } +impl TransactionErr { + /// Returns transaction if the error includes it. + #[inline] + pub fn get_tx(&self) -> Option { + match self { + TransactionErr::TxRecoverableError(tx, _) => Some(*tx.clone()), + _ => None, + } + } + + #[inline] + /// Returns plain text part of error. + pub fn get_plain_text_format(&self) -> String { + match self { + TransactionErr::TxRecoverableError(_, err) => err.to_string(), + TransactionErr::PlainError(err) => err.to_string(), + } + } +} + pub type TransactionFut = Box + Send>; #[derive(Debug, PartialEq)] diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index 78db604c15..bebfb825a9 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -16,7 +16,7 @@ use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use bitcrypto::dhash160; use coins::{CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, - TransactionEnum, TransactionErr, ValidatePaymentInput}; + TransactionEnum, ValidatePaymentInput}; use common::log::{debug, error, warn}; use common::mm_error::prelude::*; use common::privkey::key_pair_from_secret; @@ -667,24 +667,21 @@ impl MakerSwap { match payment_fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return Ok((Some(MakerSwapCommand::Finish), vec![ - MakerSwapEvent::MakerPaymentTransactionFailed(ERRL!("{}", err).into()), - ])); - }, - TransactionErr::PlainError(err) => { - return Ok((Some(MakerSwapCommand::Finish), vec![ - MakerSwapEvent::MakerPaymentTransactionFailed(ERRL!("{}", err).into()), - ])) - }, + return Ok((Some(MakerSwapCommand::Finish), vec![ + MakerSwapEvent::MakerPaymentTransactionFailed( + ERRL!("{}", err.get_plain_text_format()).into(), + ), + ])); }, } }, @@ -857,34 +854,28 @@ impl MakerSwap { let transaction = match spend_fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return Ok((Some(MakerSwapCommand::RefundMakerPayment), vec![ - MakerSwapEvent::TakerPaymentSpendFailed( - ERRL!("!taker_coin.send_maker_spends_taker_payment: {}", err).into(), - ), - MakerSwapEvent::MakerPaymentWaitRefundStarted { - wait_until: self.wait_refund_until(), - }, - ])); - }, - TransactionErr::PlainError(err) => { - return Ok((Some(MakerSwapCommand::RefundMakerPayment), vec![ - MakerSwapEvent::TakerPaymentSpendFailed( - ERRL!("!taker_coin.send_maker_spends_taker_payment: {}", err).into(), - ), - MakerSwapEvent::MakerPaymentWaitRefundStarted { - wait_until: self.wait_refund_until(), - }, - ])) - }, + return Ok((Some(MakerSwapCommand::RefundMakerPayment), vec![ + MakerSwapEvent::TakerPaymentSpendFailed( + ERRL!( + "!taker_coin.send_maker_spends_taker_payment: {}", + err.get_plain_text_format() + ) + .into(), + ), + MakerSwapEvent::MakerPaymentWaitRefundStarted { + wait_until: self.wait_refund_until(), + }, + ])); }, }; @@ -959,28 +950,25 @@ impl MakerSwap { let transaction = match spend_fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return Ok((Some(MakerSwapCommand::Finish), vec![ - MakerSwapEvent::MakerPaymentRefundFailed( - ERRL!("!maker_coin.send_maker_refunds_payment: {}", err).into(), - ), - ])); - }, - TransactionErr::PlainError(err) => { - return Ok((Some(MakerSwapCommand::Finish), vec![ - MakerSwapEvent::MakerPaymentRefundFailed( - ERRL!("!maker_coin.send_maker_refunds_payment: {}", err).into(), - ), - ])) - }, + return Ok((Some(MakerSwapCommand::Finish), vec![ + MakerSwapEvent::MakerPaymentRefundFailed( + ERRL!( + "!maker_coin.send_maker_refunds_payment: {}", + err.get_plain_text_format() + ) + .into(), + ), + ])); }, }; @@ -1242,18 +1230,17 @@ impl MakerSwap { let transaction = match fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return ERR!("{}", err); - }, - TransactionErr::PlainError(err) => return ERR!("{}", err), + return ERR!("{}", err.get_plain_text_format()); }, }; diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index b70ee8cfb0..2cbf86453d 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -14,7 +14,7 @@ use crate::mm2::lp_swap::{broadcast_p2p_tx_msg, tx_helper_topic}; use crate::mm2::MM_VERSION; use bigdecimal::BigDecimal; use coins::{lp_coinfind, CanRefundHtlc, FeeApproxStage, FoundSwapTxSpend, MmCoinEnum, TradeFee, TradePreimageValue, - TransactionErr, ValidatePaymentInput}; + ValidatePaymentInput}; use common::executor::Timer; use common::log::{debug, error, warn}; use common::mm_ctx::MmArc; @@ -1024,24 +1024,19 @@ impl TakerSwap { .await; let transaction = match fee_tx { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::TakerFeeSendFailed(ERRL!("{}", err).into()), - ])); - }, - TransactionErr::PlainError(err) => { - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::TakerFeeSendFailed(ERRL!("{}", err).into()), - ])) - }, + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::TakerFeeSendFailed(ERRL!("{}", err.get_plain_text_format()).into()), + ])); }, }; @@ -1184,24 +1179,21 @@ impl TakerSwap { match payment_fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::TakerPaymentTransactionFailed(ERRL!("{}", err).into()), - ])); - }, - TransactionErr::PlainError(err) => { - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::TakerPaymentTransactionFailed(ERRL!("{}", err).into()), - ])) - }, + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::TakerPaymentTransactionFailed( + ERRL!("{}", err.get_plain_text_format()).into(), + ), + ])); }, } }, @@ -1262,30 +1254,22 @@ impl TakerSwap { ); let tx = match f.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return Ok((Some(TakerSwapCommand::RefundTakerPayment), vec![ - TakerSwapEvent::TakerPaymentWaitForSpendFailed(err.into()), - TakerSwapEvent::TakerPaymentWaitRefundStarted { - wait_until: self.wait_refund_until(), - }, - ])); - }, - TransactionErr::PlainError(err) => { - return Ok((Some(TakerSwapCommand::RefundTakerPayment), vec![ - TakerSwapEvent::TakerPaymentWaitForSpendFailed(err.into()), - TakerSwapEvent::TakerPaymentWaitRefundStarted { - wait_until: self.wait_refund_until(), - }, - ])) - }, + return Ok((Some(TakerSwapCommand::RefundTakerPayment), vec![ + TakerSwapEvent::TakerPaymentWaitForSpendFailed(err.get_plain_text_format().into()), + TakerSwapEvent::TakerPaymentWaitRefundStarted { + wait_until: self.wait_refund_until(), + }, + ])); }, }; drop(send_abort_handle); @@ -1326,24 +1310,19 @@ impl TakerSwap { ); let transaction = match spend_fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), &tx, &self.p2p_privkey, ); + }; - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::MakerPaymentSpendFailed(ERRL!("{}", err).into()), - ])); - }, - TransactionErr::PlainError(err) => { - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::MakerPaymentSpendFailed(ERRL!("{}", err).into()), - ])) - }, + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::MakerPaymentSpendFailed(ERRL!("{}", err.get_plain_text_format()).into()), + ])); }, }; @@ -1390,24 +1369,19 @@ impl TakerSwap { let transaction = match refund_fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::TakerPaymentRefundFailed(ERRL!("{:?}", err).into()), - ])); - }, - TransactionErr::PlainError(err) => { - return Ok((Some(TakerSwapCommand::Finish), vec![ - TakerSwapEvent::TakerPaymentRefundFailed(ERRL!("{:?}", err).into()), - ])); - }, + return Ok((Some(TakerSwapCommand::Finish), vec![ + TakerSwapEvent::TakerPaymentRefundFailed(ERRL!("{:?}", err.get_plain_text_format()).into()), + ])); }, }; @@ -1616,18 +1590,17 @@ impl TakerSwap { let transaction = match fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return ERR!("{}", err); - }, - TransactionErr::PlainError(err) => return ERR!("{}", err), + return ERR!("{}", err.get_plain_text_format()); }, }; @@ -1668,18 +1641,17 @@ impl TakerSwap { let transaction = match fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return ERR!("{}", err); - }, - TransactionErr::PlainError(err) => return ERR!("{}", err), + return ERR!("{}", err.get_plain_text_format()); }, }; @@ -1713,18 +1685,17 @@ impl TakerSwap { let transaction = match fut.compat().await { Ok(t) => t, - Err(err_enum) => match err_enum { - TransactionErr::TxRecoverableError(tx, err) => { + Err(err) => { + if let Some(tx) = err.get_tx() { broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.taker_coin.ticker()), &tx, &self.p2p_privkey, ); + } - return ERR!("{:?}", err); - }, - TransactionErr::PlainError(err) => return ERR!("{:?}", err), + return ERR!("{:?}", err.get_plain_text_format()); }, }; From 9c9db1cb14153325da173f77dc8efcea1a804bc4 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 20 Apr 2022 15:45:44 +0300 Subject: [PATCH 38/48] refactor `send_raw_tx_bytes` Signed-off-by: ozkanonur --- mm2src/coins/eth.rs | 3 +-- mm2src/coins/lp_coins.rs | 2 +- mm2src/coins/qrc20.rs | 2 +- mm2src/coins/solana.rs | 6 ++---- mm2src/coins/solana/solana_tests.rs | 7 +++---- mm2src/coins/solana/spl.rs | 3 +-- mm2src/coins/solana/spl_tests.rs | 6 +++--- mm2src/coins/utxo/bch.rs | 2 +- mm2src/coins/utxo/qtum.rs | 2 +- mm2src/coins/utxo/utxo_common.rs | 18 ++++++++++++++---- mm2src/coins/utxo/utxo_standard.rs | 2 +- mm2src/coins/z_coin.rs | 2 +- 12 files changed, 30 insertions(+), 25 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 9fc21e9dde..228a81353b 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -1146,11 +1146,10 @@ impl MarketCoinOps for EthCoin { } fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - let bytes = try_fus!(hex::decode(tx)); Box::new( self.web3 .eth() - .send_raw_transaction(bytes.into()) + .send_raw_transaction(tx.into()) .map(|res| format!("{:02x}", res)) .map_err(|e| ERRL!("{}", e)), ) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index d3e2eac3b7..9bae4875a8 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -803,7 +803,7 @@ impl Default for TransactionType { /// Transaction details #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct TransactionDetails { - /// Raw bytes of signed transaction in hexadecimal string, this should be sent as is to send_raw_transaction RPC to broadcast the transaction + /// Raw bytes of signed transaction, this should be sent as is to `send_raw_transaction_bytes` RPC to broadcast the transaction pub tx_hex: BytesJson, /// Transaction hash in hexadecimal format tx_hash: String, diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 55826bf576..39e3959ff1 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -1072,7 +1072,7 @@ impl MarketCoinOps for Qrc20Coin { #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx(&self.utxo, tx) + utxo_common::send_raw_tx_bytes(&self.utxo, tx) } fn wait_for_confirmations( diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index 73047ae3f1..e14836d667 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -239,7 +239,6 @@ async fn withdraw_base_coin_impl(coin: SolanaCoin, req: WithdrawRequest) -> With let to = solana_sdk::pubkey::Pubkey::try_from(&*req.to)?; let tx = solana_sdk::system_transaction::transfer(&coin.key_pair, &to, res.lamports_to_send, hash); let serialized_tx = serialize(&tx).map_to_mm(|e| WithdrawError::InternalError(e.to_string()))?; - let encoded_tx = hex::encode(&serialized_tx); let total_amount = lamports_to_sol(res.lamports_to_send); let received_by_me = if req.to == coin.my_address { total_amount.clone() @@ -248,7 +247,7 @@ async fn withdraw_base_coin_impl(coin: SolanaCoin, req: WithdrawRequest) -> With }; let spent_by_me = &total_amount + &res.sol_required; Ok(TransactionDetails { - tx_hex: encoded_tx.as_bytes().into(), + tx_hex: serialized_tx.into(), tx_hash: tx.signatures[0].to_string(), from: vec![coin.my_address.clone()], to: vec![req.to], @@ -378,8 +377,7 @@ impl MarketCoinOps for SolanaCoin { let coin = self.clone(); let tx = tx.to_owned(); let fut = async move { - let bytes = hex::decode(tx).map_to_mm(|e| e).map_err(|e| format!("{:?}", e))?; - let tx: Transaction = deserialize(bytes.as_slice()) + let tx: Transaction = deserialize(tx.as_slice()) .map_to_mm(|e| e) .map_err(|e| format!("{:?}", e))?; let signature = coin.rpc().send_transaction(&tx).await.map_err(|e| format!("{:?}", e))?; diff --git a/mm2src/coins/solana/solana_tests.rs b/mm2src/coins/solana/solana_tests.rs index 774846b934..1c482da102 100644 --- a/mm2src/coins/solana/solana_tests.rs +++ b/mm2src/coins/solana/solana_tests.rs @@ -6,7 +6,6 @@ use crate::MarketCoinOps; use base58::ToBase58; use solana_client::rpc_request::TokenAccountsFilter; use solana_sdk::signature::Signer; -use std::str; use std::str::FromStr; mod tests { @@ -258,11 +257,11 @@ mod tests { .unwrap(); println!("{:?}", valid_tx_details); - let tx_str = str::from_utf8(&*valid_tx_details.tx_hex.0).unwrap(); - let res = sol_coin.send_raw_tx(tx_str).compat().await.unwrap(); + let tx_str = hex::encode(&*valid_tx_details.tx_hex.0); + let res = sol_coin.send_raw_tx(&tx_str).compat().await.unwrap(); let res2 = sol_coin - .send_raw_tx_bytes(&*valid_tx_details.tx_hex) + .send_raw_tx_bytes(&*valid_tx_details.tx_hex.0) .compat() .await .unwrap(); diff --git a/mm2src/coins/solana/spl.rs b/mm2src/coins/solana/spl.rs index c52a6423aa..27abfea39a 100644 --- a/mm2src/coins/solana/spl.rs +++ b/mm2src/coins/solana/spl.rs @@ -117,14 +117,13 @@ async fn withdraw_spl_token_impl(coin: SplToken, req: WithdrawRequest) -> Withdr let signers = vec![&coin.platform_coin.key_pair]; let tx = Transaction::new(&signers, msg, hash); let serialized_tx = serialize(&tx).map_to_mm(|e| WithdrawError::InternalError(e.to_string()))?; - let encoded_tx = hex::encode(&serialized_tx); let received_by_me = if req.to == coin.platform_coin.my_address { res.to_send.clone() } else { 0.into() }; Ok(TransactionDetails { - tx_hex: encoded_tx.as_bytes().into(), + tx_hex: serialized_tx.into(), tx_hash: tx.signatures[0].to_string(), from: vec![coin.platform_coin.my_address.clone()], to: vec![req.to], diff --git a/mm2src/coins/solana/spl_tests.rs b/mm2src/coins/solana/spl_tests.rs index 79b69200d3..9b6ff141dc 100644 --- a/mm2src/coins/solana/spl_tests.rs +++ b/mm2src/coins/solana/spl_tests.rs @@ -2,7 +2,7 @@ use super::*; use crate::common::Future01CompatExt; use crate::{solana::solana_common_tests::solana_coin_for_test, solana::solana_common_tests::{spl_coin_for_test, SolanaNet}}; -use std::{str::from_utf8, str::FromStr}; +use std::str::FromStr; mod tests { use super::*; @@ -83,8 +83,8 @@ mod tests { assert_eq!(valid_tx_details.coin, "USDC".to_string()); assert_ne!(valid_tx_details.timestamp, 0); - let tx_str = from_utf8(&*valid_tx_details.tx_hex.0).unwrap(); - let res = usdc_sol_coin.send_raw_tx(tx_str).compat().await.unwrap(); + let tx_str = hex::encode(&*valid_tx_details.tx_hex.0); + let res = usdc_sol_coin.send_raw_tx(&tx_str).compat().await.unwrap(); println!("{:?}", res); let res2 = usdc_sol_coin diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index e8975eefb6..ad34b1afe9 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -1060,7 +1060,7 @@ impl MarketCoinOps for BchCoin { #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx(&self.utxo_arc, tx) + utxo_common::send_raw_tx_bytes(&self.utxo_arc, tx) } fn wait_for_confirmations( diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index 7aaaf37a36..ead4e1a786 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -681,7 +681,7 @@ impl MarketCoinOps for QtumCoin { #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx(&self.utxo_arc, tx) + utxo_common::send_raw_tx_bytes(&self.utxo_arc, tx) } fn wait_for_confirmations( diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 51913c90ea..559a0622ff 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1685,15 +1685,25 @@ where Box::new(fut.boxed().compat()) } +/// Receives raw transaction as input and returns tx hash in hexadecimal format +pub fn send_raw_tx(coin: &UtxoCoinFields, tx: &str) -> Box + Send> { + let bytes = try_fus!(hex::decode(tx)); + Box::new( + coin.rpc_client + .send_raw_transaction(bytes.into()) + .map_err(|e| ERRL!("{}", e)) + .map(|hash| format!("{:?}", hash)), + ) +} + /// Receives raw transaction bytes as input and returns tx hash in hexadecimal format -pub fn send_raw_tx>( +pub fn send_raw_tx_bytes( coin: &UtxoCoinFields, - tx: T, + tx_bytes: &[u8], ) -> Box + Send> { - let bytes = try_fus!(hex::decode(tx)); Box::new( coin.rpc_client - .send_raw_transaction(bytes.into()) + .send_raw_transaction(tx_bytes.into()) .map_err(|e| ERRL!("{}", e)) .map(|hash| format!("{:?}", hash)), ) diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 1631b9212b..238f598c3e 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -456,7 +456,7 @@ impl MarketCoinOps for UtxoStandardCoin { #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx(&self.utxo_arc, tx) + utxo_common::send_raw_tx_bytes(&self.utxo_arc, tx) } fn wait_for_confirmations( diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index 1f282c62fa..66447f16b3 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -740,7 +740,7 @@ impl MarketCoinOps for ZCoin { #[inline(always)] fn send_raw_tx_bytes(&self, tx: &[u8]) -> Box + Send> { - utxo_common::send_raw_tx(self.as_ref(), tx) + utxo_common::send_raw_tx_bytes(self.as_ref(), tx) } fn wait_for_confirmations( From f461dcc35ee93e82a4d03df48ac1cd44e559b4ce Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 20 Apr 2022 17:39:17 +0300 Subject: [PATCH 39/48] sub to `txhlp/$coin` when utxo coin enabled in native mode Signed-off-by: ozkanonur --- mm2src/rpc/lp_commands.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mm2src/rpc/lp_commands.rs b/mm2src/rpc/lp_commands.rs index ec6707787a..a35254eaf7 100644 --- a/mm2src/rpc/lp_commands.rs +++ b/mm2src/rpc/lp_commands.rs @@ -30,8 +30,9 @@ use serde_json::{self as json, Value as Json}; use std::borrow::Cow; use crate::mm2::lp_dispatcher::{dispatch_lp_event, StopCtxEvent}; +use crate::mm2::lp_network::subscribe_to_topic; use crate::mm2::lp_ordermatch::{cancel_orders_by, CancelBy}; -use crate::mm2::lp_swap::active_swaps_using_coin; +use crate::mm2::lp_swap::{active_swaps_using_coin, tx_helper_topic}; use crate::mm2::MmVersionResult; /// Attempts to disable the coin @@ -128,7 +129,13 @@ pub async fn enable(ctx: MmArc, req: Json) -> Result>, String> mature_confirmations: coin.mature_confirmations(), }; let res = try_s!(json::to_vec(&res)); - Ok(try_s!(Response::builder().body(res))) + let res = try_s!(Response::builder().body(res)); + + if let MmCoinEnum::UtxoCoin(_) = &coin { + subscribe_to_topic(&ctx, tx_helper_topic(coin.ticker())); + } + + Ok(res) } #[cfg(target_arch = "wasm32")] From bad90b6e69ccd11b666a017b26af1aa2860136e7 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Wed, 20 Apr 2022 17:48:42 +0300 Subject: [PATCH 40/48] unbox `TransactionEnum` in `TxRecoverableError` Signed-off-by: ozkanonur --- mm2src/coins/lp_coins.rs | 5 +++-- mm2src/coins/qrc20.rs | 2 +- mm2src/coins/qrc20/qrc20_tests.rs | 2 +- mm2src/coins/utxo.rs | 2 +- mm2src/coins/utxo/slp.rs | 2 +- mm2src/coins/utxo/utxo_common.rs | 8 ++++---- mm2src/coins/utxo/utxo_tests.rs | 2 +- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 9bae4875a8..a200f662b0 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -314,9 +314,10 @@ impl Deref for TransactionEnum { } #[derive(Debug, Clone)] +#[allow(clippy::large_enum_variant)] pub enum TransactionErr { /// Keeps transactions while throwing errors. - TxRecoverableError(Box, String), + TxRecoverableError(TransactionEnum, String), /// Simply for plain error messages. PlainError(String), } @@ -326,7 +327,7 @@ impl TransactionErr { #[inline] pub fn get_tx(&self) -> Option { match self { - TransactionErr::TxRecoverableError(tx, _) => Some(*tx.clone()), + TransactionErr::TxRecoverableError(tx, _) => Some(tx.clone()), _ => None, } } diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 39e3959ff1..0a5f1d3fc8 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -463,7 +463,7 @@ impl Qrc20Coin { Ok(tx) => tx, Err(err) => { return Err(TransactionErr::TxRecoverableError( - Box::new(TransactionEnum::from(signed)), + TransactionEnum::from(signed), ERRL!("{:?}", err), )); }, diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index 8219fde3b8..ec8ae03e59 100644 --- a/mm2src/coins/qrc20/qrc20_tests.rs +++ b/mm2src/coins/qrc20/qrc20_tests.rs @@ -955,7 +955,7 @@ fn test_send_contract_calls_recoverable_tx() { assert_eq!( discriminant(&tx_err), discriminant(&TransactionErr::TxRecoverableError( - Box::new(TransactionEnum::from(tx)), + TransactionEnum::from(tx), String::new() )) ); diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 16e10a4d34..75e37617d2 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -1532,7 +1532,7 @@ where Ok(_) => (), Err(err) => { return Err(TransactionErr::TxRecoverableError( - Box::new(TransactionEnum::from(signed)), + TransactionEnum::from(signed), ERRL!("{:?}", err), )); }, diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 714451d552..8be406f981 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -2067,7 +2067,7 @@ mod slp_tests { assert_eq!( discriminant(&tx_err), discriminant(&TransactionErr::TxRecoverableError( - Box::new(TransactionEnum::from(utxo_tx)), + TransactionEnum::from(utxo_tx), String::new() )) ); diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 559a0622ff..f05552ae8f 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1128,7 +1128,7 @@ pub fn send_maker_spends_taker_payment( Ok(_) => (), Err(err) => { return Err(TransactionErr::TxRecoverableError( - Box::new(TransactionEnum::from(transaction)), + TransactionEnum::from(transaction), ERRL!("{:?}", err), )); }, @@ -1188,7 +1188,7 @@ pub fn send_taker_spends_maker_payment( Ok(_) => (), Err(err) => { return Err(TransactionErr::TxRecoverableError( - Box::new(TransactionEnum::from(transaction)), + TransactionEnum::from(transaction), ERRL!("{:?}", err), )); }, @@ -1246,7 +1246,7 @@ pub fn send_taker_refunds_payment( Ok(_) => (), Err(err) => { return Err(TransactionErr::TxRecoverableError( - Box::new(TransactionEnum::from(transaction)), + TransactionEnum::from(transaction), ERRL!("{:?}", err), )); }, @@ -1303,7 +1303,7 @@ pub fn send_maker_refunds_payment( Ok(_) => (), Err(err) => { return Err(TransactionErr::TxRecoverableError( - Box::new(TransactionEnum::from(transaction)), + TransactionEnum::from(transaction), ERRL!("{:?}", err), )); }, diff --git a/mm2src/coins/utxo/utxo_tests.rs b/mm2src/coins/utxo/utxo_tests.rs index 9407b6851a..a97f6a7e09 100644 --- a/mm2src/coins/utxo/utxo_tests.rs +++ b/mm2src/coins/utxo/utxo_tests.rs @@ -205,7 +205,7 @@ fn test_send_maker_spends_taker_payment_recoverable_tx() { assert_eq!( discriminant(&tx_err), discriminant(&TransactionErr::TxRecoverableError( - Box::new(TransactionEnum::from(tx)), + TransactionEnum::from(tx), String::new() )) ); From 8ca638f8fc4f48c232ef2abc7c6b2f9e8201e1e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Thu, 21 Apr 2022 14:30:53 +0300 Subject: [PATCH 41/48] add more spesific conditions on `txhlp` subscription MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/lp_coins.rs | 15 +++++++++++++++ mm2src/coins/utxo/rpc_clients.rs | 8 ++++++++ mm2src/rpc/lp_commands.rs | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index a200f662b0..921751dbe5 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -1656,6 +1656,21 @@ impl Deref for MmCoinEnum { } } +impl MmCoinEnum { + pub fn is_utxo_and_in_native_mode(&self) -> bool { + match self { + MmCoinEnum::UtxoCoin(ref c) => c.as_ref().rpc_client.is_native(), + MmCoinEnum::QtumCoin(ref c) => c.as_ref().rpc_client.is_native(), + MmCoinEnum::Qrc20Coin(ref c) => c.as_ref().rpc_client.is_native(), + MmCoinEnum::Bch(ref c) => c.as_ref().rpc_client.is_native(), + MmCoinEnum::SlpToken(ref c) => c.as_ref().rpc_client.is_native(), + #[cfg(all(not(target_arch = "wasm32"), feature = "zhtlc"))] + MmCoinEnum::ZCoin(ref c) => c.as_ref().rpc_client.is_native(), + _ => false, + } + } +} + #[async_trait] pub trait BalanceTradeFeeUpdatedHandler { async fn balance_updated(&self, coin: &MmCoinEnum, new_balance: &BigDecimal); diff --git a/mm2src/coins/utxo/rpc_clients.rs b/mm2src/coins/utxo/rpc_clients.rs index bd206b7bd2..737d025437 100644 --- a/mm2src/coins/utxo/rpc_clients.rs +++ b/mm2src/coins/utxo/rpc_clients.rs @@ -178,6 +178,14 @@ impl UtxoRpcClientEnum { }; Box::new(fut.boxed().compat()) } + + #[inline] + pub fn is_native(&self) -> bool { + match self { + UtxoRpcClientEnum::Native(_) => true, + UtxoRpcClientEnum::Electrum(_) => false, + } + } } /// Generic unspent info required to build transactions, we need this separate type because native diff --git a/mm2src/rpc/lp_commands.rs b/mm2src/rpc/lp_commands.rs index a35254eaf7..8cf4b81bad 100644 --- a/mm2src/rpc/lp_commands.rs +++ b/mm2src/rpc/lp_commands.rs @@ -131,7 +131,7 @@ pub async fn enable(ctx: MmArc, req: Json) -> Result>, String> let res = try_s!(json::to_vec(&res)); let res = try_s!(Response::builder().body(res)); - if let MmCoinEnum::UtxoCoin(_) = &coin { + if coin.is_utxo_and_in_native_mode() { subscribe_to_topic(&ctx, tx_helper_topic(coin.ticker())); } From ed574a582a8c0f65c9bd7acdee0be2d2b9037da4 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Thu, 21 Apr 2022 17:08:39 +0300 Subject: [PATCH 42/48] rollback unnecessary broadcastings Signed-off-by: ozkanonur --- mm2src/lp_swap/maker_swap.rs | 9 --------- mm2src/lp_swap/taker_swap.rs | 27 --------------------------- 2 files changed, 36 deletions(-) diff --git a/mm2src/lp_swap/maker_swap.rs b/mm2src/lp_swap/maker_swap.rs index bebfb825a9..f9c35ea428 100644 --- a/mm2src/lp_swap/maker_swap.rs +++ b/mm2src/lp_swap/maker_swap.rs @@ -668,15 +668,6 @@ impl MakerSwap { match payment_fut.compat().await { Ok(t) => t, Err(err) => { - if let Some(tx) = err.get_tx() { - broadcast_p2p_tx_msg( - &self.ctx, - tx_helper_topic(self.maker_coin.ticker()), - &tx, - &self.p2p_privkey, - ); - } - return Ok((Some(MakerSwapCommand::Finish), vec![ MakerSwapEvent::MakerPaymentTransactionFailed( ERRL!("{}", err.get_plain_text_format()).into(), diff --git a/mm2src/lp_swap/taker_swap.rs b/mm2src/lp_swap/taker_swap.rs index 2cbf86453d..751fef2be0 100644 --- a/mm2src/lp_swap/taker_swap.rs +++ b/mm2src/lp_swap/taker_swap.rs @@ -1025,15 +1025,6 @@ impl TakerSwap { let transaction = match fee_tx { Ok(t) => t, Err(err) => { - if let Some(tx) = err.get_tx() { - broadcast_p2p_tx_msg( - &self.ctx, - tx_helper_topic(self.taker_coin.ticker()), - &tx, - &self.p2p_privkey, - ); - } - return Ok((Some(TakerSwapCommand::Finish), vec![ TakerSwapEvent::TakerFeeSendFailed(ERRL!("{}", err.get_plain_text_format()).into()), ])); @@ -1180,15 +1171,6 @@ impl TakerSwap { match payment_fut.compat().await { Ok(t) => t, Err(err) => { - if let Some(tx) = err.get_tx() { - broadcast_p2p_tx_msg( - &self.ctx, - tx_helper_topic(self.taker_coin.ticker()), - &tx, - &self.p2p_privkey, - ); - } - return Ok((Some(TakerSwapCommand::Finish), vec![ TakerSwapEvent::TakerPaymentTransactionFailed( ERRL!("{}", err.get_plain_text_format()).into(), @@ -1255,15 +1237,6 @@ impl TakerSwap { let tx = match f.compat().await { Ok(t) => t, Err(err) => { - if let Some(tx) = err.get_tx() { - broadcast_p2p_tx_msg( - &self.ctx, - tx_helper_topic(self.taker_coin.ticker()), - &tx, - &self.p2p_privkey, - ); - } - return Ok((Some(TakerSwapCommand::RefundTakerPayment), vec![ TakerSwapEvent::TakerPaymentWaitForSpendFailed(err.get_plain_text_format().into()), TakerSwapEvent::TakerPaymentWaitRefundStarted { From 46ad80853beb73a0254ed607c5c5a9b5368abdef Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Fri, 29 Apr 2022 15:58:05 +0300 Subject: [PATCH 43/48] fix PR notes Signed-off-by: ozkanonur --- mm2src/coins/eth.rs | 282 +++++++++++++++-------------- mm2src/coins/lp_coins.rs | 66 +++++-- mm2src/coins/qrc20.rs | 15 +- mm2src/coins/qrc20/qrc20_tests.rs | 4 +- mm2src/coins/qrc20/swap.rs | 12 +- mm2src/coins/utxo.rs | 13 +- mm2src/coins/utxo/slp.rs | 18 +- mm2src/coins/utxo/utxo_common.rs | 36 +--- mm2src/coins/utxo/utxo_tests.rs | 4 +- mm2src/docker_tests/qrc20_tests.rs | 6 +- mm2src/rpc/lp_commands.rs | 2 +- 11 files changed, 237 insertions(+), 221 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 228a81353b..0a6fce1c2e 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -66,7 +66,7 @@ pub use ethcore_transaction::SignedTransaction as SignedEthTx; pub use rlp; mod web3_transport; -use crate::{TransactionErr, TransactionFut, ValidatePaymentInput}; +use crate::{TransactionFut, TransactionFutErr, ValidatePaymentInput}; use common::mm_number::MmNumber; use common::privkey::key_pair_from_secret; use web3_transport::{EthFeeHistoryNamespace, Web3Transport}; @@ -689,7 +689,7 @@ impl SwapOps for EthCoin { Box::new( self.send_to_address(address, try_tx_fus!(wei_from_big_decimal(&amount, self.decimals))) - .map_err(TransactionErr::PlainError) + .map_err(|e| TransactionFutErr::Plain(ERRL!("{:?}", e))) .map(TransactionEnum::from), ) } @@ -715,7 +715,6 @@ impl SwapOps for EthCoin { taker_addr, swap_contract_address, ) - .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -741,7 +740,6 @@ impl SwapOps for EthCoin { maker_addr, swap_contract_address, ) - .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -757,11 +755,10 @@ impl SwapOps for EthCoin { ) -> TransactionFut { let tx: UnverifiedTransaction = try_tx_fus!(rlp::decode(taker_payment_tx)); let signed = try_tx_fus!(SignedEthTx::new(tx)); - let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); + let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address(), signed); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) - .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -780,7 +777,6 @@ impl SwapOps for EthCoin { let swap_contract_address = try_tx_fus!(swap_contract_address.try_to_address()); Box::new( self.spend_hash_time_locked_payment(signed, swap_contract_address, secret) - .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -800,7 +796,6 @@ impl SwapOps for EthCoin { Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) - .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -820,7 +815,6 @@ impl SwapOps for EthCoin { Box::new( self.refund_hash_time_locked_payment(swap_contract_address, signed) - .map_err(TransactionErr::PlainError) .map(TransactionEnum::from), ) } @@ -1302,7 +1296,7 @@ impl MarketCoinOps for EthCoin { } if now_ms() / 1000 > wait_until { - return TX_ERR!( + return TX_PLAIN_ERR!( "Waited too long until {} for transaction {:?} to be spent ", wait_until, tx, @@ -1353,7 +1347,7 @@ lazy_static! { static ref NONCE_LOCK: TimedAsyncMutex<()> = TimedAsyncMutex::new(()); } -type EthTxFut = Box + Send + 'static>; +type EthTxFut = Box + Send + 'static>; async fn sign_and_send_transaction_impl( ctx: MmArc, @@ -1362,7 +1356,7 @@ async fn sign_and_send_transaction_impl( action: Action, data: Vec, gas: U256, -) -> Result { +) -> Result { let mut status = ctx.log.status_handle(); macro_rules! tags { () => { @@ -1381,13 +1375,13 @@ async fn sign_and_send_transaction_impl( }) .await; status.status(tags!(), "get_addr_nonce…"); - let nonce = try_s!( + let nonce = try_tx_s!( get_addr_nonce(coin.my_address, coin.web3_instances.clone()) .compat() .await ); status.status(tags!(), "get_gas_price…"); - let gas_price = try_s!(coin.get_gas_price().compat().await); + let gas_price = try_tx_s!(coin.get_gas_price().compat().await); let tx = UnSignedEthTx { nonce, gas_price, @@ -1399,14 +1393,17 @@ async fn sign_and_send_transaction_impl( let signed = tx.sign(coin.key_pair.secret(), coin.chain_id); let bytes = web3::types::Bytes(rlp::encode(&signed).to_vec()); status.status(tags!(), "send_raw_transaction…"); - try_s!( + + try_tx_s!( coin.web3 .eth() .send_raw_transaction(bytes) .map_err(|e| ERRL!("{}", e)) .compat() - .await + .await, + signed ); + status.status(tags!(), "get_addr_nonce…"); loop { // Check every second till ETH nodes recognize that nonce is increased @@ -2182,7 +2179,7 @@ impl EthCoin { #[cfg_attr(test, mockable)] impl EthCoin { fn sign_and_send_transaction(&self, value: U256, action: Action, data: Vec, gas: U256) -> EthTxFut { - let ctx = try_fus!(MmArc::from_weak(&self.ctx).ok_or("!ctx")); + let ctx = try_tx_fus!(MmArc::from_weak(&self.ctx).ok_or("!ctx")); let fut = Box::pin(sign_and_send_transaction_impl( ctx, self.clone(), @@ -2201,9 +2198,9 @@ impl EthCoin { platform: _, token_addr, } => { - let abi = try_fus!(Contract::load(ERC20_ABI.as_bytes())); - let function = try_fus!(abi.function("transfer")); - let data = try_fus!(function.encode_input(&[Token::Address(address), Token::Uint(value)])); + let abi = try_tx_fus!(Contract::load(ERC20_ABI.as_bytes())); + let function = try_tx_fus!(abi.function("transfer")); + let data = try_tx_fus!(function.encode_input(&[Token::Address(address), Token::Uint(value)])); self.sign_and_send_transaction(0.into(), Action::Call(*token_addr), data, U256::from(210_000)) }, } @@ -2220,8 +2217,8 @@ impl EthCoin { ) -> EthTxFut { match &self.coin_type { EthCoinType::Eth => { - let function = try_fus!(SWAP_CONTRACT.function("ethPayment")); - let data = try_fus!(function.encode_input(&[ + let function = try_tx_fus!(SWAP_CONTRACT.function("ethPayment")); + let data = try_tx_fus!(function.encode_input(&[ Token::FixedBytes(id), Token::Address(receiver_addr), Token::FixedBytes(secret_hash.to_vec()), @@ -2233,10 +2230,12 @@ impl EthCoin { platform: _, token_addr, } => { - let allowance_fut = self.allowance(swap_contract_address).map_err(|e| ERRL!("{}", e)); + let allowance_fut = self + .allowance(swap_contract_address) + .map_err(|e| TransactionFutErr::Plain(ERRL!("{}", e))); - let function = try_fus!(SWAP_CONTRACT.function("erc20Payment")); - let data = try_fus!(function.encode_input(&[ + let function = try_tx_fus!(SWAP_CONTRACT.function("erc20Payment")); + let data = try_tx_fus!(function.encode_input(&[ Token::FixedBytes(id), Token::Uint(value), Token::Address(*token_addr), @@ -2278,144 +2277,160 @@ impl EthCoin { swap_contract_address: Address, secret: &[u8], ) -> EthTxFut { - let spend_func = try_fus!(SWAP_CONTRACT.function("receiverSpend")); + let spend_func = try_tx_fus!(SWAP_CONTRACT.function("receiverSpend")); let clone = self.clone(); let secret_vec = secret.to_vec(); match self.coin_type { EthCoinType::Eth => { - let payment_func = try_fus!(SWAP_CONTRACT.function("ethPayment")); - let decoded = try_fus!(payment_func.decode_input(&payment.data)); + let payment_func = try_tx_fus!(SWAP_CONTRACT.function("ethPayment")); + let decoded = try_tx_fus!(payment_func.decode_input(&payment.data)); let state_f = self.payment_status(swap_contract_address, decoded[0].clone()); - Box::new(state_f.and_then(move |state| -> EthTxFut { - if state != PAYMENT_STATE_SENT.into() { - return Box::new(futures01::future::err(ERRL!( - "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", - payment, - state - ))); - } + Box::new( + state_f + .map_err(TransactionFutErr::Plain) + .and_then(move |state| -> EthTxFut { + if state != PAYMENT_STATE_SENT.into() { + return Box::new(futures01::future::err(TransactionFutErr::Plain(ERRL!( + "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", + payment, + state + )))); + } - let value = payment.value; - let data = try_fus!(spend_func.encode_input(&[ - decoded[0].clone(), - Token::Uint(value), - Token::FixedBytes(secret_vec), - Token::Address(Address::default()), - Token::Address(payment.sender()), - ])); - - clone.sign_and_send_transaction( - 0.into(), - Action::Call(swap_contract_address), - data, - U256::from(150_000), - ) - })) + let value = payment.value; + let data = try_tx_fus!(spend_func.encode_input(&[ + decoded[0].clone(), + Token::Uint(value), + Token::FixedBytes(secret_vec), + Token::Address(Address::default()), + Token::Address(payment.sender()), + ])); + + clone.sign_and_send_transaction( + 0.into(), + Action::Call(swap_contract_address), + data, + U256::from(150_000), + ) + }), + ) }, EthCoinType::Erc20 { platform: _, token_addr, } => { - let payment_func = try_fus!(SWAP_CONTRACT.function("erc20Payment")); - let decoded = try_fus!(payment_func.decode_input(&payment.data)); + let payment_func = try_tx_fus!(SWAP_CONTRACT.function("erc20Payment")); + let decoded = try_tx_fus!(payment_func.decode_input(&payment.data)); let state_f = self.payment_status(swap_contract_address, decoded[0].clone()); - Box::new(state_f.and_then(move |state| -> EthTxFut { - if state != PAYMENT_STATE_SENT.into() { - return Box::new(futures01::future::err(ERRL!( - "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", - payment, - state - ))); - } - let data = try_fus!(spend_func.encode_input(&[ - decoded[0].clone(), - decoded[1].clone(), - Token::FixedBytes(secret_vec), - Token::Address(token_addr), - Token::Address(payment.sender()), - ])); - - clone.sign_and_send_transaction( - 0.into(), - Action::Call(swap_contract_address), - data, - U256::from(150_000), - ) - })) + Box::new( + state_f + .map_err(TransactionFutErr::Plain) + .and_then(move |state| -> EthTxFut { + if state != PAYMENT_STATE_SENT.into() { + return Box::new(futures01::future::err(TransactionFutErr::Plain(ERRL!( + "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", + payment, + state + )))); + } + let data = try_tx_fus!(spend_func.encode_input(&[ + decoded[0].clone(), + decoded[1].clone(), + Token::FixedBytes(secret_vec), + Token::Address(token_addr), + Token::Address(payment.sender()), + ])); + + clone.sign_and_send_transaction( + 0.into(), + Action::Call(swap_contract_address), + data, + U256::from(150_000), + ) + }), + ) }, } } fn refund_hash_time_locked_payment(&self, swap_contract_address: Address, payment: SignedEthTx) -> EthTxFut { - let refund_func = try_fus!(SWAP_CONTRACT.function("senderRefund")); + let refund_func = try_tx_fus!(SWAP_CONTRACT.function("senderRefund")); let clone = self.clone(); match self.coin_type { EthCoinType::Eth => { - let payment_func = try_fus!(SWAP_CONTRACT.function("ethPayment")); - let decoded = try_fus!(payment_func.decode_input(&payment.data)); + let payment_func = try_tx_fus!(SWAP_CONTRACT.function("ethPayment")); + let decoded = try_tx_fus!(payment_func.decode_input(&payment.data)); let state_f = self.payment_status(swap_contract_address, decoded[0].clone()); - Box::new(state_f.and_then(move |state| -> EthTxFut { - if state != PAYMENT_STATE_SENT.into() { - return Box::new(futures01::future::err(ERRL!( - "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", - payment, - state - ))); - } + Box::new( + state_f + .map_err(TransactionFutErr::Plain) + .and_then(move |state| -> EthTxFut { + if state != PAYMENT_STATE_SENT.into() { + return Box::new(futures01::future::err(TransactionFutErr::Plain(ERRL!( + "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", + payment, + state + )))); + } - let value = payment.value; - let data = try_fus!(refund_func.encode_input(&[ - decoded[0].clone(), - Token::Uint(value), - decoded[2].clone(), - Token::Address(Address::default()), - decoded[1].clone(), - ])); - - clone.sign_and_send_transaction( - 0.into(), - Action::Call(swap_contract_address), - data, - U256::from(150_000), - ) - })) + let value = payment.value; + let data = try_tx_fus!(refund_func.encode_input(&[ + decoded[0].clone(), + Token::Uint(value), + decoded[2].clone(), + Token::Address(Address::default()), + decoded[1].clone(), + ])); + + clone.sign_and_send_transaction( + 0.into(), + Action::Call(swap_contract_address), + data, + U256::from(150_000), + ) + }), + ) }, EthCoinType::Erc20 { platform: _, token_addr, } => { - let payment_func = try_fus!(SWAP_CONTRACT.function("erc20Payment")); - let decoded = try_fus!(payment_func.decode_input(&payment.data)); + let payment_func = try_tx_fus!(SWAP_CONTRACT.function("erc20Payment")); + let decoded = try_tx_fus!(payment_func.decode_input(&payment.data)); let state_f = self.payment_status(swap_contract_address, decoded[0].clone()); - Box::new(state_f.and_then(move |state| -> EthTxFut { - if state != PAYMENT_STATE_SENT.into() { - return Box::new(futures01::future::err(ERRL!( - "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", - payment, - state - ))); - } + Box::new( + state_f + .map_err(TransactionFutErr::Plain) + .and_then(move |state| -> EthTxFut { + if state != PAYMENT_STATE_SENT.into() { + return Box::new(futures01::future::err(TransactionFutErr::Plain(ERRL!( + "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", + payment, + state + )))); + } - let data = try_fus!(refund_func.encode_input(&[ - decoded[0].clone(), - decoded[1].clone(), - decoded[4].clone(), - Token::Address(token_addr), - decoded[3].clone(), - ])); - - clone.sign_and_send_transaction( - 0.into(), - Action::Call(swap_contract_address), - data, - U256::from(150_000), - ) - })) + let data = try_tx_fus!(refund_func.encode_input(&[ + decoded[0].clone(), + decoded[1].clone(), + decoded[4].clone(), + Token::Address(token_addr), + decoded[3].clone(), + ])); + + clone.sign_and_send_transaction( + 0.into(), + Action::Call(swap_contract_address), + data, + U256::from(150_000), + ) + }), + ) }, } } @@ -2535,13 +2550,13 @@ impl EthCoin { let coin = self.clone(); let fut = async move { let token_addr = match coin.coin_type { - EthCoinType::Eth => return ERR!("'approve' is expected to be call for ERC20 coins only"), + EthCoinType::Eth => return TX_PLAIN_ERR!("'approve' is expected to be call for ERC20 coins only"), EthCoinType::Erc20 { token_addr, .. } => token_addr, }; - let function = try_s!(ERC20_CONTRACT.function("approve")); - let data = try_s!(function.encode_input(&[Token::Address(spender), Token::Uint(amount)])); + let function = try_tx_s!(ERC20_CONTRACT.function("approve")); + let data = try_tx_s!(function.encode_input(&[Token::Address(spender), Token::Uint(amount)])); - let gas_limit = try_s!( + let gas_limit = try_tx_s!( coin.estimate_gas_for_contract_call(token_addr, Bytes::from(data.clone())) .compat() .await @@ -2550,7 +2565,6 @@ impl EthCoin { coin.sign_and_send_transaction(0.into(), Action::Call(token_addr), data, gas_limit) .compat() .await - .map_err(|e| ERRL!("{}", e)) }; Box::new(fut.boxed().compat()) } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 921751dbe5..aeaa74a6f6 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -97,27 +97,38 @@ macro_rules! try_f { }; } -/// `TransactionErr:PlainError` compatible `try_fus` macro. +/// `TransactionFutErr` compatible `try_fus` macro. macro_rules! try_tx_fus { ($e: expr) => { match $e { Ok(ok) => ok, Err(err) => { - return Box::new(futures01::future::err(crate::TransactionErr::PlainError(ERRL!( + return Box::new(futures01::future::err(crate::TransactionFutErr::Plain(ERRL!( "{:?}", err )))) }, } }; + ($e: expr, $tx: expr) => { + match $e { + Ok(ok) => ok, + Err(err) => { + return Box::new(futures01::future::err(crate::TransactionFutErr::TxRecoverable( + TransactionEnum::from($tx), + ERRL!("{:?}", err), + ))) + }, + } + }; } -/// `TransactionErr:PlainError` compatible `try_s` macro. +/// `TransactionFutErr` compatible `try_s` macro. macro_rules! try_tx_s { ($e: expr) => { match $e { Ok(ok) => ok, Err(err) => { - return Err(crate::TransactionErr::PlainError(format!( + return Err(crate::TransactionFutErr::Plain(format!( "{}:{}] {:?}", file!(), line!(), @@ -126,12 +137,33 @@ macro_rules! try_tx_s { }, } }; + ($e: expr, $tx: expr) => { + match $e { + Ok(ok) => ok, + Err(err) => { + return Err(crate::TransactionFutErr::TxRecoverable( + TransactionEnum::from($tx), + format!("{}:{}] {:?}", file!(), line!(), err), + )) + }, + } + }; } -/// `TransactionErr:PlainError` compatible `ERR` macro. -macro_rules! TX_ERR { - ($format: expr, $($args: tt)+) => { Err(crate::TransactionErr::PlainError((ERRL!($format, $($args)+)))) }; - ($format: expr) => { Err(crate::TransactionErr::PlainError(ERRL!($format))) } +/// `TransactionFutErr:Plain` compatible `ERR` macro. +macro_rules! TX_PLAIN_ERR { + ($format: expr, $($args: tt)+) => { Err(crate::TransactionFutErr::Plain((ERRL!($format, $($args)+)))) }; + ($format: expr) => { Err(crate::TransactionFutErr::Plain(ERRL!($format))) } +} + +/// `TransactionFutErr:TxRecoverable` compatible `ERR` macro. +macro_rules! TX_RECOVERABLE_ERR { + ($tx: expr, $format: expr, $($args: tt)+) => { + Err(crate::TransactionFutErr::TxRecoverable(TransactionEnum::from($tx), ERRL!($format, $($args)+))) + }; + ($tx: expr, $format: expr) => { + Err(crate::TransactionFutErr::TxRecoverable(TransactionEnum::from($tx), ERRL!($format))) + }; } pub mod coin_balance; @@ -315,19 +347,19 @@ impl Deref for TransactionEnum { #[derive(Debug, Clone)] #[allow(clippy::large_enum_variant)] -pub enum TransactionErr { +pub enum TransactionFutErr { /// Keeps transactions while throwing errors. - TxRecoverableError(TransactionEnum, String), + TxRecoverable(TransactionEnum, String), /// Simply for plain error messages. - PlainError(String), + Plain(String), } -impl TransactionErr { +impl TransactionFutErr { /// Returns transaction if the error includes it. #[inline] pub fn get_tx(&self) -> Option { match self { - TransactionErr::TxRecoverableError(tx, _) => Some(tx.clone()), + TransactionFutErr::TxRecoverable(tx, _) => Some(tx.clone()), _ => None, } } @@ -336,13 +368,13 @@ impl TransactionErr { /// Returns plain text part of error. pub fn get_plain_text_format(&self) -> String { match self { - TransactionErr::TxRecoverableError(_, err) => err.to_string(), - TransactionErr::PlainError(err) => err.to_string(), + TransactionFutErr::TxRecoverable(_, err) => err.to_string(), + TransactionFutErr::Plain(err) => err.to_string(), } } } -pub type TransactionFut = Box + Send>; +pub type TransactionFut = Box + Send>; #[derive(Debug, PartialEq)] pub enum FoundSwapTxSpend { @@ -1657,7 +1689,7 @@ impl Deref for MmCoinEnum { } impl MmCoinEnum { - pub fn is_utxo_and_in_native_mode(&self) -> bool { + pub fn is_utxo_in_native_mode(&self) -> bool { match self { MmCoinEnum::UtxoCoin(ref c) => c.as_ref().rpc_client.is_native(), MmCoinEnum::QtumCoin(ref c) => c.as_ref().rpc_client.is_native(), diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 0a5f1d3fc8..a0ce24ac3a 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -14,7 +14,7 @@ use crate::utxo::{qtum, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy use crate::{BalanceError, BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, RawTransactionFut, RawTransactionRequest, SwapOps, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, - TransactionDetails, TransactionEnum, TransactionErr, TransactionFut, TransactionType, + TransactionDetails, TransactionEnum, TransactionFut, TransactionFutErr, TransactionType, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, WithdrawResult}; use async_trait::async_trait; @@ -447,7 +447,7 @@ impl Qrc20Coin { pub async fn send_contract_calls( &self, outputs: Vec, - ) -> Result { + ) -> Result { // TODO: we need to somehow refactor it using RecentlySpentOutpoints cache // Move over all QRC20 tokens should share the same cache with each other and base QTUM coin let _utxo_lock = UTXO_LOCK.lock().await; @@ -458,15 +458,10 @@ impl Qrc20Coin { .generate_qrc20_transaction(outputs) .await .mm_err(|e| e.into_withdraw_error(platform, decimals)) - .map_err(|e| TransactionErr::PlainError(ERRL!("{}", e)))?; + .map_err(|e| TransactionFutErr::Plain(ERRL!("{}", e)))?; let _tx = match self.utxo.rpc_client.send_transaction(&signed).compat().await { Ok(tx) => tx, - Err(err) => { - return Err(TransactionErr::TxRecoverableError( - TransactionEnum::from(signed), - ERRL!("{:?}", err), - )); - }, + Err(err) => return TX_RECOVERABLE_ERR!(signed, "{:?}", err), }; Ok(signed.into()) } @@ -1106,7 +1101,7 @@ impl MarketCoinOps for Qrc20Coin { let fut = async move { selfi .wait_for_tx_spend_impl(tx, wait_until, from_block) - .map_err(TransactionErr::PlainError) + .map_err(TransactionFutErr::Plain) .await }; Box::new(fut.boxed().compat()) diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index ec8ae03e59..decf7ff7ae 100644 --- a/mm2src/coins/qrc20/qrc20_tests.rs +++ b/mm2src/coins/qrc20/qrc20_tests.rs @@ -951,10 +951,10 @@ fn test_send_contract_calls_recoverable_tx() { let tx_err = block_on(coin.send_contract_calls(vec![transfer_output])).unwrap_err(); - // The error variant should equal to `TxRecoverableError` + // The error variant should equal to `TxRecoverable` assert_eq!( discriminant(&tx_err), - discriminant(&TransactionErr::TxRecoverableError( + discriminant(&TransactionFutErr::TxRecoverable( TransactionEnum::from(tx), String::new() )) diff --git a/mm2src/coins/qrc20/swap.rs b/mm2src/coins/qrc20/swap.rs index 1d22d513c4..22d98e1629 100644 --- a/mm2src/coins/qrc20/swap.rs +++ b/mm2src/coins/qrc20/swap.rs @@ -37,13 +37,13 @@ impl Qrc20Coin { secret_hash: Vec, receiver_addr: H160, swap_contract_address: H160, - ) -> Result { + ) -> Result { let balance = try_tx_s!(self.my_spendable_balance().compat().await); let balance = try_tx_s!(wei_from_big_decimal(&balance, self.utxo.decimals)); // Check the balance to avoid unnecessary burning of gas if balance < value { - return TX_ERR!("Balance {} is less than value {}", balance, value); + return TX_PLAIN_ERR!("Balance {} is less than value {}", balance, value); } let outputs = try_tx_s!( @@ -67,14 +67,14 @@ impl Qrc20Coin { payment_tx: UtxoTx, swap_contract_address: H160, secret: Vec, - ) -> Result { + ) -> Result { let Erc20PaymentDetails { swap_id, value, sender, .. } = try_tx_s!(self.erc20_payment_details_from_tx(&payment_tx).await); let status = try_tx_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { - return TX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); + return TX_PLAIN_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); } let spend_output = @@ -86,7 +86,7 @@ impl Qrc20Coin { &self, swap_contract_address: H160, payment_tx: UtxoTx, - ) -> Result { + ) -> Result { let Erc20PaymentDetails { swap_id, value, @@ -97,7 +97,7 @@ impl Qrc20Coin { let status = try_tx_s!(self.payment_status(&swap_contract_address, swap_id.clone()).await); if status != eth::PAYMENT_STATE_SENT.into() { - return TX_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); + return TX_PLAIN_ERR!("Payment state is not PAYMENT_STATE_SENT, got {}", status); } let refund_output = diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 75e37617d2..15d135e44f 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -97,7 +97,7 @@ use crate::coin_balance::{EnableCoinScanPolicy, HDAddressBalanceScanner}; use crate::hd_wallet::{HDAccountOps, HDAccountsMutex, HDAddress, HDWalletCoinOps, HDWalletOps, InvalidBip44ChainError}; use crate::hd_wallet_storage::{HDAccountStorageItem, HDWalletCoinStorage, HDWalletStorageError, HDWalletStorageResult}; use crate::utxo::utxo_block_header_storage::BlockHeaderStorageError; -use crate::TransactionErr; +use crate::TransactionFutErr; use utxo_block_header_storage::BlockHeaderStorage; #[cfg(not(target_arch = "wasm32"))] pub mod tx_cache; #[cfg(target_arch = "wasm32")] @@ -1471,7 +1471,7 @@ pub fn sat_from_big_decimal(amount: &BigDecimal, decimals: u8) -> NumConversResu async fn send_outputs_from_my_address_impl( coin: T, outputs: Vec, -) -> Result +) -> Result where T: UtxoCommonOps, { @@ -1488,7 +1488,7 @@ async fn generate_and_send_tx( fee_policy: FeePolicy, mut recently_spent: AsyncMutexGuard<'_, RecentlySpentOutPoints>, outputs: Vec, -) -> Result +) -> Result where T: AsRef + UtxoTxGenerationOps + UtxoTxBroadcastOps, { @@ -1530,12 +1530,7 @@ where match coin.broadcast_tx(&signed).await { Ok(_) => (), - Err(err) => { - return Err(TransactionErr::TxRecoverableError( - TransactionEnum::from(signed), - ERRL!("{:?}", err), - )); - }, + Err(err) => return TX_RECOVERABLE_ERR!(signed, "{:?}", err), }; recently_spent.add_spent(spent_unspents, signed.hash(), signed.outputs.clone()); diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 8be406f981..024b29c865 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -13,7 +13,7 @@ use crate::utxo::{generate_and_send_tx, sat_from_big_decimal, ActualTxFee, Addit use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, RawTransactionFut, RawTransactionRequest, SwapOps, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, - TradePreimageValue, TransactionDetails, TransactionEnum, TransactionErr, TransactionFut, TxFeeDetails, + TradePreimageValue, TransactionDetails, TransactionEnum, TransactionFutnFutErrErrErrErrErr, TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; @@ -409,7 +409,7 @@ impl SlpToken { Ok((preimage, recently_spent)) } - pub async fn send_slp_outputs(&self, slp_outputs: Vec) -> Result { + pub async fn send_slp_outputs(&self, slp_outputs: Vec) -> Result { let (preimage, recently_spent) = try_tx_s!(self.generate_slp_tx_preimage(slp_outputs).await); generate_and_send_tx( self, @@ -429,7 +429,7 @@ impl SlpToken { time_lock: u32, secret_hash: &[u8], amount: u64, - ) -> Result { + ) -> Result { let payment_script = payment_script(time_lock, secret_hash, my_pub, other_pub); let script_pubkey = ScriptBuilder::build_p2sh(&dhash160(&payment_script).into()).to_bytes(); let slp_out = SlpOutput { amount, script_pubkey }; @@ -1295,7 +1295,7 @@ impl SwapOps for SlpToken { ); Ok(tx.into()) }; - Box::new(fut.boxed().compat().map_err(TransactionErr::PlainError)) + Box::new(fut.boxed().compat().map_err(TransactionFutErr::Plain)) } fn send_maker_refunds_payment( @@ -1794,7 +1794,7 @@ pub fn slp_addr_from_pubkey_str(pubkey: &str, prefix: &str) -> Result err, - TransactionErr::PlainError(err) => err, + TransactionFutErr::TxRecoverable(_tx, err) => err, + TransactionFutErr::Plain(err) => err, }; println!("{:?}", err); @@ -2063,10 +2063,10 @@ mod slp_tests { e @ _ => panic!("Unexpected err {:?}", e), }; - // The error variant should equal to `TxRecoverableError` + // The error variant should equal to `TxRecoverable` assert_eq!( discriminant(&tx_err), - discriminant(&TransactionErr::TxRecoverableError( + discriminant(&TransactionFutErr::TxRecoverable( TransactionEnum::from(utxo_tx), String::new() )) diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index f05552ae8f..d1f3433b53 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1036,7 +1036,7 @@ pub fn send_maker_payment( Either::B( client .import_address(&addr_string, &addr_string, false) - .map_err(|e| TransactionErr::PlainError(ERRL!("{}", e))) + .map_err(|e| TransactionFutErr::Plain(ERRL!("{}", e))) .and_then(move |_| send_outputs_from_my_address(coin, outputs)), ) }, @@ -1071,7 +1071,7 @@ pub fn send_taker_payment( Either::B( client .import_address(&addr_string, &addr_string, false) - .map_err(|e| TransactionErr::PlainError(ERRL!("{}", e))) + .map_err(|e| TransactionFutErr::Plain(ERRL!("{}", e))) .and_then(move |_| send_outputs_from_my_address(coin, outputs)), ) }, @@ -1126,12 +1126,7 @@ pub fn send_maker_spends_taker_payment( let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { Ok(_) => (), - Err(err) => { - return Err(TransactionErr::TxRecoverableError( - TransactionEnum::from(transaction), - ERRL!("{:?}", err), - )); - }, + Err(err) => return TX_RECOVERABLE_ERR!(transaction, "{:?}", err), }; Ok(transaction.into()) @@ -1186,12 +1181,7 @@ pub fn send_taker_spends_maker_payment( let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { Ok(_) => (), - Err(err) => { - return Err(TransactionErr::TxRecoverableError( - TransactionEnum::from(transaction), - ERRL!("{:?}", err), - )); - }, + Err(err) => return TX_RECOVERABLE_ERR!(transaction, "{:?}", err), }; Ok(transaction.into()) @@ -1211,7 +1201,7 @@ pub fn send_taker_refunds_payment( let my_address = try_tx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); let mut prev_tx: UtxoTx = - try_tx_fus!(deserialize(taker_payment_tx).map_err(|e| TransactionErr::PlainError(format!("{:?}", e)))); + try_tx_fus!(deserialize(taker_payment_tx).map_err(|e| TransactionFutErr::Plain(format!("{:?}", e)))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default().push_opcode(Opcode::OP_1).into_script(); let redeem_script = payment_script( @@ -1244,12 +1234,7 @@ pub fn send_taker_refunds_payment( let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { Ok(_) => (), - Err(err) => { - return Err(TransactionErr::TxRecoverableError( - TransactionEnum::from(transaction), - ERRL!("{:?}", err), - )); - }, + Err(err) => return TX_RECOVERABLE_ERR!(transaction, "{:?}", err), }; Ok(transaction.into()) @@ -1301,12 +1286,7 @@ pub fn send_maker_refunds_payment( let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); match tx_fut.await { Ok(_) => (), - Err(err) => { - return Err(TransactionErr::TxRecoverableError( - TransactionEnum::from(transaction), - ERRL!("{:?}", err), - )); - }, + Err(err) => return TX_RECOVERABLE_ERR!(transaction, "{:?}", err), }; Ok(transaction.into()) @@ -1764,7 +1744,7 @@ pub fn wait_for_output_spend( }; if now_ms() / 1000 > wait_until { - return TX_ERR!( + return TX_PLAIN_ERR!( "Waited too long until {} for transaction {:?} {} to be spent ", wait_until, tx, diff --git a/mm2src/coins/utxo/utxo_tests.rs b/mm2src/coins/utxo/utxo_tests.rs index a97f6a7e09..07a25044a7 100644 --- a/mm2src/coins/utxo/utxo_tests.rs +++ b/mm2src/coins/utxo/utxo_tests.rs @@ -201,10 +201,10 @@ fn test_send_maker_spends_taker_payment_recoverable_tx() { let tx: UtxoTx = deserialize(tx_hex.as_slice()).unwrap(); - // The error variant should equal to `TxRecoverableError` + // The error variant should equal to `TxRecoverable` assert_eq!( discriminant(&tx_err), - discriminant(&TransactionErr::TxRecoverableError( + discriminant(&TransactionFutErr::TxRecoverable( TransactionEnum::from(tx), String::new() )) diff --git a/mm2src/docker_tests/qrc20_tests.rs b/mm2src/docker_tests/qrc20_tests.rs index e854cd7043..63bc27b91c 100644 --- a/mm2src/docker_tests/qrc20_tests.rs +++ b/mm2src/docker_tests/qrc20_tests.rs @@ -8,7 +8,7 @@ use coins::utxo::rpc_clients::UtxoRpcClientEnum; use coins::utxo::utxo_common::big_decimal_from_sat; use coins::utxo::{UtxoActivationParams, UtxoCommonOps}; use coins::{FeeApproxStage, FoundSwapTxSpend, MarketCoinOps, MmCoin, SwapOps, TradePreimageValue, TransactionEnum, - TransactionErr, ValidatePaymentInput}; + TransactionFutErr, ValidatePaymentInput}; use common::log::debug; use common::mm_ctx::{MmArc, MmCtxBuilder}; use common::{temp_dir, DEX_FEE_ADDR_RAW_PUBKEY}; @@ -738,8 +738,8 @@ fn test_wait_for_tx_spend() { .expect_err("Expected 'Waited too long' error"); let err = match tx_err { - TransactionErr::TxRecoverableError(_tx, err) => err, - TransactionErr::PlainError(err) => err, + TransactionFutErr::TxRecoverable(_tx, err) => err, + TransactionFutErr::Plain(err) => err, }; log!("error: "[err]); assert!(err.contains("Waited too long")); diff --git a/mm2src/rpc/lp_commands.rs b/mm2src/rpc/lp_commands.rs index 8cf4b81bad..4726686877 100644 --- a/mm2src/rpc/lp_commands.rs +++ b/mm2src/rpc/lp_commands.rs @@ -131,7 +131,7 @@ pub async fn enable(ctx: MmArc, req: Json) -> Result>, String> let res = try_s!(json::to_vec(&res)); let res = try_s!(Response::builder().body(res)); - if coin.is_utxo_and_in_native_mode() { + if coin.is_utxo_in_native_mode() { subscribe_to_topic(&ctx, tx_helper_topic(coin.ticker())); } From d456326e1d7a66107f39a51c1c821d4a3a76bb41 Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Fri, 29 Apr 2022 16:09:25 +0300 Subject: [PATCH 44/48] fix auto-format's bug Signed-off-by: ozkanonur --- mm2src/coins/utxo/slp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index 024b29c865..193058c403 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -13,7 +13,7 @@ use crate::utxo::{generate_and_send_tx, sat_from_big_decimal, ActualTxFee, Addit use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, RawTransactionFut, RawTransactionRequest, SwapOps, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, - TradePreimageValue, TransactionDetails, TransactionEnum, TransactionFutnFutErrErrErrErrErr, TxFeeDetails, + TradePreimageValue, TransactionDetails, TransactionEnum, TransactionFut, TransactionFutErr, TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; From 9444edabe014b1d5519e1784159f9234e87f16ce Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Fri, 29 Apr 2022 16:54:34 +0300 Subject: [PATCH 45/48] remove unnecessary type casting --- mm2src/coins/eth.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 758f4884af..1f3964656f 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -689,7 +689,6 @@ impl SwapOps for EthCoin { Box::new( self.send_to_address(address, try_tx_fus!(wei_from_big_decimal(&amount, self.decimals))) - .map_err(|e| TransactionFutErr::Plain(ERRL!("{:?}", e))) .map(TransactionEnum::from), ) } From 5ba0dd1684ce879b4724c6c9badcbe524537f228 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Sat, 30 Apr 2022 03:44:59 +0300 Subject: [PATCH 46/48] resolve pr notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/lp_coins.rs | 1 + mm2src/coins/qrc20.rs | 5 +---- mm2src/coins/qrc20/qrc20_tests.rs | 3 +-- mm2src/coins/solana.rs | 4 +--- mm2src/coins/utxo.rs | 5 +---- mm2src/coins/utxo/utxo_common.rs | 24 ++++++------------------ mm2src/docker_tests/qrc20_tests.rs | 5 +---- 7 files changed, 12 insertions(+), 35 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index cbb8c89b90..a4489a45f5 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -156,6 +156,7 @@ macro_rules! TX_PLAIN_ERR { } /// `TransactionFutErr:TxRecoverable` compatible `ERR` macro. +#[allow(unused_macros)] macro_rules! TX_RECOVERABLE_ERR { ($tx: expr, $format: expr, $($args: tt)+) => { Err(crate::TransactionFutErr::TxRecoverable(TransactionEnum::from($tx), ERRL!($format, $($args)+))) diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index a0ce24ac3a..593d4fd448 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -459,10 +459,7 @@ impl Qrc20Coin { .await .mm_err(|e| e.into_withdraw_error(platform, decimals)) .map_err(|e| TransactionFutErr::Plain(ERRL!("{}", e)))?; - let _tx = match self.utxo.rpc_client.send_transaction(&signed).compat().await { - Ok(tx) => tx, - Err(err) => return TX_RECOVERABLE_ERR!(signed, "{:?}", err), - }; + try_tx_s!(self.utxo.rpc_client.send_transaction(&signed).compat().await, signed); Ok(signed.into()) } diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index b42757492b..7aa3953d2e 100644 --- a/mm2src/coins/qrc20/qrc20_tests.rs +++ b/mm2src/coins/qrc20/qrc20_tests.rs @@ -1,5 +1,3 @@ -use std::mem::discriminant; - use super::*; use crate::TxFeeDetails; use bigdecimal::Zero; @@ -9,6 +7,7 @@ use common::{block_on, DEX_FEE_ADDR_RAW_PUBKEY}; use itertools::Itertools; use mocktopus::mocking::{MockResult, Mockable}; use rpc::v1::types::ToTxHash; +use std::mem::discriminant; const EXPECTED_TX_FEE: i64 = 1000; const CONTRACT_CALL_GAS_FEE: i64 = (QRC20_GAS_LIMIT_DEFAULT * QRC20_GAS_PRICE_DEFAULT) as i64; diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index e14836d667..324d4d71a1 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -377,9 +377,7 @@ impl MarketCoinOps for SolanaCoin { let coin = self.clone(); let tx = tx.to_owned(); let fut = async move { - let tx: Transaction = deserialize(tx.as_slice()) - .map_to_mm(|e| e) - .map_err(|e| format!("{:?}", e))?; + let tx = try_s!(deserialize(tx.as_slice())); let signature = coin.rpc().send_transaction(&tx).await.map_err(|e| format!("{:?}", e))?; Ok(signature.to_string()) }; diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 201cf19e71..57cf4a6133 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -1530,10 +1530,7 @@ where coin.as_ref().conf.fork_id )); - match coin.broadcast_tx(&signed).await { - Ok(_) => (), - Err(err) => return TX_RECOVERABLE_ERR!(signed, "{:?}", err), - }; + try_tx_s!(coin.broadcast_tx(&signed).await, signed); recently_spent.add_spent(spent_unspents, signed.hash(), signed.outputs.clone()); diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 5cb91db1f8..b60395c917 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1125,10 +1125,7 @@ pub fn send_maker_spends_taker_payment( ); let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); - match tx_fut.await { - Ok(_) => (), - Err(err) => return TX_RECOVERABLE_ERR!(transaction, "{:?}", err), - }; + try_tx_s!(tx_fut.await, transaction); Ok(transaction.into()) }; @@ -1180,10 +1177,7 @@ pub fn send_taker_spends_maker_payment( ); let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); - match tx_fut.await { - Ok(_) => (), - Err(err) => return TX_RECOVERABLE_ERR!(transaction, "{:?}", err), - }; + try_tx_s!(tx_fut.await, transaction); Ok(transaction.into()) }; @@ -1233,10 +1227,7 @@ pub fn send_taker_refunds_payment( ); let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); - match tx_fut.await { - Ok(_) => (), - Err(err) => return TX_RECOVERABLE_ERR!(transaction, "{:?}", err), - }; + try_tx_s!(tx_fut.await, transaction); Ok(transaction.into()) }; @@ -1285,10 +1276,7 @@ pub fn send_maker_refunds_payment( ); let tx_fut = coin.as_ref().rpc_client.send_transaction(&transaction).compat(); - match tx_fut.await { - Ok(_) => (), - Err(err) => return TX_RECOVERABLE_ERR!(transaction, "{:?}", err), - }; + try_tx_s!(tx_fut.await, transaction); Ok(transaction.into()) }; @@ -1668,7 +1656,7 @@ where Box::new(fut.boxed().compat()) } -/// Receives raw transaction as input and returns tx hash in hexadecimal format +/// Takes raw transaction as input and returns tx hash in hexadecimal format pub fn send_raw_tx(coin: &UtxoCoinFields, tx: &str) -> Box + Send> { let bytes = try_fus!(hex::decode(tx)); Box::new( @@ -1679,7 +1667,7 @@ pub fn send_raw_tx(coin: &UtxoCoinFields, tx: &str) -> Box err, - TransactionFutErr::Plain(err) => err, - }; + let err = tx_err.get_plain_text_format(); log!("error: "[err]); assert!(err.contains("Waited too long")); From f87cef3ba6d7802fcb720e4a69e43c27f653e14b Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Sat, 30 Apr 2022 14:04:50 +0300 Subject: [PATCH 47/48] resolve pr notes Signed-off-by: ozkanonur --- mm2src/coins/eth.rs | 24 +++++------ mm2src/coins/lp_coins.rs | 64 ++++++++++++++++++++---------- mm2src/coins/qrc20.rs | 8 ++-- mm2src/coins/qrc20/qrc20_tests.rs | 5 +-- mm2src/coins/qrc20/swap.rs | 6 +-- mm2src/coins/utxo.rs | 6 +-- mm2src/coins/utxo/slp.rs | 16 ++++---- mm2src/coins/utxo/utxo_common.rs | 6 +-- mm2src/coins/utxo/utxo_tests.rs | 5 +-- mm2src/coins/z_coin.rs | 8 ++-- mm2src/coins/z_coin/z_htlc.rs | 22 +++++++--- mm2src/docker_tests/qrc20_tests.rs | 2 +- 12 files changed, 99 insertions(+), 73 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 1f3964656f..884cdd5234 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -66,7 +66,7 @@ pub use ethcore_transaction::SignedTransaction as SignedEthTx; pub use rlp; mod web3_transport; -use crate::{TransactionFut, TransactionFutErr, ValidatePaymentInput}; +use crate::{TransactionErr, TransactionFut, ValidatePaymentInput}; use common::mm_number::MmNumber; use common::privkey::key_pair_from_secret; use web3_transport::{EthFeeHistoryNamespace, Web3Transport}; @@ -1346,7 +1346,7 @@ lazy_static! { static ref NONCE_LOCK: TimedAsyncMutex<()> = TimedAsyncMutex::new(()); } -type EthTxFut = Box + Send + 'static>; +type EthTxFut = Box + Send + 'static>; async fn sign_and_send_transaction_impl( ctx: MmArc, @@ -1355,7 +1355,7 @@ async fn sign_and_send_transaction_impl( action: Action, data: Vec, gas: U256, -) -> Result { +) -> Result { let mut status = ctx.log.status_handle(); macro_rules! tags { () => { @@ -2231,7 +2231,7 @@ impl EthCoin { } => { let allowance_fut = self .allowance(swap_contract_address) - .map_err(|e| TransactionFutErr::Plain(ERRL!("{}", e))); + .map_err(|e| TransactionErr::Plain(ERRL!("{}", e))); let function = try_tx_fus!(SWAP_CONTRACT.function("erc20Payment")); let data = try_tx_fus!(function.encode_input(&[ @@ -2288,10 +2288,10 @@ impl EthCoin { let state_f = self.payment_status(swap_contract_address, decoded[0].clone()); Box::new( state_f - .map_err(TransactionFutErr::Plain) + .map_err(TransactionErr::Plain) .and_then(move |state| -> EthTxFut { if state != PAYMENT_STATE_SENT.into() { - return Box::new(futures01::future::err(TransactionFutErr::Plain(ERRL!( + return Box::new(futures01::future::err(TransactionErr::Plain(ERRL!( "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", payment, state @@ -2326,10 +2326,10 @@ impl EthCoin { Box::new( state_f - .map_err(TransactionFutErr::Plain) + .map_err(TransactionErr::Plain) .and_then(move |state| -> EthTxFut { if state != PAYMENT_STATE_SENT.into() { - return Box::new(futures01::future::err(TransactionFutErr::Plain(ERRL!( + return Box::new(futures01::future::err(TransactionErr::Plain(ERRL!( "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", payment, state @@ -2367,10 +2367,10 @@ impl EthCoin { let state_f = self.payment_status(swap_contract_address, decoded[0].clone()); Box::new( state_f - .map_err(TransactionFutErr::Plain) + .map_err(TransactionErr::Plain) .and_then(move |state| -> EthTxFut { if state != PAYMENT_STATE_SENT.into() { - return Box::new(futures01::future::err(TransactionFutErr::Plain(ERRL!( + return Box::new(futures01::future::err(TransactionErr::Plain(ERRL!( "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", payment, state @@ -2404,10 +2404,10 @@ impl EthCoin { let state_f = self.payment_status(swap_contract_address, decoded[0].clone()); Box::new( state_f - .map_err(TransactionFutErr::Plain) + .map_err(TransactionErr::Plain) .and_then(move |state| -> EthTxFut { if state != PAYMENT_STATE_SENT.into() { - return Box::new(futures01::future::err(TransactionFutErr::Plain(ERRL!( + return Box::new(futures01::future::err(TransactionErr::Plain(ERRL!( "Payment {:?} state is not PAYMENT_STATE_SENT, got {}", payment, state diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index a4489a45f5..c2dfbf1ae5 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -96,23 +96,19 @@ macro_rules! try_f { }; } -/// `TransactionFutErr` compatible `try_fus` macro. +/// `TransactionErr` compatible `try_fus` macro. macro_rules! try_tx_fus { ($e: expr) => { match $e { Ok(ok) => ok, - Err(err) => { - return Box::new(futures01::future::err(crate::TransactionFutErr::Plain(ERRL!( - "{:?}", err - )))) - }, + Err(err) => return Box::new(futures01::future::err(crate::TransactionErr::Plain(ERRL!("{:?}", err)))), } }; ($e: expr, $tx: expr) => { match $e { Ok(ok) => ok, Err(err) => { - return Box::new(futures01::future::err(crate::TransactionFutErr::TxRecoverable( + return Box::new(futures01::future::err(crate::TransactionErr::TxRecoverable( TransactionEnum::from($tx), ERRL!("{:?}", err), ))) @@ -121,13 +117,13 @@ macro_rules! try_tx_fus { }; } -/// `TransactionFutErr` compatible `try_s` macro. +/// `TransactionErr` compatible `try_s` macro. macro_rules! try_tx_s { ($e: expr) => { match $e { Ok(ok) => ok, Err(err) => { - return Err(crate::TransactionFutErr::Plain(format!( + return Err(crate::TransactionErr::Plain(format!( "{}:{}] {:?}", file!(), line!(), @@ -140,7 +136,7 @@ macro_rules! try_tx_s { match $e { Ok(ok) => ok, Err(err) => { - return Err(crate::TransactionFutErr::TxRecoverable( + return Err(crate::TransactionErr::TxRecoverable( TransactionEnum::from($tx), format!("{}:{}] {:?}", file!(), line!(), err), )) @@ -149,20 +145,44 @@ macro_rules! try_tx_s { }; } -/// `TransactionFutErr:Plain` compatible `ERR` macro. +/// `ZP2SHSpendError` compatible `TransactionErr` handling macro. +macro_rules! try_ztx_s { + ($e: expr) => { + match $e { + Ok(ok) => ok, + Err(err) => { + if let Some(tx) = err.get_inner().get_tx() { + return Err(crate::TransactionErr::TxRecoverable( + tx, + format!("{}:{}] {:?}", file!(), line!(), err), + )); + } + + return Err(crate::TransactionErr::Plain(format!( + "{}:{}] {:?}", + file!(), + line!(), + err + ))); + }, + } + }; +} + +/// `TransactionErr:Plain` compatible `ERR` macro. macro_rules! TX_PLAIN_ERR { - ($format: expr, $($args: tt)+) => { Err(crate::TransactionFutErr::Plain((ERRL!($format, $($args)+)))) }; - ($format: expr) => { Err(crate::TransactionFutErr::Plain(ERRL!($format))) } + ($format: expr, $($args: tt)+) => { Err(crate::TransactionErr::Plain((ERRL!($format, $($args)+)))) }; + ($format: expr) => { Err(crate::TransactionErr::Plain(ERRL!($format))) } } -/// `TransactionFutErr:TxRecoverable` compatible `ERR` macro. +/// `TransactionErr:TxRecoverable` compatible `ERR` macro. #[allow(unused_macros)] macro_rules! TX_RECOVERABLE_ERR { ($tx: expr, $format: expr, $($args: tt)+) => { - Err(crate::TransactionFutErr::TxRecoverable(TransactionEnum::from($tx), ERRL!($format, $($args)+))) + Err(crate::TransactionErr::TxRecoverable(TransactionEnum::from($tx), ERRL!($format, $($args)+))) }; ($tx: expr, $format: expr) => { - Err(crate::TransactionFutErr::TxRecoverable(TransactionEnum::from($tx), ERRL!($format))) + Err(crate::TransactionErr::TxRecoverable(TransactionEnum::from($tx), ERRL!($format))) }; } @@ -390,19 +410,19 @@ impl Deref for TransactionEnum { #[derive(Debug, Clone)] #[allow(clippy::large_enum_variant)] -pub enum TransactionFutErr { +pub enum TransactionErr { /// Keeps transactions while throwing errors. TxRecoverable(TransactionEnum, String), /// Simply for plain error messages. Plain(String), } -impl TransactionFutErr { +impl TransactionErr { /// Returns transaction if the error includes it. #[inline] pub fn get_tx(&self) -> Option { match self { - TransactionFutErr::TxRecoverable(tx, _) => Some(tx.clone()), + TransactionErr::TxRecoverable(tx, _) => Some(tx.clone()), _ => None, } } @@ -411,13 +431,13 @@ impl TransactionFutErr { /// Returns plain text part of error. pub fn get_plain_text_format(&self) -> String { match self { - TransactionFutErr::TxRecoverable(_, err) => err.to_string(), - TransactionFutErr::Plain(err) => err.to_string(), + TransactionErr::TxRecoverable(_, err) => err.to_string(), + TransactionErr::Plain(err) => err.to_string(), } } } -pub type TransactionFut = Box + Send>; +pub type TransactionFut = Box + Send>; #[derive(Debug, PartialEq)] pub enum FoundSwapTxSpend { diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 593d4fd448..45b67f3634 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -14,7 +14,7 @@ use crate::utxo::{qtum, ActualTxFee, AdditionalTxData, BroadcastTxErr, FeePolicy use crate::{BalanceError, BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, PrivKeyNotAllowed, RawTransactionFut, RawTransactionRequest, SwapOps, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, - TransactionDetails, TransactionEnum, TransactionFut, TransactionFutErr, TransactionType, + TransactionDetails, TransactionEnum, TransactionErr, TransactionFut, TransactionType, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest, WithdrawResult}; use async_trait::async_trait; @@ -447,7 +447,7 @@ impl Qrc20Coin { pub async fn send_contract_calls( &self, outputs: Vec, - ) -> Result { + ) -> Result { // TODO: we need to somehow refactor it using RecentlySpentOutpoints cache // Move over all QRC20 tokens should share the same cache with each other and base QTUM coin let _utxo_lock = UTXO_LOCK.lock().await; @@ -458,7 +458,7 @@ impl Qrc20Coin { .generate_qrc20_transaction(outputs) .await .mm_err(|e| e.into_withdraw_error(platform, decimals)) - .map_err(|e| TransactionFutErr::Plain(ERRL!("{}", e)))?; + .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; try_tx_s!(self.utxo.rpc_client.send_transaction(&signed).compat().await, signed); Ok(signed.into()) } @@ -1098,7 +1098,7 @@ impl MarketCoinOps for Qrc20Coin { let fut = async move { selfi .wait_for_tx_spend_impl(tx, wait_until, from_block) - .map_err(TransactionFutErr::Plain) + .map_err(TransactionErr::Plain) .await }; Box::new(fut.boxed().compat()) diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index 7aa3953d2e..2def78c339 100644 --- a/mm2src/coins/qrc20/qrc20_tests.rs +++ b/mm2src/coins/qrc20/qrc20_tests.rs @@ -955,9 +955,6 @@ fn test_send_contract_calls_recoverable_tx() { // The error variant should equal to `TxRecoverable` assert_eq!( discriminant(&tx_err), - discriminant(&TransactionFutErr::TxRecoverable( - TransactionEnum::from(tx), - String::new() - )) + discriminant(&TransactionErr::TxRecoverable(TransactionEnum::from(tx), String::new())) ); } diff --git a/mm2src/coins/qrc20/swap.rs b/mm2src/coins/qrc20/swap.rs index 22d98e1629..aa5ab12c1b 100644 --- a/mm2src/coins/qrc20/swap.rs +++ b/mm2src/coins/qrc20/swap.rs @@ -37,7 +37,7 @@ impl Qrc20Coin { secret_hash: Vec, receiver_addr: H160, swap_contract_address: H160, - ) -> Result { + ) -> Result { let balance = try_tx_s!(self.my_spendable_balance().compat().await); let balance = try_tx_s!(wei_from_big_decimal(&balance, self.utxo.decimals)); @@ -67,7 +67,7 @@ impl Qrc20Coin { payment_tx: UtxoTx, swap_contract_address: H160, secret: Vec, - ) -> Result { + ) -> Result { let Erc20PaymentDetails { swap_id, value, sender, .. } = try_tx_s!(self.erc20_payment_details_from_tx(&payment_tx).await); @@ -86,7 +86,7 @@ impl Qrc20Coin { &self, swap_contract_address: H160, payment_tx: UtxoTx, - ) -> Result { + ) -> Result { let Erc20PaymentDetails { swap_id, value, diff --git a/mm2src/coins/utxo.rs b/mm2src/coins/utxo.rs index 57cf4a6133..4ef8b394cc 100644 --- a/mm2src/coins/utxo.rs +++ b/mm2src/coins/utxo.rs @@ -97,7 +97,7 @@ use crate::coin_balance::{EnableCoinScanPolicy, HDAddressBalanceScanner}; use crate::hd_wallet::{HDAccountOps, HDAccountsMutex, HDAddress, HDWalletCoinOps, HDWalletOps, InvalidBip44ChainError}; use crate::hd_wallet_storage::{HDAccountStorageItem, HDWalletCoinStorage, HDWalletStorageError, HDWalletStorageResult}; use crate::utxo::utxo_block_header_storage::BlockHeaderStorageError; -use crate::TransactionFutErr; +use crate::TransactionErr; use utxo_block_header_storage::BlockHeaderStorage; #[cfg(not(target_arch = "wasm32"))] pub mod tx_cache; #[cfg(target_arch = "wasm32")] @@ -1473,7 +1473,7 @@ pub fn sat_from_big_decimal(amount: &BigDecimal, decimals: u8) -> NumConversResu async fn send_outputs_from_my_address_impl( coin: T, outputs: Vec, -) -> Result +) -> Result where T: UtxoCommonOps, { @@ -1490,7 +1490,7 @@ async fn generate_and_send_tx( fee_policy: FeePolicy, mut recently_spent: AsyncMutexGuard<'_, RecentlySpentOutPoints>, outputs: Vec, -) -> Result +) -> Result where T: AsRef + UtxoTxGenerationOps + UtxoTxBroadcastOps, { diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index de4121ab15..f5691af02d 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -13,7 +13,7 @@ use crate::utxo::{generate_and_send_tx, sat_from_big_decimal, ActualTxFee, Addit use crate::{BalanceFut, CoinBalance, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MarketCoinOps, MmCoin, NegotiateSwapContractAddrErr, NumConversError, PrivKeyNotAllowed, RawTransactionFut, RawTransactionRequest, SwapOps, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, - TradePreimageValue, TransactionDetails, TransactionEnum, TransactionFut, TransactionFutErr, TxFeeDetails, + TradePreimageValue, TransactionDetails, TransactionEnum, TransactionErr, TransactionFut, TxFeeDetails, UnexpectedDerivationMethod, ValidateAddressResult, ValidatePaymentInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; @@ -409,7 +409,7 @@ impl SlpToken { Ok((preimage, recently_spent)) } - pub async fn send_slp_outputs(&self, slp_outputs: Vec) -> Result { + pub async fn send_slp_outputs(&self, slp_outputs: Vec) -> Result { let (preimage, recently_spent) = try_tx_s!(self.generate_slp_tx_preimage(slp_outputs).await); generate_and_send_tx( self, @@ -429,7 +429,7 @@ impl SlpToken { time_lock: u32, secret_hash: &[u8], amount: u64, - ) -> Result { + ) -> Result { let payment_script = payment_script(time_lock, secret_hash, my_pub, other_pub); let script_pubkey = ScriptBuilder::build_p2sh(&dhash160(&payment_script).into()).to_bytes(); let slp_out = SlpOutput { amount, script_pubkey }; @@ -1296,7 +1296,7 @@ impl SwapOps for SlpToken { ); Ok(tx.into()) }; - Box::new(fut.boxed().compat().map_err(TransactionFutErr::Plain)) + Box::new(fut.boxed().compat().map_err(TransactionErr::Plain)) } fn send_maker_refunds_payment( @@ -1795,7 +1795,7 @@ pub fn slp_addr_from_pubkey_str(pubkey: &str, prefix: &str) -> Result err, - TransactionFutErr::Plain(err) => err, + TransactionErr::TxRecoverable(_tx, err) => err, + TransactionErr::Plain(err) => err, }; println!("{:?}", err); @@ -2067,7 +2067,7 @@ mod slp_tests { // The error variant should equal to `TxRecoverable` assert_eq!( discriminant(&tx_err), - discriminant(&TransactionFutErr::TxRecoverable( + discriminant(&TransactionErr::TxRecoverable( TransactionEnum::from(utxo_tx), String::new() )) diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index b60395c917..5cac15ea76 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -1037,7 +1037,7 @@ pub fn send_maker_payment( Either::B( client .import_address(&addr_string, &addr_string, false) - .map_err(|e| TransactionFutErr::Plain(ERRL!("{}", e))) + .map_err(|e| TransactionErr::Plain(ERRL!("{}", e))) .and_then(move |_| send_outputs_from_my_address(coin, outputs)), ) }, @@ -1072,7 +1072,7 @@ pub fn send_taker_payment( Either::B( client .import_address(&addr_string, &addr_string, false) - .map_err(|e| TransactionFutErr::Plain(ERRL!("{}", e))) + .map_err(|e| TransactionErr::Plain(ERRL!("{}", e))) .and_then(move |_| send_outputs_from_my_address(coin, outputs)), ) }, @@ -1196,7 +1196,7 @@ pub fn send_taker_refunds_payment( let my_address = try_tx_fus!(coin.as_ref().derivation_method.iguana_or_err()).clone(); let mut prev_tx: UtxoTx = - try_tx_fus!(deserialize(taker_payment_tx).map_err(|e| TransactionFutErr::Plain(format!("{:?}", e)))); + try_tx_fus!(deserialize(taker_payment_tx).map_err(|e| TransactionErr::Plain(format!("{:?}", e)))); prev_tx.tx_hash_algo = coin.as_ref().tx_hash_algo; let script_data = Builder::default().push_opcode(Opcode::OP_1).into_script(); let redeem_script = payment_script( diff --git a/mm2src/coins/utxo/utxo_tests.rs b/mm2src/coins/utxo/utxo_tests.rs index 51b5b72629..7900ff8cf0 100644 --- a/mm2src/coins/utxo/utxo_tests.rs +++ b/mm2src/coins/utxo/utxo_tests.rs @@ -205,10 +205,7 @@ fn test_send_maker_spends_taker_payment_recoverable_tx() { // The error variant should equal to `TxRecoverable` assert_eq!( discriminant(&tx_err), - discriminant(&TransactionFutErr::TxRecoverable( - TransactionEnum::from(tx), - String::new() - )) + discriminant(&TransactionErr::TxRecoverable(TransactionEnum::from(tx), String::new())) ); } diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index 16008e5eb4..a5486ad697 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -893,7 +893,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_tx_s!(tx_fut.await); + let tx = try_ztx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -931,7 +931,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_tx_s!(tx_fut.await); + let tx = try_ztx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -966,7 +966,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_tx_s!(tx_fut.await); + let tx = try_ztx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) @@ -1001,7 +1001,7 @@ impl SwapOps for ZCoin { script_data, key_pair.private().secret.as_slice(), ); - let tx = try_tx_s!(tx_fut.await); + let tx = try_ztx_s!(tx_fut.await); Ok(tx.into()) }; Box::new(fut.boxed().compat()) diff --git a/mm2src/coins/z_coin/z_htlc.rs b/mm2src/coins/z_coin/z_htlc.rs index 5de6a650f9..324d7c9bfb 100644 --- a/mm2src/coins/z_coin/z_htlc.rs +++ b/mm2src/coins/z_coin/z_htlc.rs @@ -10,7 +10,7 @@ use crate::utxo::rpc_clients::{UtxoRpcClientEnum, UtxoRpcError}; use crate::utxo::utxo_common::payment_script; use crate::utxo::{sat_from_big_decimal, UtxoAddressFormat}; use crate::z_coin::{ARRRConsensusParams, SendOutputsErr, ZOutput, DEX_FEE_OVK}; -use crate::{NumConversError, PrivKeyNotAllowed}; +use crate::{NumConversError, PrivKeyNotAllowed, TransactionEnum}; use bigdecimal::BigDecimal; use bitcrypto::dhash160; use chain::Transaction as UtxoTx; @@ -99,6 +99,8 @@ pub enum ZP2SHSpendError { ZTxBuilderError(ZTxBuilderError), PrivKeyNotAllowed(PrivKeyNotAllowed), Rpc(UtxoRpcError), + #[display(fmt = "{:?} {}", _0, _1)] + TxRecoverable(TransactionEnum, String), } impl From for ZP2SHSpendError { @@ -113,6 +115,16 @@ impl From for ZP2SHSpendError { fn from(rpc: UtxoRpcError) -> ZP2SHSpendError { ZP2SHSpendError::Rpc(rpc) } } +impl ZP2SHSpendError { + #[inline] + pub fn get_tx(&self) -> Option { + match self { + ZP2SHSpendError::TxRecoverable(ref tx, _) => Some(tx.clone()), + _ => None, + } + } +} + /// Spends P2SH output 0 to the coin's my_z_addr pub async fn z_p2sh_spend( coin: &ZCoin, @@ -161,10 +173,10 @@ pub async fn z_p2sh_spend( zcash_tx.write(&mut tx_buffer).unwrap(); let refund_tx: UtxoTx = deserialize(tx_buffer.as_slice()).expect("librustzcash should produce a valid tx"); - coin.rpc_client() - .send_raw_transaction(tx_buffer.into()) - .compat() - .await?; + match coin.rpc_client().send_raw_transaction(tx_buffer.into()).compat().await { + Ok(_) => (), + Err(e) => return Err(ZP2SHSpendError::TxRecoverable(refund_tx.into(), e.to_string()).into()), + }; Ok(refund_tx) } diff --git a/mm2src/docker_tests/qrc20_tests.rs b/mm2src/docker_tests/qrc20_tests.rs index be1beb63ea..814c2c8f39 100644 --- a/mm2src/docker_tests/qrc20_tests.rs +++ b/mm2src/docker_tests/qrc20_tests.rs @@ -7,7 +7,7 @@ use coins::utxo::rpc_clients::UtxoRpcClientEnum; use coins::utxo::utxo_common::big_decimal_from_sat; use coins::utxo::{UtxoActivationParams, UtxoCommonOps}; use coins::{FeeApproxStage, FoundSwapTxSpend, MarketCoinOps, MmCoin, SwapOps, TradePreimageValue, TransactionEnum, - TransactionFutErr, ValidatePaymentInput}; + TransactionErr, ValidatePaymentInput}; use common::log::debug; use common::mm_ctx::{MmArc, MmCtxBuilder}; use common::mm_number::BigDecimal; From 21f9684e7e84a1e9baea3cfab2197903643c0b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Wed, 4 May 2022 10:30:41 +0300 Subject: [PATCH 48/48] resolve pr notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- mm2src/coins/lp_coins.rs | 24 ------------------------ mm2src/coins/qrc20.rs | 3 --- mm2src/coins/z_coin.rs | 19 +++++++++++++++++++ 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index c2dfbf1ae5..a6809d6122 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -145,30 +145,6 @@ macro_rules! try_tx_s { }; } -/// `ZP2SHSpendError` compatible `TransactionErr` handling macro. -macro_rules! try_ztx_s { - ($e: expr) => { - match $e { - Ok(ok) => ok, - Err(err) => { - if let Some(tx) = err.get_inner().get_tx() { - return Err(crate::TransactionErr::TxRecoverable( - tx, - format!("{}:{}] {:?}", file!(), line!(), err), - )); - } - - return Err(crate::TransactionErr::Plain(format!( - "{}:{}] {:?}", - file!(), - line!(), - err - ))); - }, - } - }; -} - /// `TransactionErr:Plain` compatible `ERR` macro. macro_rules! TX_PLAIN_ERR { ($format: expr, $($args: tt)+) => { Err(crate::TransactionErr::Plain((ERRL!($format, $($args)+)))) }; diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 45b67f3634..c636790507 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -452,12 +452,9 @@ impl Qrc20Coin { // Move over all QRC20 tokens should share the same cache with each other and base QTUM coin let _utxo_lock = UTXO_LOCK.lock().await; - let platform = self.platform.clone(); - let decimals = self.utxo.decimals; let GenerateQrc20TxResult { signed, .. } = self .generate_qrc20_transaction(outputs) .await - .mm_err(|e| e.into_withdraw_error(platform, decimals)) .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; try_tx_s!(self.utxo.rpc_client.send_transaction(&signed).compat().await, signed); Ok(signed.into()) diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index a5486ad697..aebd351805 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -69,6 +69,25 @@ pub use z_coin_errors::*; #[cfg(all(test, feature = "zhtlc-native-tests"))] mod z_coin_tests; +/// `ZP2SHSpendError` compatible `TransactionErr` handling macro. +macro_rules! try_ztx_s { + ($e: expr) => { + match $e { + Ok(ok) => ok, + Err(err) => { + if let Some(tx) = err.get_inner().get_tx() { + return Err(crate::TransactionErr::TxRecoverable( + tx, + format!("{}:{}] {:?}", file!(), line!(), err), + )); + } + + return Err(crate::TransactionErr::Plain(ERRL!("{:?}", err))); + }, + } + }; +} + #[derive(Debug, Clone)] pub struct ARRRConsensusParams {}