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 cc771da commit d2538af
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 69 deletions.
1 change: 1 addition & 0 deletions src/swapd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
mod opts;
mod runtime;
mod syncer_client;
mod temporal_safety;
#[allow(dead_code)]
pub(self) mod storage;

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

use super::{
storage::{self, Driver},
syncer_client::{SyncerState, SyncerTasks},
};
use super::{storage::{self, Driver}, syncer_client::{SyncerState, SyncerTasks}, temporal_safety::TemporalSafety};
use crate::rpc::{
request::{self, Msg},
Request, ServiceBus,
Expand Down Expand Up @@ -200,72 +197,8 @@ 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 {
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 d2538af

Please sign in to comment.