diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index dfdac1304a..f985db4bb7 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -5454,6 +5454,8 @@ impl MmCoin for EthCoin { Box::new(get_tx_hex_by_hash_impl(self.clone(), tx_hash).boxed().compat()) } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { Box::new(Box::pin(withdraw_impl(self.clone(), req)).compat()) } diff --git a/mm2src/coins/lightning.rs b/mm2src/coins/lightning.rs index 2feb7ef014..3db5b87aa3 100644 --- a/mm2src/coins/lightning.rs +++ b/mm2src/coins/lightning.rs @@ -1294,6 +1294,8 @@ impl MmCoin for LightningCoin { Box::new(fut.boxed().compat()) } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn withdraw(&self, _req: WithdrawRequest) -> WithdrawFut { let fut = async move { MmError::err(WithdrawError::InternalError( diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 463028a635..e171dee2e9 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -3210,6 +3210,10 @@ pub trait MmCoin: fn get_tx_hex_by_hash(&self, tx_hash: Vec) -> RawTransactionFut; + /// Checks if the transaction is on-chain whether it is confirmed or not (in the mempool). + // Todo: maybe use a new error type for this + async fn is_tx_on_chain(&self, tx_hash: Vec) -> MmResult; + /// Maximum number of digits after decimal point used to denominate integer coin units (satoshis, wei, etc.) fn decimals(&self) -> u8; diff --git a/mm2src/coins/qrc20.rs b/mm2src/coins/qrc20.rs index 3ee9e7761b..a5d99926d1 100644 --- a/mm2src/coins/qrc20.rs +++ b/mm2src/coins/qrc20.rs @@ -20,9 +20,9 @@ use crate::{BalanceError, BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, Coi DexFee, Eip1559Ops, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, IguanaPrivKey, MakerSwapTakerCoin, MarketCoinOps, MmCoin, MmCoinEnum, NegotiateSwapContractAddrErr, PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, PrivKeyBuildPolicy, PrivKeyPolicyNotAllowed, - RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundError, RefundPaymentArgs, - RefundResult, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, - SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, + RawTransactionError, RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundError, + RefundPaymentArgs, RefundResult, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, + SendPaymentArgs, SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, SwapOps, SwapTxFeePolicy, TakerSwapMakerCoin, TradeFee, TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionData, TransactionDetails, TransactionEnum, TransactionErr, TransactionFut, TransactionResult, TransactionType, TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, @@ -1326,6 +1326,8 @@ impl MmCoin for Qrc20Coin { Box::new(utxo_common::get_tx_hex_by_hash(&self.utxo, tx_hash).boxed().compat()) } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn decimals(&self) -> u8 { utxo_common::decimals(&self.utxo) } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { diff --git a/mm2src/coins/sia.rs b/mm2src/coins/sia.rs index 446a507070..5246966ae8 100644 --- a/mm2src/coins/sia.rs +++ b/mm2src/coins/sia.rs @@ -1,5 +1,5 @@ -use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, RawTransactionFut, RawTransactionRequest, SwapOps, - TradeFee, TransactionEnum, TransactionFut}; +use super::{CoinBalance, HistorySyncState, MarketCoinOps, MmCoin, RawTransactionError, RawTransactionFut, + RawTransactionRequest, SwapOps, TradeFee, TransactionEnum, TransactionFut}; use crate::{coin_errors::MyAddressError, BalanceFut, CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinFutSpawner, ConfirmPaymentInput, DexFee, FeeApproxStage, FoundSwapTxSpend, MakerSwapTakerCoin, MmCoinEnum, NegotiateSwapContractAddrErr, PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, @@ -220,6 +220,8 @@ impl MmCoin for SiaCoin { fn get_tx_hex_by_hash(&self, _tx_hash: Vec) -> RawTransactionFut { unimplemented!() } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn withdraw(&self, _req: WithdrawRequest) -> WithdrawFut { unimplemented!() } fn decimals(&self) -> u8 { unimplemented!() } diff --git a/mm2src/coins/solana.rs b/mm2src/coins/solana.rs index 2a454fd90c..17623e736b 100644 --- a/mm2src/coins/solana.rs +++ b/mm2src/coins/solana.rs @@ -717,6 +717,8 @@ impl MmCoin for SolanaCoin { fn get_tx_hex_by_hash(&self, tx_hash: Vec) -> RawTransactionFut { unimplemented!() } + async fn is_tx_on_chain(&self, tx_hash: Vec) -> MmResult { todo!() } + fn decimals(&self) -> u8 { self.decimals } fn convert_to_address(&self, _from: &str, _to_address_format: Json) -> Result { unimplemented!() } diff --git a/mm2src/coins/solana/spl.rs b/mm2src/coins/solana/spl.rs index 7bc720e5e7..45f65a94a6 100644 --- a/mm2src/coins/solana/spl.rs +++ b/mm2src/coins/solana/spl.rs @@ -536,6 +536,8 @@ impl MmCoin for SplToken { fn get_tx_hex_by_hash(&self, tx_hash: Vec) -> RawTransactionFut { unimplemented!() } + async fn is_tx_on_chain(&self, tx_hash: Vec) -> MmResult { todo!() } + fn decimals(&self) -> u8 { self.conf.decimals } fn convert_to_address(&self, _from: &str, _to_address_format: Json) -> Result { unimplemented!() } diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index f073d31d29..64f8fadda5 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -2207,6 +2207,8 @@ impl MmCoin for TendermintCoin { Box::new(fut.boxed().compat()) } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn decimals(&self) -> u8 { self.decimals } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { diff --git a/mm2src/coins/tendermint/tendermint_token.rs b/mm2src/coins/tendermint/tendermint_token.rs index 894982aa83..de572bdff4 100644 --- a/mm2src/coins/tendermint/tendermint_token.rs +++ b/mm2src/coins/tendermint/tendermint_token.rs @@ -645,6 +645,8 @@ impl MmCoin for TendermintToken { fn get_tx_hex_by_hash(&self, tx_hash: Vec) -> RawTransactionFut { unimplemented!() } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn decimals(&self) -> u8 { self.decimals } fn convert_to_address(&self, from: &str, to_address_format: Json) -> Result { diff --git a/mm2src/coins/test_coin.rs b/mm2src/coins/test_coin.rs index c077bf60bd..b01aa887cf 100644 --- a/mm2src/coins/test_coin.rs +++ b/mm2src/coins/test_coin.rs @@ -1,8 +1,8 @@ #![allow(clippy::all)] -use super::{CoinBalance, FundingTxSpend, HistorySyncState, MarketCoinOps, MmCoin, RawTransactionFut, - RawTransactionRequest, SearchForFundingSpendErr, SwapOps, TradeFee, TransactionEnum, TransactionFut, - WaitForTakerPaymentSpendError}; +use super::{CoinBalance, FundingTxSpend, HistorySyncState, MarketCoinOps, MmCoin, RawTransactionError, + RawTransactionFut, RawTransactionRequest, SearchForFundingSpendErr, SwapOps, TradeFee, TransactionEnum, + TransactionFut, WaitForTakerPaymentSpendError}; use crate::coin_errors::ValidatePaymentResult; use crate::{coin_errors::MyAddressError, BalanceFut, CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinFutSpawner, ConfirmPaymentInput, FeeApproxStage, FoundSwapTxSpend, GenPreimageResult, GenTakerFundingSpendArgs, @@ -345,6 +345,8 @@ impl MmCoin for TestCoin { fn get_tx_hex_by_hash(&self, tx_hash: Vec) -> RawTransactionFut { unimplemented!() } + async fn is_tx_on_chain(&self, tx_hash: Vec) -> MmResult { unimplemented!() } + fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { unimplemented!() } fn decimals(&self) -> u8 { unimplemented!() } diff --git a/mm2src/coins/utxo/bch.rs b/mm2src/coins/utxo/bch.rs index 2b94135933..8df325d81f 100644 --- a/mm2src/coins/utxo/bch.rs +++ b/mm2src/coins/utxo/bch.rs @@ -17,14 +17,14 @@ use crate::{coin_balance, BlockHeightAndTime, CanRefundHtlc, CheckIfMyPaymentSen CoinWithDerivationMethod, CoinWithPrivKeyPolicy, ConfirmPaymentInput, DexFee, GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MakerSwapTakerCoin, MmCoinEnum, NegotiateSwapContractAddrErr, PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, PrivKeyBuildPolicy, - RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundError, RefundPaymentArgs, - RefundResult, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, - SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, SwapOps, TakerSwapMakerCoin, - TradePreimageValue, TransactionFut, TransactionResult, TransactionType, TxFeeDetails, TxMarshalingErr, - UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateInstructionsErr, - ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, - ValidateWatcherSpendInput, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, - WatcherRewardError, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, + RawTransactionError, RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundError, + RefundPaymentArgs, RefundResult, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, + SendPaymentArgs, SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, SwapOps, + TakerSwapMakerCoin, TradePreimageValue, TransactionFut, TransactionResult, TransactionType, TxFeeDetails, + TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, + ValidateInstructionsErr, ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, + ValidatePaymentInput, ValidateWatcherSpendInput, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, + WatcherReward, WatcherRewardError, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WithdrawFut}; use common::executor::{AbortableSystem, AbortedError}; use common::log::warn; @@ -1275,6 +1275,8 @@ impl MmCoin for BchCoin { ) } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { Box::new(utxo_common::withdraw(self.clone(), req).boxed().compat()) } diff --git a/mm2src/coins/utxo/qtum.rs b/mm2src/coins/utxo/qtum.rs index 8b8a60d246..cf32238826 100644 --- a/mm2src/coins/utxo/qtum.rs +++ b/mm2src/coins/utxo/qtum.rs @@ -26,9 +26,9 @@ use crate::{eth, CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinWithD CoinWithPrivKeyPolicy, ConfirmPaymentInput, DelegationError, DelegationFut, DexFee, GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MakerSwapTakerCoin, MmCoinEnum, NegotiateSwapContractAddrErr, PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, - PrivKeyBuildPolicy, RawTransactionRequest, RawTransactionResult, RefundError, RefundPaymentArgs, - RefundResult, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, - SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, StakingInfosFut, SwapOps, + PrivKeyBuildPolicy, RawTransactionError, RawTransactionRequest, RawTransactionResult, RefundError, + RefundPaymentArgs, RefundResult, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, + SendPaymentArgs, SignRawTransactionRequest, SignatureResult, SpendPaymentArgs, StakingInfosFut, SwapOps, TakerSwapMakerCoin, TradePreimageValue, TransactionFut, TransactionResult, TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateInstructionsErr, ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, @@ -894,6 +894,8 @@ impl MmCoin for QtumCoin { ) } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { Box::new(utxo_common::withdraw(self.clone(), req).boxed().compat()) } diff --git a/mm2src/coins/utxo/slp.rs b/mm2src/coins/utxo/slp.rs index c559449c22..81ff4ccf65 100644 --- a/mm2src/coins/utxo/slp.rs +++ b/mm2src/coins/utxo/slp.rs @@ -16,17 +16,17 @@ use crate::utxo::{generate_and_send_tx, sat_from_big_decimal, ActualTxFee, Addit use crate::{BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, CoinFutSpawner, ConfirmPaymentInput, DerivationMethod, DexFee, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MakerSwapTakerCoin, MarketCoinOps, MmCoin, MmCoinEnum, NegotiateSwapContractAddrErr, NumConversError, PaymentInstructionArgs, PaymentInstructions, - PaymentInstructionsErr, PrivKeyPolicyNotAllowed, RawTransactionFut, RawTransactionRequest, - RawTransactionResult, RefundError, RefundPaymentArgs, RefundResult, SearchForSwapTxSpendInput, - SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SignRawTransactionRequest, SignatureResult, - SpendPaymentArgs, SwapOps, SwapTxTypeWithSecretHash, TakerSwapMakerCoin, TradeFee, TradePreimageError, - TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionData, TransactionDetails, - TransactionEnum, TransactionErr, TransactionFut, TransactionResult, TxFeeDetails, TxMarshalingErr, - UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateInstructionsErr, - ValidateOtherPubKeyErr, ValidatePaymentInput, ValidateWatcherSpendInput, VerificationError, - VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, WatcherRewardError, - WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, - WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; + PaymentInstructionsErr, PrivKeyPolicyNotAllowed, RawTransactionError, RawTransactionFut, + RawTransactionRequest, RawTransactionResult, RefundError, RefundPaymentArgs, RefundResult, + SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SignRawTransactionRequest, + SignatureResult, SpendPaymentArgs, SwapOps, SwapTxTypeWithSecretHash, TakerSwapMakerCoin, TradeFee, + TradePreimageError, TradePreimageFut, TradePreimageResult, TradePreimageValue, TransactionData, + TransactionDetails, TransactionEnum, TransactionErr, TransactionFut, TransactionResult, TxFeeDetails, + TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, + ValidateInstructionsErr, ValidateOtherPubKeyErr, ValidatePaymentInput, ValidateWatcherSpendInput, + VerificationError, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, + WatcherRewardError, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, + WatcherValidateTakerFeeInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; use async_trait::async_trait; use base64::engine::general_purpose::STANDARD; use base64::Engine; @@ -1615,6 +1615,8 @@ impl MmCoin for SlpToken { ) } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { let coin = self.clone(); let fut = async move { diff --git a/mm2src/coins/utxo/utxo_standard.rs b/mm2src/coins/utxo/utxo_standard.rs index 03c889d790..3e54322c57 100644 --- a/mm2src/coins/utxo/utxo_standard.rs +++ b/mm2src/coins/utxo/utxo_standard.rs @@ -25,9 +25,9 @@ use crate::{CanRefundHtlc, CheckIfMyPaymentSentArgs, CoinBalance, CoinWithDeriva ConfirmPaymentInput, DexFee, FundingTxSpend, GenPreimageResult, GenTakerFundingSpendArgs, GenTakerPaymentSpendArgs, GetWithdrawSenderAddress, IguanaBalanceOps, IguanaPrivKey, MakerCoinSwapOpsV2, MakerSwapTakerCoin, MmCoinEnum, NegotiateSwapContractAddrErr, PaymentInstructionArgs, PaymentInstructions, - PaymentInstructionsErr, PrivKeyBuildPolicy, RawTransactionRequest, RawTransactionResult, RefundError, - RefundFundingSecretArgs, RefundMakerPaymentArgs, RefundPaymentArgs, RefundResult, - SearchForFundingSpendErr, SearchForSwapTxSpendInput, SendMakerPaymentArgs, + PaymentInstructionsErr, PrivKeyBuildPolicy, RawTransactionError, RawTransactionRequest, + RawTransactionResult, RefundError, RefundFundingSecretArgs, RefundMakerPaymentArgs, RefundPaymentArgs, + RefundResult, SearchForFundingSpendErr, SearchForSwapTxSpendInput, SendMakerPaymentArgs, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, SendTakerFundingArgs, SignRawTransactionRequest, SignatureResult, SpendMakerPaymentArgs, SpendPaymentArgs, SwapOps, SwapTxTypeWithSecretHash, TakerCoinSwapOpsV2, TakerSwapMakerCoin, ToBytes, TradePreimageValue, TransactionFut, TransactionResult, @@ -923,6 +923,8 @@ impl MmCoin for UtxoStandardCoin { ) } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn withdraw(&self, req: WithdrawRequest) -> WithdrawFut { Box::new(utxo_common::withdraw(self.clone(), req).boxed().compat()) } diff --git a/mm2src/coins/z_coin.rs b/mm2src/coins/z_coin.rs index d9a416d204..7cceb3dacf 100644 --- a/mm2src/coins/z_coin.rs +++ b/mm2src/coins/z_coin.rs @@ -30,16 +30,16 @@ use crate::{BalanceError, BalanceFut, CheckIfMyPaymentSentArgs, CoinBalance, Coi DexFee, FeeApproxStage, FoundSwapTxSpend, HistorySyncState, MakerSwapTakerCoin, MarketCoinOps, MmCoin, MmCoinEnum, NegotiateSwapContractAddrErr, NumConversError, PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, PrivKeyActivationPolicy, PrivKeyBuildPolicy, PrivKeyPolicyNotAllowed, - RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundError, RefundPaymentArgs, - RefundResult, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, SendPaymentArgs, - SignRawTransactionRequest, SignatureError, SignatureResult, SpendPaymentArgs, SwapOps, TakerSwapMakerCoin, - TradeFee, TradePreimageFut, TradePreimageResult, TradePreimageValue, Transaction, TransactionData, - TransactionDetails, TransactionEnum, TransactionFut, TransactionResult, TxFeeDetails, TxMarshalingErr, - UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, ValidateInstructionsErr, - ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, ValidatePaymentInput, - ValidateWatcherSpendInput, VerificationError, VerificationResult, WaitForHTLCTxSpendArgs, WatcherOps, - WatcherReward, WatcherRewardError, WatcherSearchForSwapTxSpendInput, WatcherValidatePaymentInput, - WatcherValidateTakerFeeInput, WithdrawError, WithdrawFut, WithdrawRequest}; + RawTransactionError, RawTransactionFut, RawTransactionRequest, RawTransactionResult, RefundError, + RefundPaymentArgs, RefundResult, SearchForSwapTxSpendInput, SendMakerPaymentSpendPreimageInput, + SendPaymentArgs, SignRawTransactionRequest, SignatureError, SignatureResult, SpendPaymentArgs, SwapOps, + TakerSwapMakerCoin, TradeFee, TradePreimageFut, TradePreimageResult, TradePreimageValue, Transaction, + TransactionData, TransactionDetails, TransactionEnum, TransactionFut, TransactionResult, TxFeeDetails, + TxMarshalingErr, UnexpectedDerivationMethod, ValidateAddressResult, ValidateFeeArgs, + ValidateInstructionsErr, ValidateOtherPubKeyErr, ValidatePaymentError, ValidatePaymentFut, + ValidatePaymentInput, ValidateWatcherSpendInput, VerificationError, VerificationResult, + WaitForHTLCTxSpendArgs, WatcherOps, WatcherReward, WatcherRewardError, WatcherSearchForSwapTxSpendInput, + WatcherValidatePaymentInput, WatcherValidateTakerFeeInput, WithdrawError, WithdrawFut, WithdrawRequest}; use async_trait::async_trait; use bitcrypto::dhash256; @@ -1685,6 +1685,8 @@ impl MmCoin for ZCoin { ) } + async fn is_tx_on_chain(&self, _tx_hash: Vec) -> MmResult { todo!() } + fn decimals(&self) -> u8 { self.utxo_arc.decimals } fn convert_to_address(&self, _from: &str, _to_address_format: Json) -> Result { diff --git a/mm2src/mm2_main/src/lp_swap/maker_swap.rs b/mm2src/mm2_main/src/lp_swap/maker_swap.rs index b1117e707a..18b9bfe2d2 100644 --- a/mm2src/mm2_main/src/lp_swap/maker_swap.rs +++ b/mm2src/mm2_main/src/lp_swap/maker_swap.rs @@ -20,6 +20,7 @@ use coins::{CanRefundHtlc, CheckIfMyPaymentSentArgs, ConfirmPaymentInput, FeeApp MmCoinEnum, PaymentInstructionArgs, PaymentInstructions, PaymentInstructionsErr, RefundPaymentArgs, SearchForSwapTxSpendInput, SendPaymentArgs, SpendPaymentArgs, SwapTxTypeWithSecretHash, TradeFee, TradePreimageValue, TransactionEnum, ValidateFeeArgs, ValidatePaymentInput}; +use common::custom_futures::repeatable::{Ready, Retry}; use common::log::{debug, error, info, warn}; use common::{bits256, executor::Timer, now_ms, DEX_FEE_ADDR_RAW_PUBKEY}; use common::{now_sec, wait_until_sec}; @@ -1185,6 +1186,13 @@ impl MakerSwap { } async fn refund_maker_payment(&self) -> Result<(Option, Vec), String> { + const REFUND_RETRY_DELAY_SECS: f64 = 60.; + + enum TxKind { + Refund(TransactionEnum), + Spend(TransactionEnum), + } + #[cfg(test)] if self.fail_at == Some(FailAt::MakerPaymentRefund) { return Ok((Some(MakerSwapCommand::Finish), vec![ @@ -1220,26 +1228,35 @@ impl MakerSwap { let other_maker_coin_htlc_pub = self.r().other_maker_coin_htlc_pub; let maker_coin_swap_contract_address = self.r().data.maker_coin_swap_contract_address.clone(); + let secret_hash = self.secret_hash().clone(); + let unique_swap_data = self.unique_swap_data().clone(); let watcher_reward = self.r().watcher_reward; - let spend_result = self - .maker_coin - .send_maker_refunds_payment(RefundPaymentArgs { + let spend_result_fut = || { + self.maker_coin.send_maker_refunds_payment(RefundPaymentArgs { payment_tx: &maker_payment, time_lock: locktime, other_pubkey: other_maker_coin_htlc_pub.as_slice(), tx_type_with_secret_hash: SwapTxTypeWithSecretHash::TakerOrMakerPayment { - maker_secret_hash: self.secret_hash().as_slice(), + maker_secret_hash: secret_hash.as_slice(), }, swap_contract_address: &maker_coin_swap_contract_address, - swap_unique_data: &self.unique_swap_data(), + swap_unique_data: &unique_swap_data, watcher_reward, }) - .await; + }; - let transaction = match spend_result { + let transaction = match spend_result_fut().await { Ok(t) => t, Err(err) => { if let Some(tx) = err.get_tx() { + // Broadcast the refund transaction to the peer-to-peer network. + // This allows other nodes running a native daemon to attempt the transaction. + // This broadcast is attempted only once if failed and once again later if successful. + // If the refund transaction initially broadcast by the maker node is not accepted, + // the broadcast will not be retried while the maker retries the transaction. + // If there are issues in the 'can_refund_htlc' function, such as non-final errors, + // this broadcast will not resolve the problem. + // Any issues in 'can_refund_htlc' must be addressed separately. broadcast_p2p_tx_msg( &self.ctx, tx_helper_topic(self.maker_coin.ticker()), @@ -1248,15 +1265,73 @@ impl MakerSwap { ); } - return Ok((Some(MakerSwapCommand::Finish), vec![ - MakerSwapEvent::MakerPaymentRefundFailed( - ERRL!( - "!maker_coin.send_maker_refunds_payment: {}", - err.get_plain_text_format() - ) - .into(), - ), - ])); + match repeatable!(async { + let maker_coin_start_block = self.r().data.maker_coin_start_block; + let search_input = SearchForSwapTxSpendInput { + time_lock: locktime, + other_pub: other_maker_coin_htlc_pub.as_slice(), + secret_hash: secret_hash.as_slice(), + tx: &maker_payment, + search_from_block: maker_coin_start_block, + swap_contract_address: &maker_coin_swap_contract_address, + swap_unique_data: &unique_swap_data, + watcher_reward, + }; + let search_for_maker_payment_spend_fut = + || self.maker_coin.search_for_swap_tx_spend_my(search_input); + match search_for_maker_payment_spend_fut().await { + // This is in case the maker payment was refunded by watchers or through other means + Ok(Some(FoundSwapTxSpend::Refunded(tx))) => return Ready(TxKind::Refund(tx)), + // This is in case the taker spent the maker payment, + // it shouldn't happen, but we check just in case there was a mistake was made in the code + Ok(Some(FoundSwapTxSpend::Spent(tx))) => return Ready(TxKind::Spend(tx)), + Err(err) => { + error!( + "Error {} on maker_coin.search_for_swap_tx_spend_my, retrying in {} seconds", + err, REFUND_RETRY_DELAY_SECS + ); + return Retry(()); + }, + Ok(None) => (), + } + match spend_result_fut().await { + Ok(t) => Ready(TxKind::Refund(t)), + Err(err) => { + error!( + "Error {} on send_maker_refunds_payment, retrying in {} seconds", + err.get_plain_text_format(), + REFUND_RETRY_DELAY_SECS + ); + Retry(()) + }, + } + }) + .until_ready() + .repeat_every_secs(REFUND_RETRY_DELAY_SECS) + .await + { + Ok(t) => match t { + TxKind::Refund(tx) => tx, + TxKind::Spend(tx) => { + return Ok((Some(MakerSwapCommand::Finish), vec![ + MakerSwapEvent::MakerPaymentRefundFailed( + ERRL!( + "maker_coin.search_for_swap_tx_spend_my: found spend tx: {:02x}", + tx.tx_hash_as_bytes() + ) + .into(), + ), + ])) + }, + }, + Err(err) => { + return Ok((Some(MakerSwapCommand::Finish), vec![ + MakerSwapEvent::MakerPaymentRefundFailed( + ERRL!("!maker_coin.send_maker_refunds_payment: {:?}", err.error()).into(), + ), + ])); + }, + } }, }; diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands_legacy.rs b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands_legacy.rs index 7e61b8c642..c3d19bdecf 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands_legacy.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands_legacy.rs @@ -173,9 +173,11 @@ pub async fn enable(ctx: MmArc, req: Json) -> Result>, String> let res = try_s!(Response::builder().body(res)); if coin.is_utxo_in_native_mode() { + // Todo: add this to other enable methods subscribe_to_topic(&ctx, tx_helper_topic(coin.ticker())); } if ctx.is_watcher() { + // Todo: add this to other enable methods subscribe_to_topic(&ctx, watcher_topic(coin.ticker())); }