Skip to content

Commit

Permalink
swapd: extract temporal safety into its own file
Browse files Browse the repository at this point in the history
  • Loading branch information
zkao committed May 25, 2022
1 parent d24ae64 commit aa6408a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 68 deletions.
1 change: 1 addition & 0 deletions src/swapd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#[cfg(feature = "shell")]
mod opts;
mod runtime;
mod temporal_safety;
#[allow(dead_code)]
pub(self) mod storage;

Expand Down
72 changes: 4 additions & 68 deletions src/swapd/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ use std::{
time::{Duration, SystemTime},
};

use super::storage::{self, Driver};
use super::{
storage::{self, Driver},
temporal_safety::TemporalSafety,
};
use crate::rpc::{
request::{self, Msg},
Request, ServiceBus,
Expand Down Expand Up @@ -204,73 +207,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
}
}

struct SyncerTasks {
counter: u32,
watched_txs: HashMap<TaskId, TxLabel>,
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
}
}

0 comments on commit aa6408a

Please sign in to comment.