Skip to content

Commit

Permalink
fix(utxo-swap): apply events occurred while taker down (#2114)
Browse files Browse the repository at this point in the history
This commit adds missed apply_event for events discovered while taker was offline, like the maker spent or watcher refunded the taker payment.
  • Loading branch information
dimxy authored May 7, 2024
1 parent cdf032b commit 9a82349
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 6 deletions.
1 change: 0 additions & 1 deletion mm2src/mm2_main/src/lp_swap/maker_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2125,7 +2125,6 @@ pub async fn run_maker_swap(swap: RunMakerSwapInput, ctx: MmArc) {
)
}

#[cfg(target_arch = "wasm32")]
if event.is_error() {
error!("[swap uuid={uuid_str}] {event:?}");
}
Expand Down
5 changes: 4 additions & 1 deletion mm2src/mm2_main/src/lp_swap/taker_restart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use super::swap_watcher::{default_watcher_maker_payment_spend_factor, default_wa
#[cfg(not(any(test, feature = "run-docker-tests")))]
use common::now_sec;

pub async fn get_command_based_on_watcher_activity(
pub async fn get_command_based_on_maker_or_watcher_activity(
ctx: &MmArc,
swap: &TakerSwap,
mut saved: TakerSavedSwap,
Expand Down Expand Up @@ -136,6 +136,7 @@ pub async fn check_maker_payment_spend_and_add_event(
timestamp: now_ms(),
event,
};
swap.apply_event(to_save.event.clone());
saved.events.push(to_save);
let new_swap = SavedSwap::Taker(saved);
try_s!(new_swap.save_to_db(ctx).await);
Expand Down Expand Up @@ -208,6 +209,7 @@ pub async fn add_taker_payment_spent_event(
timestamp: now_ms(),
event,
};
swap.apply_event(to_save.event.clone());
saved.events.push(to_save);
Ok(())
}
Expand Down Expand Up @@ -255,6 +257,7 @@ pub async fn add_taker_payment_refunded_by_watcher_event(
timestamp: now_ms(),
event,
};
swap.apply_event(to_save.event.clone());
saved.events.push(to_save);

let new_swap = SavedSwap::Taker(saved);
Expand Down
8 changes: 4 additions & 4 deletions mm2src/mm2_main/src/lp_swap/taker_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::{broadcast_my_swap_status, broadcast_swap_message, broadcast_swap_msg
use crate::mm2::lp_network::subscribe_to_topic;
use crate::mm2::lp_ordermatch::TakerOrderBuilder;
use crate::mm2::lp_swap::swap_v2_common::mark_swap_as_finished;
use crate::mm2::lp_swap::taker_restart::get_command_based_on_watcher_activity;
use crate::mm2::lp_swap::taker_restart::get_command_based_on_maker_or_watcher_activity;
use crate::mm2::lp_swap::{broadcast_p2p_tx_msg, broadcast_swap_msg_every_delayed, tx_helper_topic,
wait_for_maker_payment_conf_duration, TakerSwapWatcherData, MAX_STARTED_AT_DIFF};
use coins::lp_price::fetch_swap_coins_price;
Expand Down Expand Up @@ -471,7 +471,6 @@ pub async fn run_taker_swap(swap: RunTakerSwapInput, ctx: MmArc) {
)
}

#[cfg(target_arch = "wasm32")]
if event.is_error() {
error!("[swap uuid={uuid}] {event:?}");
}
Expand Down Expand Up @@ -784,7 +783,7 @@ impl TakerSwap {
#[inline]
fn wait_refund_until(&self) -> u64 { self.r().data.taker_payment_lock + 3700 }

fn apply_event(&self, event: TakerSwapEvent) {
pub(crate) fn apply_event(&self, event: TakerSwapEvent) {
match event {
TakerSwapEvent::Started(data) => {
self.w().data = data;
Expand Down Expand Up @@ -2039,7 +2038,8 @@ impl TakerSwap {
&& maker_coin.is_supported_by_watchers()
&& saved.watcher_message_sent()
{
command = get_command_based_on_watcher_activity(&ctx, &swap, saved, command).await?;
// discover events occurred while taker was offline, due to maker or watcher activity
command = get_command_based_on_maker_or_watcher_activity(&ctx, &swap, saved, command).await?;
}
drop_mutability!(command);

Expand Down
49 changes: 49 additions & 0 deletions mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,55 @@ fn test_taker_completes_swap_after_restart() {
block_on(mm_bob.stop()).unwrap();
}

// Verifies https://github.com/KomodoPlatform/komodo-defi-framework/issues/2111
#[test]
fn test_taker_completes_swap_after_taker_payment_spent_while_offline() {
let coins = json!([mycoin_conf(1000), mycoin1_conf(1000)]);
let mut mm_bob = run_maker_node(&coins, &[], &[]);
let (mut mm_alice, mut alice_conf) = run_taker_node(&coins, &[], &[&mm_bob.ip.to_string()]);

let uuids = block_on(start_swaps(
&mut mm_bob,
&mut mm_alice,
&[("MYCOIN1", "MYCOIN")],
25.,
25.,
2.,
));

// stop taker after taker payment sent
block_on(mm_alice.wait_for_log(120., |log| log.contains("Taker payment tx"))).unwrap();
alice_conf.conf["dbdir"] = mm_alice.folder.join("DB").to_str().unwrap().into();
block_on(mm_alice.stop()).unwrap();

// wait for taker payment spent by maker
block_on(mm_bob.wait_for_log(120., |log| log.contains("Taker payment spend tx"))).unwrap();
// and restart taker
let mut mm_alice = block_on(MarketMakerIt::start_with_envs(
alice_conf.conf,
alice_conf.rpc_password.clone(),
None,
&[],
))
.unwrap();

let (_alice_dump_log, _alice_dump_dashboard) = mm_alice.mm_dump();
log!("Alice log path: {}", mm_alice.log_path.display());
enable_coin(&mm_alice, "MYCOIN");
enable_coin(&mm_alice, "MYCOIN1");

block_on(wait_for_swaps_finish_and_check_status(
&mut mm_bob,
&mut mm_alice,
&uuids,
2.,
25.,
));

block_on(mm_alice.stop()).unwrap();
block_on(mm_bob.stop()).unwrap();
}

#[test]
fn test_watcher_spends_maker_payment_utxo_utxo() {
let alice_privkey = hex::encode(random_secp256k1_secret());
Expand Down

0 comments on commit 9a82349

Please sign in to comment.