Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(legacy-refunds): support going the spending path on refund #2280

Open
wants to merge 23 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
026cd08
refactor recover_funds for maker & taker
mariocynicys Nov 23, 2024
bb4a9ca
fix recover_funds tests
mariocynicys Nov 24, 2024
8cadb68
make refund_maker_payment more robust
mariocynicys Nov 24, 2024
553d054
make refund_taker_payment more robust
mariocynicys Nov 25, 2024
3aa1811
review(omer): typo - (taker -> maker) payment spend
mariocynicys Nov 30, 2024
df94b09
review(sami): use MmError to track the error origin
mariocynicys Nov 30, 2024
5e0709d
review(alina): restructure match and optimize tx_hex clone
mariocynicys Nov 30, 2024
07f5bed
remove extra line
mariocynicys Nov 30, 2024
ea294e4
can_refund_htlc errors are temporary
mariocynicys Dec 5, 2024
a28c768
wait_for_htlc_refund errors are temporary also
mariocynicys Dec 5, 2024
5c1bb6f
remove todo
mariocynicys Dec 5, 2024
4a44e16
store the swap aborthanle in `running_swaps`
mariocynicys Dec 6, 2024
e5c5f34
add stop/kickstart swap rpcs
mariocynicys Dec 6, 2024
245ea93
fix running_swap memory leak
mariocynicys Dec 16, 2024
c3b3b6b
Revert "remove todo"
mariocynicys Dec 16, 2024
70afcde
remove todo regarding refund finalization
mariocynicys Dec 16, 2024
0ce3c93
Revert "fix running_swap memory leak"
mariocynicys Dec 23, 2024
cc0db2e
review(dimxy): DRY, use a clourse for finding maker and taker coins
mariocynicys Dec 29, 2024
997ad63
review(dimxy): issue an info! log when stop rpc is used
mariocynicys Dec 29, 2024
497c394
Reapply "fix running_swap memory leak"
mariocynicys Jan 24, 2025
caf52dd
merge with origin/dev
mariocynicys Jan 24, 2025
90263d9
review(dimxy): use abortable instead of spawn_abortable and await it …
mariocynicys Jan 24, 2025
ff636f4
cargo fmt
mariocynicys Jan 24, 2025
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
1 change: 1 addition & 0 deletions mm2src/mm2_main/src/lp_native_dex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,7 @@ pub async fn lp_init(ctx: MmArc, version: String, datetime: String) -> MmInitRes
Timer::sleep(0.2).await
}
// Clearing up the running swaps removes any circular references that might prevent the context from being dropped.
// Note that this obviously isn't needed for native targets since the executable will terminate either way, but in WASM we need to have the memory cleaned up.
lp_swap::clear_running_swaps(&ctx);

Ok(())
Expand Down
56 changes: 37 additions & 19 deletions mm2src/mm2_main/src/lp_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,22 @@ pub struct RecoveredSwap {
transaction: TransactionEnum,
}

#[derive(Display, Debug, PartialEq)]
pub enum RecoverSwapError {
// We might not find the original payment tx on chain (e.g. re-orged). This doesn't mean though that nobody has it.
// TODO: These coins should be spent ASAP to avoid them getting locked (or stolen).
mariocynicys marked this conversation as resolved.
Show resolved Hide resolved
#[display(fmt = "The payment tx is not on-chain. Nothing to recover.")]
PaymentTxNotFound,
#[display(fmt = "An unknown error occurred. Retrying might fix it: {}", _0)]
Temporary(String),
#[display(fmt = "The swap is not recoverable: {}", _0)]
Irrecoverable(String),
#[display(fmt = "Wait {}s and try to recover again.", _0)]
WaitAndRetry(u64),
#[display(fmt = "The funds will be automatically recovered after lock-time: {}", _0)]
AutoRecoverableAfter(u64),
}

/// Represents the amount of a coin locked by ongoing swap
#[derive(Debug)]
pub struct LockedAmount {
Expand Down Expand Up @@ -516,8 +532,11 @@ struct LockedAmountInfo {
locked_amount: LockedAmount,
}

/// A running swap is the swap accompanied by the abort handle of the thread the swap is running on.
type RunningSwap = (Arc<dyn AtomicSwap>, AbortOnDropHandle);

struct SwapsContext {
running_swaps: Mutex<HashMap<Uuid, Arc<dyn AtomicSwap>>>,
running_swaps: Mutex<HashMap<Uuid, RunningSwap>>,
active_swaps_v2_infos: Mutex<HashMap<Uuid, ActiveSwapV2Info>>,
banned_pubkeys: Mutex<HashMap<H256Json, BanReason>>,
swap_msgs: Mutex<HashMap<Uuid, SwapMsgStore>>,
Expand Down Expand Up @@ -616,21 +635,20 @@ pub fn get_locked_amount(ctx: &MmArc, coin: &str) -> MmNumber {
let swap_ctx = SwapsContext::from_ctx(ctx).unwrap();
let swap_lock = swap_ctx.running_swaps.lock().unwrap();

let mut locked =
swap_lock
.values()
.flat_map(|swap| swap.locked_amount())
.fold(MmNumber::from(0), |mut total_amount, locked| {
if locked.coin == coin {
total_amount += locked.amount;
}
if let Some(trade_fee) = locked.trade_fee {
if trade_fee.coin == coin && !trade_fee.paid_from_trading_vol {
total_amount += trade_fee.amount;
}
let mut locked = swap_lock.values().flat_map(|(swap, _)| swap.locked_amount()).fold(
MmNumber::from(0),
|mut total_amount, locked| {
if locked.coin == coin {
total_amount += locked.amount;
}
if let Some(trade_fee) = locked.trade_fee {
if trade_fee.coin == coin && !trade_fee.paid_from_trading_vol {
total_amount += trade_fee.amount;
}
total_amount
});
}
total_amount
},
);
drop(swap_lock);

let locked_amounts = swap_ctx.locked_amounts.lock().unwrap();
Expand All @@ -653,7 +671,7 @@ pub fn get_locked_amount(ctx: &MmArc, coin: &str) -> MmNumber {

/// Clear up all the running swaps.
///
/// This doesn't mean that these swaps will be stopped. They can only be stopped from the abortable systems they are running on top of.
/// This also auto-stops any running swaps since their abort handles will get triggered (assuming these abort handles aren't already triggered by other means).
pub fn clear_running_swaps(ctx: &MmArc) {
let swap_ctx = SwapsContext::from_ctx(ctx).unwrap();
swap_ctx.running_swaps.lock().unwrap().clear();
Expand All @@ -666,8 +684,8 @@ fn get_locked_amount_by_other_swaps(ctx: &MmArc, except_uuid: &Uuid, coin: &str)

swap_lock
.values()
.filter(|swap| swap.uuid() != except_uuid)
.flat_map(|swap| swap.locked_amount())
.filter(|(swap, _)| swap.uuid() != except_uuid)
.flat_map(|(swap, _)| swap.locked_amount())
.fold(MmNumber::from(0), |mut total_amount, locked| {
if locked.coin == coin {
total_amount += locked.amount;
Expand All @@ -685,7 +703,7 @@ pub fn active_swaps_using_coins(ctx: &MmArc, coins: &HashSet<String>) -> Result<
let swap_ctx = try_s!(SwapsContext::from_ctx(ctx));
let swaps = try_s!(swap_ctx.running_swaps.lock());
let mut uuids = vec![];
for swap in swaps.values() {
for (swap, _) in swaps.values() {
if coins.contains(&swap.maker_coin().to_string()) || coins.contains(&swap.taker_coin().to_string()) {
uuids.push(*swap.uuid())
}
Expand Down
Loading
Loading