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

extract from Swapd runtime temporal safety #447

Merged
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
1 change: 1 addition & 0 deletions src/swapd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod runtime;
#[allow(dead_code)]
pub(self) mod storage;
mod syncer_client;
mod temporal_safety;

#[cfg(feature = "shell")]
pub use opts::Opts;
Expand Down
68 changes: 1 addition & 67 deletions src/swapd/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use std::{
use super::{
storage::{self, Driver},
syncer_client::{log_tx_received, SyncerState, SyncerTasks},
temporal_safety::TemporalSafety,
};
use crate::rpc::{
request::{self, Msg},
Expand Down Expand Up @@ -207,73 +208,6 @@ pub struct Runtime {
storage: Box<dyn storage::Driver>,
}

struct TemporalSafety {
cancel_timelock: BlockHeight,
punish_timelock: BlockHeight,
race_thr: BlockHeight,
btc_finality_thr: BlockHeight,
xmr_finality_thr: BlockHeight,
sweep_monero_thr: BlockHeight,
}

type BlockHeight = u32;

impl TemporalSafety {
/// check if temporal params are in correct order
fn valid_params(&self) -> Result<(), Error> {
let btc_finality = self.btc_finality_thr;
// let xmr_finality = self.xmr_finality_thr;
let cancel = self.cancel_timelock;
let punish = self.punish_timelock;
let race = self.race_thr;
if btc_finality < cancel
&& cancel < punish
&& btc_finality < race
&& punish > race
&& cancel > race
// && btc_finality < xmr_finality
{
Ok(())
} else {
Err(Error::Farcaster(s!(
"unsafe and invalid temporal parameters, timelocks, race and tx finality params"
)))
}
}
/// returns whether tx is final given the finality threshold set for the chain
fn final_tx(&self, confs: u32, coin: Coin) -> bool {
let finality_thr = match coin {
Coin::Bitcoin => self.btc_finality_thr,
Coin::Monero => self.xmr_finality_thr,
};
confs >= finality_thr
}
/// lock must be final, cancel cannot be raced, add + 1 to offset initial lock confirmation
fn stop_funding_before_cancel(&self, lock_confirmations: u32) -> bool {
self.final_tx(lock_confirmations, Coin::Bitcoin)
&& lock_confirmations > (self.cancel_timelock - self.race_thr + 1)
}
/// lock must be final, valid after lock_minedblock + cancel_timelock
fn valid_cancel(&self, lock_confirmations: u32) -> bool {
self.final_tx(lock_confirmations, Coin::Bitcoin)
&& lock_confirmations >= self.cancel_timelock
}
/// lock must be final, but buy shall not be raced with cancel
fn safe_buy(&self, lock_confirmations: u32) -> bool {
self.final_tx(lock_confirmations, Coin::Bitcoin)
&& lock_confirmations <= (self.cancel_timelock - self.race_thr)
}
/// cancel must be final, but refund shall not be raced with punish
fn safe_refund(&self, cancel_confirmations: u32) -> bool {
self.final_tx(cancel_confirmations, Coin::Bitcoin)
&& cancel_confirmations <= (self.punish_timelock - self.race_thr)
}
fn valid_punish(&self, cancel_confirmations: u32) -> bool {
self.final_tx(cancel_confirmations, Coin::Bitcoin)
&& cancel_confirmations >= self.punish_timelock
}
}

#[derive(Display, Clone)]
pub enum AliceState {
// #[display("Start: {0:#?} {1:#?}")]
Expand Down
68 changes: 68 additions & 0 deletions src/swapd/temporal_safety.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::{syncerd::Coin, Error};

pub type BlockHeight = u32;

pub struct TemporalSafety {
pub cancel_timelock: BlockHeight,
pub punish_timelock: BlockHeight,
pub race_thr: BlockHeight,
pub btc_finality_thr: BlockHeight,
pub xmr_finality_thr: BlockHeight,
pub sweep_monero_thr: BlockHeight,
}

impl TemporalSafety {
/// check if temporal params are in correct order
pub fn valid_params(&self) -> Result<(), Error> {
let btc_finality = self.btc_finality_thr;
// let xmr_finality = self.xmr_finality_thr;
let cancel = self.cancel_timelock;
let punish = self.punish_timelock;
let race = self.race_thr;
if btc_finality < cancel
&& cancel < punish
&& btc_finality < race
&& punish > race
&& cancel > race
// && btc_finality < xmr_finality
{
Ok(())
} else {
Err(Error::Farcaster(s!(
"unsafe and invalid temporal parameters, timelocks, race and tx finality params"
)))
}
}
/// returns whether tx is final given the finality threshold set for the chain
pub fn final_tx(&self, confs: u32, coin: Coin) -> bool {
let finality_thr = match coin {
Coin::Bitcoin => self.btc_finality_thr,
Coin::Monero => self.xmr_finality_thr,
};
confs >= finality_thr
}
/// lock must be final, cancel cannot be raced, add + 1 to offset initial lock confirmation
pub fn stop_funding_before_cancel(&self, lock_confirmations: u32) -> bool {
self.final_tx(lock_confirmations, Coin::Bitcoin)
&& lock_confirmations > (self.cancel_timelock - self.race_thr + 1)
}
/// lock must be final, valid after lock_minedblock + cancel_timelock
pub fn valid_cancel(&self, lock_confirmations: u32) -> bool {
self.final_tx(lock_confirmations, Coin::Bitcoin)
&& lock_confirmations >= self.cancel_timelock
}
/// lock must be final, but buy shall not be raced with cancel
pub fn safe_buy(&self, lock_confirmations: u32) -> bool {
self.final_tx(lock_confirmations, Coin::Bitcoin)
&& lock_confirmations <= (self.cancel_timelock - self.race_thr)
}
/// cancel must be final, but refund shall not be raced with punish
pub fn safe_refund(&self, cancel_confirmations: u32) -> bool {
self.final_tx(cancel_confirmations, Coin::Bitcoin)
&& cancel_confirmations <= (self.punish_timelock - self.race_thr)
}
pub fn valid_punish(&self, cancel_confirmations: u32) -> bool {
self.final_tx(cancel_confirmations, Coin::Bitcoin)
&& cancel_confirmations >= self.punish_timelock
}
}