Skip to content

Commit

Permalink
Merge pull request #887 from TheCharlatan/abortAbortFix
Browse files Browse the repository at this point in the history
Swapd: Always abort all tasks on swap end
  • Loading branch information
h4sh3d authored Dec 28, 2022
2 parents 624bc1b + e3dbf4a commit 03cba21
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 127 deletions.
26 changes: 25 additions & 1 deletion src/swapd/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ use crate::swapd::temporal_safety::SWEEP_MONERO_THRESHOLD;
use crate::swapd::Opts;
use crate::syncerd::bitcoin_syncer::p2wpkh_signed_tx_fee;
use crate::syncerd::types::{Event, TransactionConfirmations};
use crate::syncerd::{Abort, Task, TaskTarget};
use crate::{
bus::ctl::{BitcoinFundingInfo, Checkpoint, CtlMsg, FundingInfo},
bus::info::{InfoMsg, SwapInfo},
bus::p2p::PeerMsg,
bus::sync::SyncMsg,
bus::{BusMsg, Outcome, ServiceBus},
syncerd::{HeightChanged, Task, TransactionRetrieved, XmrAddressAddendum},
syncerd::{HeightChanged, TransactionRetrieved, XmrAddressAddendum},
};
use crate::{
service::{Endpoints, Reporter},
Expand Down Expand Up @@ -703,6 +704,8 @@ impl Runtime {
// On SwapEnd, report immediately to ensure the progress message goes out before the swap is terminated, then let farcasterd know of the outcome.
if let SwapStateMachine::SwapEnd(outcome) = &self.swap_state_machine {
let outcome = outcome.clone(); // so we don't borrow self anymore
self.abort_all_syncer_tasks(endpoints)?;
self.txs = none!();
self.report_potential_state_change(endpoints)?;
self.send_ctl(
endpoints,
Expand Down Expand Up @@ -824,6 +827,27 @@ impl Runtime {
Ok(())
}

pub fn abort_all_syncer_tasks(&mut self, endpoints: &mut Endpoints) -> Result<(), Error> {
let abort_all = Task::Abort(Abort {
task_target: TaskTarget::AllTasks,
respond: false,
});

endpoints.send_to(
ServiceBus::Sync,
self.identity(),
self.syncer_state.monero_syncer(),
BusMsg::Sync(SyncMsg::Task(abort_all.clone())),
)?;
endpoints.send_to(
ServiceBus::Sync,
self.identity(),
self.syncer_state.bitcoin_syncer(),
BusMsg::Sync(SyncMsg::Task(abort_all)),
)?;
Ok(())
}

pub fn bob_watch_cancel_output_task(&mut self) -> Option<Task> {
// add a watch for the cancel tx output address. This is necessary so Bob can detect punish:
// Since Alice can craft the punish tx at her leisure and Bob won't know its txid in advance,
Expand Down
132 changes: 6 additions & 126 deletions src/swapd/swap_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@ use microservices::esb::Handler;
use monero::ViewPair;
use strict_encoding::{StrictDecode, StrictEncode};

use crate::swapd::temporal_safety::SWEEP_MONERO_THRESHOLD;
use crate::{
bus::{ctl::MoneroFundingInfo, p2p::Reveal},
syncerd::AddressTransaction,
};
use crate::{bus::ctl::MoneroFundingInfo, syncerd::AddressTransaction};
use crate::{bus::p2p::Reveal, swapd::temporal_safety::SWEEP_MONERO_THRESHOLD};
use crate::{
bus::{
ctl::{CtlMsg, InitMakerSwap, InitTakerSwap},
Expand All @@ -48,7 +45,7 @@ use crate::{
swap_key_manager::{HandleBuyProcedureSignatureRes, HandleRefundProcedureSignaturesRes},
syncer_client::{log_tx_created, log_tx_seen},
},
syncerd::{Abort, SweepSuccess, Task, TaskTarget, TransactionConfirmations},
syncerd::{SweepSuccess, Task, TransactionConfirmations},
Endpoints, Error,
};
use crate::{
Expand Down Expand Up @@ -130,7 +127,7 @@ use super::{
/// |
/// V
/// SwapEnd
///
///
/// ```
#[derive(Debug, Display, Clone, StrictDecode, StrictEncode)]
Expand Down Expand Up @@ -1353,43 +1350,9 @@ fn try_bob_cancel_final_to_swap_end(
{
match runtime.syncer_state.tasks.watched_txs.get(&id) {
Some(&TxLabel::Refund) => {
let abort_all = Task::Abort(Abort {
task_target: TaskTarget::AllTasks,
respond: false,
});
event.send_sync_service(
runtime.syncer_state.monero_syncer(),
SyncMsg::Task(abort_all.clone()),
)?;
event.send_sync_service(
runtime.syncer_state.bitcoin_syncer(),
SyncMsg::Task(abort_all),
)?;
// remove txs to invalidate outdated states
runtime.txs.remove(&TxLabel::Cancel);
runtime.txs.remove(&TxLabel::Refund);
runtime.txs.remove(&TxLabel::Buy);
runtime.txs.remove(&TxLabel::Punish);
// send swap outcome to farcasterd
Ok(Some(SwapStateMachine::SwapEnd(Outcome::FailureRefund)))
}
Some(&TxLabel::Punish) => {
let abort_all = Task::Abort(Abort {
task_target: TaskTarget::AllTasks,
respond: false,
});
event.send_sync_service(
runtime.syncer_state.monero_syncer(),
SyncMsg::Task(abort_all.clone()),
)?;
event.send_sync_service(
runtime.syncer_state.bitcoin_syncer(),
SyncMsg::Task(abort_all),
)?;
// remove txs to invalidate outdated states
runtime.txs.remove(&TxLabel::Cancel);
runtime.txs.remove(&TxLabel::Refund);
runtime.txs.remove(&TxLabel::Buy);
Ok(Some(SwapStateMachine::SwapEnd(Outcome::FailurePunish)))
}
_ => Ok(None),
Expand Down Expand Up @@ -1884,7 +1847,7 @@ fn try_alice_accordant_lock_to_alice_buy_procedure_signature(
}

fn try_alice_buy_procedure_signature_to_swap_end(
mut event: Event,
event: Event,
runtime: &mut Runtime,
) -> Result<Option<SwapStateMachine>, Error> {
match event.request {
Expand All @@ -1899,20 +1862,6 @@ fn try_alice_buy_procedure_signature_to_swap_end(
.final_tx(confirmations, Blockchain::Bitcoin)
&& runtime.syncer_state.tasks.watched_txs.get(&id) == Some(&TxLabel::Buy) =>
{
let abort_all = Task::Abort(Abort {
task_target: TaskTarget::AllTasks,
respond: false,
});
event.send_sync_service(
runtime.syncer_state.monero_syncer(),
SyncMsg::Task(abort_all.clone()),
)?;
event.send_sync_service(
runtime.syncer_state.bitcoin_syncer(),
SyncMsg::Task(abort_all),
)?;
runtime.txs.remove(&TxLabel::Cancel);
runtime.txs.remove(&TxLabel::Punish);
Ok(Some(SwapStateMachine::SwapEnd(Outcome::SuccessSwap)))
}
_ => Ok(None),
Expand Down Expand Up @@ -1970,25 +1919,7 @@ fn try_alice_canceled_to_alice_refund_or_alice_punish(
.temporal_safety
.final_tx(confirmations, Blockchain::Bitcoin) =>
{
let abort_all = Task::Abort(Abort {
task_target: TaskTarget::AllTasks,
respond: false,
});
event.send_sync_service(
runtime.syncer_state.monero_syncer(),
SyncMsg::Task(abort_all.clone()),
)?;
event.send_sync_service(
runtime.syncer_state.bitcoin_syncer(),
SyncMsg::Task(abort_all),
)?;
// remove txs to invalidate outdated states
runtime.txs.remove(&TxLabel::Cancel);
runtime.txs.remove(&TxLabel::Refund);
runtime.txs.remove(&TxLabel::Buy);
runtime.txs.remove(&TxLabel::Punish);
let outcome = Outcome::FailurePunish;
Ok(Some(SwapStateMachine::SwapEnd(outcome)))
Ok(Some(SwapStateMachine::SwapEnd(Outcome::FailurePunish)))
}

// Hit this path if Alice overfunded, moved on to AliceCanceled, but
Expand Down Expand Up @@ -2078,23 +2009,6 @@ fn try_alice_canceled_to_alice_refund_or_alice_punish(
CtlMsg::FundingCompleted(Blockchain::Monero),
)?;
}
let abort_all = Task::Abort(Abort {
task_target: TaskTarget::AllTasks,
respond: false,
});
event.send_sync_service(
runtime.syncer_state.monero_syncer(),
SyncMsg::Task(abort_all.clone()),
)?;
event.send_sync_service(
runtime.syncer_state.bitcoin_syncer(),
SyncMsg::Task(abort_all),
)?;
// remove txs to invalidate outdated states
runtime.txs.remove(&TxLabel::Cancel);
runtime.txs.remove(&TxLabel::Refund);
runtime.txs.remove(&TxLabel::Buy);
runtime.txs.remove(&TxLabel::Punish);
Ok(Some(SwapStateMachine::SwapEnd(Outcome::FailureRefund)))
}
}
Expand Down Expand Up @@ -2151,23 +2065,6 @@ fn try_alice_refund_sweeping_to_swap_end(
CtlMsg::FundingCompleted(Blockchain::Monero),
)?;
}
let abort_all = Task::Abort(Abort {
task_target: TaskTarget::AllTasks,
respond: false,
});
event.send_sync_service(
runtime.syncer_state.monero_syncer(),
SyncMsg::Task(abort_all.clone()),
)?;
event.send_sync_service(
runtime.syncer_state.bitcoin_syncer(),
SyncMsg::Task(abort_all),
)?;
// remove txs to invalidate outdated states
runtime.txs.remove(&TxLabel::Cancel);
runtime.txs.remove(&TxLabel::Refund);
runtime.txs.remove(&TxLabel::Buy);
runtime.txs.remove(&TxLabel::Punish);
Ok(Some(SwapStateMachine::SwapEnd(Outcome::FailureRefund)))
}
_ => Ok(None),
Expand All @@ -2192,23 +2089,6 @@ fn try_bob_buy_sweeping_to_swap_end(
CtlMsg::FundingCompleted(Blockchain::Bitcoin),
)?;
}
let abort_all = Task::Abort(Abort {
task_target: TaskTarget::AllTasks,
respond: false,
});
event.send_sync_service(
runtime.syncer_state.monero_syncer(),
SyncMsg::Task(abort_all.clone()),
)?;
event.send_sync_service(
runtime.syncer_state.bitcoin_syncer(),
SyncMsg::Task(abort_all),
)?;
// remove txs to invalidate outdated states
runtime.txs.remove(&TxLabel::Cancel);
runtime.txs.remove(&TxLabel::Refund);
runtime.txs.remove(&TxLabel::Buy);
runtime.txs.remove(&TxLabel::Punish);
Ok(Some(SwapStateMachine::SwapEnd(Outcome::SuccessSwap)))
}
_ => Ok(None),
Expand Down

0 comments on commit 03cba21

Please sign in to comment.