Skip to content

Commit

Permalink
Implementing maker payment immediate refund.
Browse files Browse the repository at this point in the history
  • Loading branch information
artemii235 committed Dec 18, 2023
1 parent fba95bb commit c040a18
Show file tree
Hide file tree
Showing 24 changed files with 450 additions and 341 deletions.
2 changes: 2 additions & 0 deletions mm2src/coins/coin_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use std::num::TryFromIntError;

/// Helper type used as result for swap payment validation function(s)
pub type ValidatePaymentFut<T> = Box<dyn Future<Item = T, Error = MmError<ValidatePaymentError>> + Send>;
/// Helper type used as result for swap payment validation function(s)
pub type ValidatePaymentResult<T> = Result<T, MmError<ValidatePaymentError>>;

/// Enum covering possible error cases of swap payment validation
#[derive(Debug, Display)]
Expand Down
9 changes: 5 additions & 4 deletions mm2src/coins/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ use crate::nft::{find_wallet_nft_amount, WithdrawNftResult};
use v2_activation::{build_address_and_priv_key_policy, EthActivationV2Error};

mod nonce;
use crate::coin_errors::ValidatePaymentResult;
use crate::{PrivKeyPolicy, TransactionResult, WithdrawFrom};
use nonce::ParityNonce;

Expand Down Expand Up @@ -1128,13 +1129,13 @@ impl SwapOps for EthCoin {
}

#[inline]
fn validate_maker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentFut<()> {
self.validate_payment(input)
async fn validate_maker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentResult<()> {
self.validate_payment(input).compat().await
}

#[inline]
fn validate_taker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentFut<()> {
self.validate_payment(input)
async fn validate_taker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentResult<()> {
self.validate_payment(input).compat().await
}

fn check_if_my_payment_sent(
Expand Down
10 changes: 7 additions & 3 deletions mm2src/coins/eth/eth_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use crate::{DexFee, IguanaPrivKey};
use crate::{DexFee, IguanaPrivKey, SwapTxTypeWithSecretHash};
use common::{block_on, now_sec, wait_until_sec};
use crypto::privkey::key_pair_from_seed;
use ethkey::{Generator, Random};
Expand Down Expand Up @@ -375,10 +375,12 @@ fn send_and_refund_erc20_payment() {
payment_tx: &payment.tx_hex(),
time_lock,
other_pubkey: &DEX_FEE_ADDR_RAW_PUBKEY,
secret_hash,
swap_contract_address: &coin.swap_contract_address(),
swap_unique_data: &[],
watcher_reward: false,
tx_type_with_secret_hash: SwapTxTypeWithSecretHash::TakerOrMakerPayment {
maker_secret_hash: secret_hash,
},
};
let refund = block_on(coin.send_maker_refunds_payment(maker_refunds_payment_args)).unwrap();
log!("{:?}", refund);
Expand Down Expand Up @@ -462,7 +464,9 @@ fn send_and_refund_eth_payment() {
payment_tx: &payment.tx_hex(),
time_lock,
other_pubkey: &DEX_FEE_ADDR_RAW_PUBKEY,
secret_hash,
tx_type_with_secret_hash: SwapTxTypeWithSecretHash::TakerOrMakerPayment {
maker_secret_hash: secret_hash,
},
swap_contract_address: &coin.swap_contract_address(),
swap_unique_data: &[],
watcher_reward: false,
Expand Down
12 changes: 6 additions & 6 deletions mm2src/coins/lightning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ mod ln_sql;
pub mod ln_storage;
pub mod ln_utils;

use crate::coin_errors::MyAddressError;
use crate::coin_errors::{MyAddressError, ValidatePaymentResult};
use crate::lightning::ln_utils::{filter_channels, pay_invoice_with_max_total_cltv_expiry_delta, PaymentError};
use crate::utxo::rpc_clients::UtxoRpcClientEnum;
use crate::utxo::utxo_common::{big_decimal_from_sat, big_decimal_from_sat_unsigned};
Expand All @@ -37,7 +37,7 @@ use bitcrypto::{dhash256, ripemd160};
use common::custom_futures::repeatable::{Ready, Retry};
use common::executor::{AbortableSystem, AbortedError, Timer};
use common::log::{error, info, LogOnError, LogState};
use common::{async_blocking, get_local_duration_since_epoch, log, now_sec, PagingOptionsEnum};
use common::{async_blocking, get_local_duration_since_epoch, log, now_sec, Future01CompatExt, PagingOptionsEnum};
use db_common::sqlite::rusqlite::Error as SqlError;
use futures::{FutureExt, TryFutureExt};
use futures01::Future;
Expand Down Expand Up @@ -685,13 +685,13 @@ impl SwapOps for LightningCoin {
}

#[inline]
fn validate_maker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentFut<()> {
self.validate_swap_payment(input)
async fn validate_maker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentResult<()> {
self.validate_swap_payment(input).compat().await
}

#[inline]
fn validate_taker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentFut<()> {
self.validate_swap_payment(input)
async fn validate_taker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentResult<()> {
self.validate_swap_payment(input).compat().await
}

fn check_if_my_payment_sent(
Expand Down
37 changes: 32 additions & 5 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,9 @@ use nft::nft_errors::GetNftInfoError;
use script::{Builder, Script};

pub mod z_coin;
use crate::coin_errors::ValidatePaymentResult;
use crate::utxo::swap_proto_v2_scripts;
use crate::utxo::utxo_common::payment_script;
use crate::utxo::utxo_common::{payment_script, WaitForOutputSpendErr};
use z_coin::{ZCoin, ZcoinProtocolInfo};

pub type TransactionFut = Box<dyn Future<Item = TransactionEnum, Error = TransactionErr> + Send>;
Expand Down Expand Up @@ -984,9 +985,9 @@ pub trait SwapOps {

fn validate_fee(&self, validate_fee_args: ValidateFeeArgs<'_>) -> ValidatePaymentFut<()>;

fn validate_maker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentFut<()>;
async fn validate_maker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentResult<()>;

fn validate_taker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentFut<()>;
async fn validate_taker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentResult<()>;

fn check_if_my_payment_sent(
&self,
Expand Down Expand Up @@ -1463,7 +1464,7 @@ pub trait MakerCoinSwapOpsV2: CoinAssocTypes + Send + Sync + 'static {
async fn send_maker_payment_v2(&self, args: SendMakerPaymentArgs<'_, Self>) -> Result<Self::Tx, TransactionErr>;

/// Validate maker payment transaction
async fn validate_maker_payment_v2(&self, args: ValidateMakerPaymentArgs<'_, Self>) -> ValidateSwapV2TxResult;
async fn validate_maker_payment_v2(&self, args: ValidateMakerPaymentArgs<'_, Self>) -> ValidatePaymentResult<()>;

/// Refund maker payment transaction
async fn refund_maker_payment_v2(&self, args: RefundMakerPaymentArgs<'_, Self>)
Expand All @@ -1474,7 +1475,31 @@ pub trait MakerCoinSwapOpsV2: CoinAssocTypes + Send + Sync + 'static {
}

#[derive(Display)]
pub enum WaitForTakerPaymentSpendError {}
pub enum WaitForTakerPaymentSpendError {
#[display(
fmt = "Timed out waiting for taker payment spend, wait_until {}, now {}",
wait_until,
now
)]
Timeout {
wait_until: u64,
now: u64,
},
Internal(String),
}

impl From<WaitForOutputSpendErr> for WaitForTakerPaymentSpendError {
fn from(err: WaitForOutputSpendErr) -> Self {
match err {
WaitForOutputSpendErr::Timeout { wait_until, now } => {
WaitForTakerPaymentSpendError::Timeout { wait_until, now }
},
WaitForOutputSpendErr::NoOutputWithIndex(index) => {
WaitForTakerPaymentSpendError::Internal(format!("Tx doesn't have output with index {}", index))
},
}
}
}

/// Operations specific to taker coin in [Trading Protocol Upgrade implementation](https://github.com/KomodoPlatform/komodo-defi-framework/issues/1895)
#[async_trait]
Expand Down Expand Up @@ -1548,6 +1573,8 @@ pub trait TakerCoinSwapOpsV2: CoinAssocTypes + Send + Sync + 'static {
async fn wait_for_taker_payment_spend(
&self,
taker_payment: &Self::Tx,
from_block: u64,
wait_until: u64,
) -> MmResult<Self::Tx, WaitForTakerPaymentSpendError>;

/// Derives an HTLC key-pair and returns a public key corresponding to that key.
Expand Down
81 changes: 36 additions & 45 deletions mm2src/coins/qrc20.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::coin_errors::{MyAddressError, ValidatePaymentError};
use crate::coin_errors::{MyAddressError, ValidatePaymentError, ValidatePaymentResult};
use crate::eth::{self, u256_to_big_decimal, wei_from_big_decimal, TryToAddress};
use crate::qrc20::rpc_clients::{LogEntry, Qrc20ElectrumOps, Qrc20NativeOps, Qrc20RpcOps, TopicFilter, TxReceipt,
ViewContractCallType};
Expand Down Expand Up @@ -891,64 +891,55 @@ impl SwapOps for Qrc20Coin {
}

#[inline]
fn validate_maker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentFut<()> {
let payment_tx: UtxoTx = try_f!(deserialize(input.payment_tx.as_slice()));
let sender = try_f!(self
async fn validate_maker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentResult<()> {
let payment_tx: UtxoTx = deserialize(input.payment_tx.as_slice())?;
let sender = self
.contract_address_from_raw_pubkey(&input.other_pub)
.map_to_mm(ValidatePaymentError::InvalidParameter));
let swap_contract_address = try_f!(input
.map_to_mm(ValidatePaymentError::InvalidParameter)?;
let swap_contract_address = input
.swap_contract_address
.try_to_address()
.map_to_mm(ValidatePaymentError::InvalidParameter));
.map_to_mm(ValidatePaymentError::InvalidParameter)?;

let time_lock = try_f!(input
let time_lock = input
.time_lock
.try_into()
.map_to_mm(ValidatePaymentError::TimelockOverflow));
let selfi = self.clone();
let fut = async move {
selfi
.validate_payment(
payment_tx,
time_lock,
sender,
input.secret_hash,
input.amount,
swap_contract_address,
)
.await
};
Box::new(fut.boxed().compat())
.map_to_mm(ValidatePaymentError::TimelockOverflow)?;
self.validate_payment(
payment_tx,
time_lock,
sender,
input.secret_hash,
input.amount,
swap_contract_address,
)
.await
}

#[inline]
fn validate_taker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentFut<()> {
let swap_contract_address = try_f!(input
async fn validate_taker_payment(&self, input: ValidatePaymentInput) -> ValidatePaymentResult<()> {
let swap_contract_address = input
.swap_contract_address
.try_to_address()
.map_to_mm(ValidatePaymentError::InvalidParameter));
let payment_tx: UtxoTx = try_f!(deserialize(input.payment_tx.as_slice()));
let sender = try_f!(self
.map_to_mm(ValidatePaymentError::InvalidParameter)?;
let payment_tx: UtxoTx = deserialize(input.payment_tx.as_slice())?;
let sender = self
.contract_address_from_raw_pubkey(&input.other_pub)
.map_to_mm(ValidatePaymentError::InvalidParameter));
let time_lock = try_f!(input
.map_to_mm(ValidatePaymentError::InvalidParameter)?;
let time_lock = input
.time_lock
.try_into()
.map_to_mm(ValidatePaymentError::TimelockOverflow));
let selfi = self.clone();
let fut = async move {
selfi
.validate_payment(
payment_tx,
time_lock,
sender,
input.secret_hash,
input.amount,
swap_contract_address,
)
.await
};
Box::new(fut.boxed().compat())
.map_to_mm(ValidatePaymentError::TimelockOverflow)?;

self.validate_payment(
payment_tx,
time_lock,
sender,
input.secret_hash,
input.amount,
swap_contract_address,
)
.await
}

#[inline]
Expand Down
Loading

0 comments on commit c040a18

Please sign in to comment.