Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 74 additions & 20 deletions mm2src/coins/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2827,6 +2827,9 @@ impl EthCoin {
let swap_contract_address = try_tx_fus!(args.swap_contract_address.try_to_address());
let id = self.etomic_swap_id(args.time_lock, args.secret_hash);
let trade_amount = try_tx_fus!(wei_from_big_decimal(&args.amount, self.decimals));
let watcher_reward = args.watcher_reward.map(U256::from);
let time_lock = U256::from(args.time_lock);
let gas = U256::from(ETH_GAS);

let secret_hash = if args.secret_hash.len() == 32 {
ripemd160(args.secret_hash).to_vec()
Expand All @@ -2836,31 +2839,32 @@ impl EthCoin {

match &self.coin_type {
EthCoinType::Eth => {
let function_name = get_function_name("ethPayment", args.watcher_reward.is_some());
let function_name = get_function_name("ethPayment", watcher_reward.is_some());
let function = try_tx_fus!(SWAP_CONTRACT.function(&function_name));
let mut value = trade_amount;

let data = match args.watcher_reward {
let mut value = trade_amount;
let data = match watcher_reward {
Some(reward) => {
value += U256::from(reward);
value += reward;

try_tx_fus!(function.encode_input(&[
Token::FixedBytes(id),
Token::Address(receiver_addr),
Token::FixedBytes(secret_hash),
Token::Uint(U256::from(args.time_lock)),
Token::Uint(U256::from(reward)),
Token::Uint(time_lock),
Token::Uint(reward),
]))
},
None => try_tx_fus!(function.encode_input(&[
Token::FixedBytes(id),
Token::Address(receiver_addr),
Token::FixedBytes(secret_hash),
Token::Uint(U256::from(args.time_lock)),
Token::Uint(time_lock),
])),
};
drop_mutability!(value);

self.sign_and_send_transaction(value, Action::Call(swap_contract_address), data, U256::from(ETH_GAS))
self.sign_and_send_transaction(value, Action::Call(swap_contract_address), data, gas)
},
EthCoinType::Erc20 {
platform: _,
Expand All @@ -2870,7 +2874,7 @@ impl EthCoin {
.allowance(swap_contract_address)
.map_err(|e| TransactionErr::Plain(ERRL!("{}", e)));

let function_name = get_function_name("erc20Payment", args.watcher_reward.is_some());
let function_name = get_function_name("erc20Payment", watcher_reward.is_some());
let function = try_tx_fus!(SWAP_CONTRACT.function(&function_name));

let data = try_tx_fus!(function.encode_input(&[
Expand All @@ -2879,30 +2883,46 @@ impl EthCoin {
Token::Address(*token_addr),
Token::Address(receiver_addr),
Token::FixedBytes(secret_hash),
Token::Uint(U256::from(args.time_lock))
Token::Uint(time_lock)
]));
let value = U256::from(args.watcher_reward.unwrap_or(0));
let wait_for_required_allowance_until = args.wait_for_confirmation_until;

let arc = self.clone();
Box::new(allowance_fut.and_then(move |allowed| -> EthTxFut {
if allowed < value {
if allowed < trade_amount {
Box::new(
arc.approve(swap_contract_address, U256::max_value())
.and_then(move |_approved| {
arc.sign_and_send_transaction(
value,
Action::Call(swap_contract_address),
data,
U256::from(ETH_GAS),
.and_then(move |approved| {
// make sure the approve tx is confirmed by making sure that the allowed value has been updated
// this call is cheaper than waiting for confirmation calls
arc.wait_for_required_allowance(
swap_contract_address,
trade_amount,
wait_for_required_allowance_until,
)
.map_err(move |e| {
TransactionErr::Plain(ERRL!(
"Allowed value was not updated in time after sending approve transaction {:02x}: {}",
approved.tx_hash(),
e
))
})
.and_then(move |_| {
arc.sign_and_send_transaction(
watcher_reward.unwrap_or_else(|| 0.into()),
Action::Call(swap_contract_address),
data,
gas,
)
})
}),
)
} else {
Box::new(arc.sign_and_send_transaction(
value,
watcher_reward.unwrap_or_else(|| 0.into()),
Action::Call(swap_contract_address),
data,
U256::from(ETH_GAS),
gas,
))
}
}))
Expand Down Expand Up @@ -3499,6 +3519,40 @@ impl EthCoin {
Box::new(fut.boxed().compat())
}

fn wait_for_required_allowance(
&self,
spender: Address,
required_allowance: U256,
wait_until: u64,
) -> Web3RpcFut<()> {
const CHECK_ALLOWANCE_EVERY: f64 = 5.;

let selfi = self.clone();
let fut = async move {
loop {
if now_ms() / 1000 > wait_until {
return MmError::err(Web3RpcError::Internal(ERRL!(
"Waited too long until {} for allowance to be updated to at least {}",
wait_until,
required_allowance
)));
}

match selfi.allowance(spender).compat().await {
Ok(allowed) if allowed >= required_allowance => return Ok(()),
Ok(_allowed) => (),
Err(e) => match e.get_inner() {
Web3RpcError::Transport(e) => error!("Error {} on trying to get the allowed amount!", e),
_ => return Err(e),
},
}

Timer::sleep(CHECK_ALLOWANCE_EVERY).await;
}
};
Box::new(fut.boxed().compat())
}

fn approve(&self, spender: Address, amount: U256) -> EthTxFut {
let coin = self.clone();
let fut = async move {
Expand Down
2 changes: 2 additions & 0 deletions mm2src/coins/eth/eth_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ fn send_and_refund_erc20_payment() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = coin.send_maker_payment(maker_payment_args).wait().unwrap();
log!("{:?}", payment);
Expand Down Expand Up @@ -332,6 +333,7 @@ fn send_and_refund_eth_payment() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = coin.send_maker_payment(send_maker_payment_args).wait().unwrap();

Expand Down
1 change: 1 addition & 0 deletions mm2src/coins/eth/eth_wasm_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async fn test_send() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let tx = coin.send_maker_payment(maker_payment_args).compat().await;
console::log_1(&format!("{:?}", tx).into());
Expand Down
1 change: 1 addition & 0 deletions mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ pub struct SendPaymentArgs<'a> {
pub swap_unique_data: &'a [u8],
pub payment_instructions: &'a Option<PaymentInstructions>,
pub watcher_reward: Option<u64>,
pub wait_for_confirmation_until: u64,
}

#[derive(Clone, Debug)]
Expand Down
3 changes: 3 additions & 0 deletions mm2src/mm2_main/src/lp_swap/maker_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,8 @@ impl MakerSwap {
Ok(res) => match res {
Some(tx) => tx,
None => {
let maker_payment_wait_confirm =
wait_for_maker_payment_conf_until(self.r().data.started_at, self.r().data.lock_duration);
let payment_fut = self.maker_coin.send_maker_payment(SendPaymentArgs {
time_lock_duration: self.r().data.lock_duration,
time_lock: self.r().data.maker_payment_lock as u32,
Expand All @@ -838,6 +840,7 @@ impl MakerSwap {
swap_unique_data: &unique_data,
payment_instructions: &self.r().payment_instructions,
watcher_reward: reward_amount,
wait_for_confirmation_until: maker_payment_wait_confirm,
});

match payment_fut.compat().await {
Expand Down
1 change: 1 addition & 0 deletions mm2src/mm2_main/src/lp_swap/taker_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,7 @@ impl TakerSwap {
swap_unique_data: &unique_data,
payment_instructions: &self.r().payment_instructions,
watcher_reward: reward_amount,
wait_for_confirmation_until: self.r().data.taker_payment_lock,
});

match payment_fut.compat().await {
Expand Down
5 changes: 5 additions & 0 deletions mm2src/mm2_main/tests/docker_tests/docker_tests_inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ fn test_search_for_swap_tx_spend_native_was_refunded_taker() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let tx = coin.send_taker_payment(taker_payment_args).wait().unwrap();

Expand Down Expand Up @@ -111,6 +112,7 @@ fn test_search_for_swap_tx_spend_native_was_refunded_maker() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let tx = coin.send_maker_payment(maker_payment_args).wait().unwrap();

Expand Down Expand Up @@ -170,6 +172,7 @@ fn test_search_for_taker_swap_tx_spend_native_was_spent_by_maker() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let tx = coin.send_taker_payment(taker_payment_args).wait().unwrap();

Expand Down Expand Up @@ -230,6 +233,7 @@ fn test_search_for_maker_swap_tx_spend_native_was_spent_by_taker() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let tx = coin.send_maker_payment(maker_payment_args).wait().unwrap();

Expand Down Expand Up @@ -293,6 +297,7 @@ fn test_one_hundred_maker_payments_in_a_row_native() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let tx = coin.send_maker_payment(maker_payment_args).wait().unwrap();
if let TransactionEnum::UtxoTx(tx) = tx {
Expand Down
12 changes: 12 additions & 0 deletions mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ fn test_taker_spends_maker_payment() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = maker_coin.send_maker_payment(maker_payment_args).wait().unwrap();
let payment_tx_hash = payment.tx_hash();
Expand Down Expand Up @@ -287,6 +288,7 @@ fn test_maker_spends_taker_payment() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = taker_coin.send_taker_payment(taker_payment_args).wait().unwrap();
let payment_tx_hash = payment.tx_hash();
Expand Down Expand Up @@ -372,6 +374,7 @@ fn test_maker_refunds_payment() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = coin.send_maker_payment(maker_payment).wait().unwrap();
let payment_tx_hash = payment.tx_hash();
Expand Down Expand Up @@ -434,6 +437,7 @@ fn test_taker_refunds_payment() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = coin.send_taker_payment(taker_payment_args).wait().unwrap();
let payment_tx_hash = payment.tx_hash();
Expand Down Expand Up @@ -493,6 +497,7 @@ fn test_check_if_my_payment_sent() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = coin.send_maker_payment(maker_payment_args).wait().unwrap();
let payment_tx_hash = payment.tx_hash();
Expand Down Expand Up @@ -544,6 +549,7 @@ fn test_search_for_swap_tx_spend_taker_spent() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = maker_coin.send_maker_payment(maker_payment_args).wait().unwrap();
let payment_tx_hash = payment.tx_hash();
Expand Down Expand Up @@ -617,6 +623,7 @@ fn test_search_for_swap_tx_spend_maker_refunded() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = maker_coin.send_maker_payment(maker_payment_args).wait().unwrap();
let payment_tx_hash = payment.tx_hash();
Expand Down Expand Up @@ -689,6 +696,7 @@ fn test_search_for_swap_tx_spend_not_spent() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = maker_coin.send_maker_payment(maker_payment_args).wait().unwrap();
let payment_tx_hash = payment.tx_hash();
Expand Down Expand Up @@ -741,6 +749,7 @@ fn test_wait_for_tx_spend() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let payment = maker_coin.send_maker_payment(maker_payment_args).wait().unwrap();
let payment_tx_hash = payment.tx_hash();
Expand Down Expand Up @@ -1058,6 +1067,7 @@ fn test_get_max_taker_vol_and_trade_with_dynamic_trade_fee(coin: QtumCoin, priv_
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};

let _taker_payment_tx = coin
Expand Down Expand Up @@ -1457,6 +1467,7 @@ fn test_search_for_segwit_swap_tx_spend_native_was_refunded_maker() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let tx = coin.send_maker_payment(maker_payment).wait().unwrap();

Expand Down Expand Up @@ -1515,6 +1526,7 @@ fn test_search_for_segwit_swap_tx_spend_native_was_refunded_taker() {
swap_unique_data: &[],
payment_instructions: &None,
watcher_reward: None,
wait_for_confirmation_until: 0,
};
let tx = coin.send_taker_payment(taker_payment).wait().unwrap();

Expand Down
Loading