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

Swapd: Always abort all tasks on swap end #887

Merged
merged 4 commits into from
Dec 28, 2022
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
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