From 6003ad0bc72f0cb483be4f841289b2d5311fbb05 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Thu, 18 Nov 2021 14:46:06 +1100 Subject: [PATCH 1/3] Cleanup impl blocks --- daemon/src/taker_cfd.rs | 55 +++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/daemon/src/taker_cfd.rs b/daemon/src/taker_cfd.rs index ea3920f..bcbe12b 100644 --- a/daemon/src/taker_cfd.rs +++ b/daemon/src/taker_cfd.rs @@ -319,36 +319,7 @@ impl Actor { } Ok(()) } -} -impl Actor -where - W: xtra::Handler, -{ - async fn handle_oracle_attestation(&mut self, attestation: oracle::Attestation) -> Result<()> { - let mut conn = self.db.acquire().await?; - cfd_actors::handle_oracle_attestation( - attestation, - &mut conn, - &self.wallet, - &self.projection_actor, - ) - .await?; - Ok(()) - } - - async fn handle_monitoring_event(&mut self, event: monitor::Event) -> Result<()> { - let mut conn = self.db.acquire().await?; - cfd_actors::handle_monitoring_event(event, &mut conn, &self.wallet, &self.projection_actor) - .await?; - Ok(()) - } -} - -impl Actor -where - W: xtra::Handler, -{ async fn handle_propose_roll_over(&mut self, order_id: OrderId) -> Result<()> { if self.current_pending_proposals.contains_key(&order_id) { anyhow::bail!("An update for order id {} is already in progress", order_id) @@ -377,11 +348,29 @@ where Ok(()) } } -impl Actor where - W: xtra::Handler - + xtra::Handler - + xtra::Handler + +impl Actor +where + W: xtra::Handler, { + async fn handle_oracle_attestation(&mut self, attestation: oracle::Attestation) -> Result<()> { + let mut conn = self.db.acquire().await?; + cfd_actors::handle_oracle_attestation( + attestation, + &mut conn, + &self.wallet, + &self.projection_actor, + ) + .await?; + Ok(()) + } + + async fn handle_monitoring_event(&mut self, event: monitor::Event) -> Result<()> { + let mut conn = self.db.acquire().await?; + cfd_actors::handle_monitoring_event(event, &mut conn, &self.wallet, &self.projection_actor) + .await?; + Ok(()) + } } impl Actor From d853b8ec0b51feaf0d372d9b0a80fb44ed25fd8f Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Thu, 18 Nov 2021 16:27:41 +1100 Subject: [PATCH 2/3] Move tests to bottom of file --- daemon/src/model/cfd.rs | 350 ++++++++++++++++++++-------------------- 1 file changed, 175 insertions(+), 175 deletions(-) diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index a4ad16d..4af0e8c 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -1464,6 +1464,181 @@ fn calculate_profit( Ok((profit, Percent(percent))) } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct Cet { + pub tx: Transaction, + pub adaptor_sig: EcdsaAdaptorSignature, + + // TODO: Range + number of digits (usize) could be represented as Digits similar to what we do + // in the protocol lib + pub range: RangeInclusive, + pub n_bits: usize, +} + +/// Contains all data we've assembled about the CFD through the setup protocol. +/// +/// All contained signatures are the signatures of THE OTHER PARTY. +/// To use any of these transactions, we need to re-sign them with the correct secret key. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct Dlc { + pub identity: SecretKey, + pub identity_counterparty: PublicKey, + pub revocation: SecretKey, + pub revocation_pk_counterparty: PublicKey, + pub publish: SecretKey, + pub publish_pk_counterparty: PublicKey, + pub maker_address: Address, + pub taker_address: Address, + + /// The fully signed lock transaction ready to be published on chain + pub lock: (Transaction, Descriptor), + pub commit: (Transaction, EcdsaAdaptorSignature, Descriptor), + pub cets: HashMap>, + pub refund: (Transaction, Signature), + + #[serde(with = "::bdk::bitcoin::util::amount::serde::as_sat")] + pub maker_lock_amount: Amount, + #[serde(with = "::bdk::bitcoin::util::amount::serde::as_sat")] + pub taker_lock_amount: Amount, + + pub revoked_commit: Vec, +} + +impl Dlc { + /// Create a close transaction based on the current contract and a settlement proposals + pub fn close_transaction( + &self, + proposal: &crate::model::cfd::SettlementProposal, + ) -> Result<(Transaction, Signature)> { + let (lock_tx, lock_desc) = &self.lock; + let (lock_outpoint, lock_amount) = { + let outpoint = lock_tx + .outpoint(&lock_desc.script_pubkey()) + .expect("lock script to be in lock tx"); + let amount = Amount::from_sat(lock_tx.output[outpoint.vout as usize].value); + + (outpoint, amount) + }; + let (tx, sighash) = maia::close_transaction( + lock_desc, + lock_outpoint, + lock_amount, + (&self.maker_address, proposal.maker), + (&self.taker_address, proposal.taker), + ) + .context("Unable to collaborative close transaction")?; + + let sig = SECP256K1.sign(&sighash, &self.identity); + + Ok((tx, sig)) + } + + pub fn finalize_spend_transaction( + &self, + (close_tx, own_sig): (Transaction, Signature), + counterparty_sig: Signature, + ) -> Result { + let own_pk = PublicKey::new(secp256k1_zkp::PublicKey::from_secret_key( + SECP256K1, + &self.identity, + )); + + let (_, lock_desc) = &self.lock; + let spend_tx = maia::finalize_spend_transaction( + close_tx, + lock_desc, + (own_pk, own_sig), + (self.identity_counterparty, counterparty_sig), + )?; + + Ok(spend_tx) + } + + pub fn refund_amount(&self, role: Role) -> Amount { + let our_script_pubkey = match role { + Role::Taker => self.taker_address.script_pubkey(), + Role::Maker => self.maker_address.script_pubkey(), + }; + + self.refund + .0 + .output + .iter() + .find(|output| output.script_pubkey == our_script_pubkey) + .map(|output| Amount::from_sat(output.value)) + .unwrap_or_default() + } + + pub fn script_pubkey_for(&self, role: Role) -> Script { + match role { + Role::Maker => self.maker_address.script_pubkey(), + Role::Taker => self.taker_address.script_pubkey(), + } + } +} + +/// Information which we need to remember in order to construct a +/// punishment transaction in case the counterparty publishes a +/// revoked commit transaction. +/// +/// It also includes the information needed to monitor for the +/// publication of the revoked commit transaction. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct RevokedCommit { + // To build punish transaction + pub encsig_ours: EcdsaAdaptorSignature, + pub revocation_sk_theirs: SecretKey, + pub publication_pk_theirs: PublicKey, + // To monitor revoked commit transaction + pub txid: Txid, + pub script_pubkey: Script, +} + +/// Used when transactions (e.g. collaborative close) are recorded as a part of +/// CfdState in the cases when we can't solely rely on state transition +/// timestamp as it could have occured for different reasons (like a new +/// attestation in Open state) +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub struct CollaborativeSettlement { + pub tx: Transaction, + pub timestamp: Timestamp, + #[serde(with = "::bdk::bitcoin::util::amount::serde::as_sat")] + payout: Amount, + price: Price, +} + +impl CollaborativeSettlement { + pub fn new(tx: Transaction, own_script_pubkey: Script, price: Price) -> Result { + // Falls back to Amount::ZERO in case we don't find an output that matches out script pubkey + // The assumption is, that this can happen for cases where we were liuqidated + let payout = match tx + .output + .iter() + .find(|output| output.script_pubkey == own_script_pubkey) + .map(|output| Amount::from_sat(output.value)) + { + Some(payout) => payout, + None => { + tracing::error!( + "Collaborative settlement with a zero amount, this should really not happen!" + ); + Amount::ZERO + } + }; + + Ok(Self { + tx, + timestamp: Timestamp::now(), + payout, + price, + }) + } + + pub fn payout(&self) -> Amount { + self.payout + } +} + #[cfg(test)] mod tests { use super::*; @@ -1715,178 +1890,3 @@ mod tests { assert_eq!(id, deserialized); } } - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Cet { - pub tx: Transaction, - pub adaptor_sig: EcdsaAdaptorSignature, - - // TODO: Range + number of digits (usize) could be represented as Digits similar to what we do - // in the protocol lib - pub range: RangeInclusive, - pub n_bits: usize, -} - -/// Contains all data we've assembled about the CFD through the setup protocol. -/// -/// All contained signatures are the signatures of THE OTHER PARTY. -/// To use any of these transactions, we need to re-sign them with the correct secret key. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Dlc { - pub identity: SecretKey, - pub identity_counterparty: PublicKey, - pub revocation: SecretKey, - pub revocation_pk_counterparty: PublicKey, - pub publish: SecretKey, - pub publish_pk_counterparty: PublicKey, - pub maker_address: Address, - pub taker_address: Address, - - /// The fully signed lock transaction ready to be published on chain - pub lock: (Transaction, Descriptor), - pub commit: (Transaction, EcdsaAdaptorSignature, Descriptor), - pub cets: HashMap>, - pub refund: (Transaction, Signature), - - #[serde(with = "::bdk::bitcoin::util::amount::serde::as_sat")] - pub maker_lock_amount: Amount, - #[serde(with = "::bdk::bitcoin::util::amount::serde::as_sat")] - pub taker_lock_amount: Amount, - - pub revoked_commit: Vec, -} - -impl Dlc { - /// Create a close transaction based on the current contract and a settlement proposals - pub fn close_transaction( - &self, - proposal: &crate::model::cfd::SettlementProposal, - ) -> Result<(Transaction, Signature)> { - let (lock_tx, lock_desc) = &self.lock; - let (lock_outpoint, lock_amount) = { - let outpoint = lock_tx - .outpoint(&lock_desc.script_pubkey()) - .expect("lock script to be in lock tx"); - let amount = Amount::from_sat(lock_tx.output[outpoint.vout as usize].value); - - (outpoint, amount) - }; - let (tx, sighash) = maia::close_transaction( - lock_desc, - lock_outpoint, - lock_amount, - (&self.maker_address, proposal.maker), - (&self.taker_address, proposal.taker), - ) - .context("Unable to collaborative close transaction")?; - - let sig = SECP256K1.sign(&sighash, &self.identity); - - Ok((tx, sig)) - } - - pub fn finalize_spend_transaction( - &self, - (close_tx, own_sig): (Transaction, Signature), - counterparty_sig: Signature, - ) -> Result { - let own_pk = PublicKey::new(secp256k1_zkp::PublicKey::from_secret_key( - SECP256K1, - &self.identity, - )); - - let (_, lock_desc) = &self.lock; - let spend_tx = maia::finalize_spend_transaction( - close_tx, - lock_desc, - (own_pk, own_sig), - (self.identity_counterparty, counterparty_sig), - )?; - - Ok(spend_tx) - } - - pub fn refund_amount(&self, role: Role) -> Amount { - let our_script_pubkey = match role { - Role::Taker => self.taker_address.script_pubkey(), - Role::Maker => self.maker_address.script_pubkey(), - }; - - self.refund - .0 - .output - .iter() - .find(|output| output.script_pubkey == our_script_pubkey) - .map(|output| Amount::from_sat(output.value)) - .unwrap_or_default() - } - - pub fn script_pubkey_for(&self, role: Role) -> Script { - match role { - Role::Maker => self.maker_address.script_pubkey(), - Role::Taker => self.taker_address.script_pubkey(), - } - } -} - -/// Information which we need to remember in order to construct a -/// punishment transaction in case the counterparty publishes a -/// revoked commit transaction. -/// -/// It also includes the information needed to monitor for the -/// publication of the revoked commit transaction. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct RevokedCommit { - // To build punish transaction - pub encsig_ours: EcdsaAdaptorSignature, - pub revocation_sk_theirs: SecretKey, - pub publication_pk_theirs: PublicKey, - // To monitor revoked commit transaction - pub txid: Txid, - pub script_pubkey: Script, -} - -/// Used when transactions (e.g. collaborative close) are recorded as a part of -/// CfdState in the cases when we can't solely rely on state transition -/// timestamp as it could have occured for different reasons (like a new -/// attestation in Open state) -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -pub struct CollaborativeSettlement { - pub tx: Transaction, - pub timestamp: Timestamp, - #[serde(with = "::bdk::bitcoin::util::amount::serde::as_sat")] - payout: Amount, - price: Price, -} - -impl CollaborativeSettlement { - pub fn new(tx: Transaction, own_script_pubkey: Script, price: Price) -> Result { - // Falls back to Amount::ZERO in case we don't find an output that matches out script pubkey - // The assumption is, that this can happen for cases where we were liuqidated - let payout = match tx - .output - .iter() - .find(|output| output.script_pubkey == own_script_pubkey) - .map(|output| Amount::from_sat(output.value)) - { - Some(payout) => payout, - None => { - tracing::error!( - "Collaborative settlement with a zero amount, this should really not happen!" - ); - Amount::ZERO - } - }; - - Ok(Self { - tx, - timestamp: Timestamp::now(), - payout, - price, - }) - } - - pub fn payout(&self) -> Amount { - self.payout - } -} From 585057532773501d46d019fa6e6eaac1f8833b09 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Thu, 18 Nov 2021 14:57:10 +1100 Subject: [PATCH 3/3] Fixed settlement interval A configurable settlement interval for the maker causes friction when implementing auto-rollover, because the settlement interval is not known to the taker. The settlement interval should not be configurable, thus the configurable settlement interval is removed on the maker side. The cfd actors and oracle actor use a global constant to decide the settlement interval and oracle even lookahead. Not pulling the constant into the actors is a conscious decision, it allows us to set this to a different value in the actor tests. The fact that we use the same constant for cfd actor and oracle actor is an implementation detail. --- daemon/src/db.rs | 10 +++++----- daemon/src/lib.rs | 16 ++++++++++++++-- daemon/src/maker.rs | 12 +++--------- daemon/src/maker_cfd.rs | 12 ++++++------ daemon/src/model/cfd.rs | 18 +++++++++--------- daemon/src/taker.rs | 4 ++-- daemon/src/to_sse_event.rs | 2 +- daemon/tests/harness/mod.rs | 4 ++-- 8 files changed, 42 insertions(+), 36 deletions(-) diff --git a/daemon/src/db.rs b/daemon/src/db.rs index 429793b..cffc11f 100644 --- a/daemon/src/db.rs +++ b/daemon/src/db.rs @@ -39,7 +39,7 @@ pub async fn insert_order(order: &Order, conn: &mut PoolConnection) -> a .bind(order.leverage.get()) .bind(&order.liquidation_price.to_string()) .bind(&order.creation_timestamp.seconds()) - .bind(&order.settlement_time_interval_hours.whole_seconds()) + .bind(&order.settlement_interval.whole_seconds()) .bind(&order.origin) .bind(&order.oracle_event_id.to_string()) .execute(conn) @@ -90,7 +90,7 @@ pub async fn load_order_by_id( leverage: row.leverage, liquidation_price: row.liquidation_price.parse()?, creation_timestamp: row.ts_secs, - settlement_time_interval_hours: Duration::new(row.settlement_time_interval_secs, 0), + settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), origin: row.origin, oracle_event_id: row.oracle_event_id.parse()?, }) @@ -307,7 +307,7 @@ pub async fn load_cfd_by_order_id( leverage: row.leverage, liquidation_price: row.liquidation_price.parse()?, creation_timestamp: row.ts_secs, - settlement_time_interval_hours: Duration::new(row.settlement_time_interval_secs, 0), + settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), origin: row.origin, oracle_event_id: row.oracle_event_id.parse()?, }; @@ -405,7 +405,7 @@ pub async fn load_all_cfds(conn: &mut PoolConnection) -> anyhow::Result< leverage: row.leverage, liquidation_price: row.liquidation_price.parse()?, creation_timestamp: row.ts_secs, - settlement_time_interval_hours: Duration::new(row.settlement_time_interval_secs, 0), + settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), origin: row.origin, oracle_event_id: row.oracle_event_id.parse()?, }; @@ -511,7 +511,7 @@ pub async fn load_cfds_by_oracle_event_id( leverage: row.leverage, liquidation_price: row.liquidation_price.parse()?, creation_timestamp: row.ts_secs, - settlement_time_interval_hours: Duration::new(row.settlement_time_interval_secs, 0), + settlement_interval: Duration::new(row.settlement_time_interval_secs, 0), origin: row.origin, oracle_event_id: row.oracle_event_id.parse()?, }; diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index 5a5cc38..54e2b17 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -52,6 +52,18 @@ pub const HEARTBEAT_INTERVAL: std::time::Duration = Duration::from_secs(5); pub const N_PAYOUTS: usize = 200; +/// The interval until the cfd gets settled, i.e. the attestation happens +/// +/// This variable defines at what point in time the oracle event id will be chose to settle the cfd. +/// Hence, this constant defines how long a cfd is open (until it gets either settled or rolled +/// over). +/// +/// Multiple code parts align on this constant: +/// - How the oracle event id is chosen when creating an order (maker) +/// - The sliding window of cached oracle announcements (maker, taker) +/// - The auto-rollover time-window (taker) +pub const SETTLEMENT_INTERVAL: time::Duration = time::Duration::hours(24); + /// Struct controlling the lifetime of the async tasks, /// such as running actors and periodic notifications. /// If it gets dropped, all tasks are cancelled. @@ -106,7 +118,7 @@ where Box>, Box>, ) -> T, - settlement_time_interval_hours: time::Duration, + settlement_interval: time::Duration, n_payouts: usize, projection_actor: Address, ) -> Result @@ -126,7 +138,7 @@ where let (cfd_actor_addr, cfd_actor_fut) = maker_cfd::Actor::new( db, wallet_addr, - settlement_time_interval_hours, + settlement_interval, oracle_pk, projection_actor, inc_conn_addr.clone(), diff --git a/daemon/src/maker.rs b/daemon/src/maker.rs index 477edca..8abcbcb 100644 --- a/daemon/src/maker.rs +++ b/daemon/src/maker.rs @@ -13,6 +13,7 @@ use daemon::tokio_ext::FutureExt; use daemon::{ bitmex_price_feed, db, housekeeping, logger, maker_cfd, maker_inc_connections, monitor, oracle, projection, wallet, wallet_sync, MakerActorSystem, Tasks, HEARTBEAT_INTERVAL, N_PAYOUTS, + SETTLEMENT_INTERVAL, }; use sqlx::sqlite::SqliteConnectOptions; use sqlx::SqlitePool; @@ -51,10 +52,6 @@ struct Opts { #[clap(short, long, default_value = "Debug")] log_level: LevelFilter, - /// The time interval until potential settlement of each CFD in hours - #[clap(long, default_value = "24")] - settlement_time_interval_hours: u8, - #[clap(subcommand)] network: Network, } @@ -247,9 +244,6 @@ async fn main() -> Result<()> { housekeeping::transition_non_continue_cfds_to_setup_failed(&mut conn).await?; housekeeping::rebroadcast_transactions(&mut conn, &wallet).await?; - let settlement_time_interval_hours = - time::Duration::hours(opts.settlement_time_interval_hours as i64); - let (projection_actor, projection_context) = xtra::Context::new(None); let MakerActorSystem { @@ -260,7 +254,7 @@ async fn main() -> Result<()> { db.clone(), wallet.clone(), oracle, - |cfds, channel| oracle::Actor::new(cfds, channel, settlement_time_interval_hours), + |cfds, channel| oracle::Actor::new(cfds, channel, SETTLEMENT_INTERVAL), { |channel, cfds| { let electrum = opts.network.electrum().to_string(); @@ -270,7 +264,7 @@ async fn main() -> Result<()> { |channel0, channel1| { maker_inc_connections::Actor::new(channel0, channel1, identity_sk, HEARTBEAT_INTERVAL) }, - time::Duration::hours(opts.settlement_time_interval_hours as i64), + SETTLEMENT_INTERVAL, N_PAYOUTS, projection_actor.clone(), ) diff --git a/daemon/src/maker_cfd.rs b/daemon/src/maker_cfd.rs index a8e96c8..6738f33 100644 --- a/daemon/src/maker_cfd.rs +++ b/daemon/src/maker_cfd.rs @@ -62,7 +62,7 @@ pub struct FromTaker { pub struct Actor { db: sqlx::SqlitePool, wallet: Address, - settlement_time_interval_hours: Duration, + settlement_interval: Duration, oracle_pk: schnorrsig::PublicKey, projection_actor: Address, takers: Address, @@ -100,7 +100,7 @@ impl Actor { pub fn new( db: sqlx::SqlitePool, wallet: Address, - settlement_time_interval_hours: Duration, + settlement_interval: Duration, oracle_pk: schnorrsig::PublicKey, projection_actor: Address, takers: Address, @@ -111,7 +111,7 @@ impl Actor { Self { db, wallet, - settlement_time_interval_hours, + settlement_interval, oracle_pk, projection_actor, takers, @@ -736,7 +736,7 @@ where let dlc = cfd.open_dlc().context("CFD was in wrong state")?; let oracle_event_id = oracle::next_announcement_after( - time::OffsetDateTime::now_utc() + cfd.order.settlement_time_interval_hours, + time::OffsetDateTime::now_utc() + cfd.order.settlement_interval, )?; let announcement = self .oracle_actor @@ -951,7 +951,7 @@ where } = msg; let oracle_event_id = oracle::next_announcement_after( - time::OffsetDateTime::now_utc() + self.settlement_time_interval_hours, + time::OffsetDateTime::now_utc() + self.settlement_interval, )?; let order = Order::new( @@ -960,7 +960,7 @@ where max_quantity, Origin::Ours, oracle_event_id, - self.settlement_time_interval_hours, + self.settlement_interval, )?; // 1. Save to DB diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index 4af0e8c..46b44f9 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -115,7 +115,7 @@ pub struct Order { pub creation_timestamp: Timestamp, /// The duration that will be used for calculating the settlement timestamp - pub settlement_time_interval_hours: Duration, + pub settlement_interval: Duration, pub origin: Origin, @@ -132,7 +132,7 @@ impl Order { max_quantity: Usd, origin: Origin, oracle_event_id: BitMexPriceEventId, - settlement_time_interval_hours: Duration, + settlement_interval: Duration, ) -> Result { let leverage = Leverage::new(2)?; let liquidation_price = calculate_long_liquidation_price(leverage, price); @@ -147,7 +147,7 @@ impl Order { liquidation_price, position: Position::Short, creation_timestamp: Timestamp::now(), - settlement_time_interval_hours, + settlement_interval, origin, oracle_event_id, }) @@ -671,7 +671,7 @@ impl Cfd { } pub fn refund_timelock_in_blocks(&self) -> u32 { - (self.order.settlement_time_interval_hours * Cfd::REFUND_THRESHOLD) + (self.order.settlement_interval * Cfd::REFUND_THRESHOLD) .as_blocks() .ceil() as u32 } @@ -680,20 +680,20 @@ impl Cfd { self.order.oracle_event_id.timestamp() } - /// A factor to be added to the CFD order settlement_time_interval_hours for calculating the + /// A factor to be added to the CFD order settlement_interval for calculating the /// refund timelock. /// /// The refund timelock is important in case the oracle disappears or never publishes a /// signature. Ideally, both users collaboratively settle in the refund scenario. This /// factor is important if the users do not settle collaboratively. - /// `1.5` times the settlement_time_interval_hours as defined in CFD order should be safe in the + /// `1.5` times the settlement_interval as defined in CFD order should be safe in the /// extreme case where a user publishes the commit transaction right after the contract was /// initialized. In this case, the oracle still has `1.0 * - /// cfdorder.settlement_time_interval_hours` time to attest and no one can publish the refund + /// cfdorder.settlement_interval` time to attest and no one can publish the refund /// transaction. /// The downside is that if the oracle disappears: the users would only notice at the end - /// of the cfd settlement_time_interval_hours. In this case the users has to wait for another - /// `1.5` times of the settlement_time_interval_hours to get his funds back. + /// of the cfd settlement_interval. In this case the users has to wait for another + /// `1.5` times of the settlement_interval to get his funds back. const REFUND_THRESHOLD: f32 = 1.5; pub const CET_TIMELOCK: u32 = 12; diff --git a/daemon/src/taker.rs b/daemon/src/taker.rs index 6fa56ec..fc5c21c 100644 --- a/daemon/src/taker.rs +++ b/daemon/src/taker.rs @@ -13,6 +13,7 @@ use daemon::tokio_ext::FutureExt; use daemon::{ bitmex_price_feed, connection, db, housekeeping, logger, monitor, oracle, projection, taker_cfd, wallet, wallet_sync, TakerActorSystem, Tasks, HEARTBEAT_INTERVAL, N_PAYOUTS, + SETTLEMENT_INTERVAL, }; use sqlx::sqlite::SqliteConnectOptions; use sqlx::SqlitePool; @@ -30,7 +31,6 @@ use xtra::Actor; mod routes_taker; -pub const ANNOUNCEMENT_LOOKAHEAD: time::Duration = time::Duration::hours(24); const CONNECTION_RETRY_INTERVAL: Duration = Duration::from_secs(5); #[derive(Parser)] @@ -247,7 +247,7 @@ async fn main() -> Result<()> { wallet.clone(), oracle, identity_sk, - |cfds, channel| oracle::Actor::new(cfds, channel, ANNOUNCEMENT_LOOKAHEAD), + |cfds, channel| oracle::Actor::new(cfds, channel, SETTLEMENT_INTERVAL), { |channel, cfds| { let electrum = opts.network.electrum().to_string(); diff --git a/daemon/src/to_sse_event.rs b/daemon/src/to_sse_event.rs index 0acd0ed..ad340fb 100644 --- a/daemon/src/to_sse_event.rs +++ b/daemon/src/to_sse_event.rs @@ -339,7 +339,7 @@ impl ToSseEvent for Option { liquidation_price: order.liquidation_price.into(), creation_timestamp: order.creation_timestamp, settlement_time_interval_in_secs: order - .settlement_time_interval_hours + .settlement_interval .whole_seconds() .try_into() .expect("settlement_time_interval_hours is always positive number"), diff --git a/daemon/tests/harness/mod.rs b/daemon/tests/harness/mod.rs index 1c81cd6..0e1c896 100644 --- a/daemon/tests/harness/mod.rs +++ b/daemon/tests/harness/mod.rs @@ -77,7 +77,7 @@ impl Maker { let (wallet_addr, wallet_fut) = wallet.create(None).run(); tasks.add(wallet_fut); - let settlement_time_interval_hours = time::Duration::hours(24); + let settlement_interval = time::Duration::hours(24); let seed = Seed::default(); let (identity_pk, identity_sk) = seed.derive_identity(); @@ -100,7 +100,7 @@ impl Maker { HEARTBEAT_INTERVAL_FOR_TEST, ) }, - settlement_time_interval_hours, + settlement_interval, N_PAYOUTS_FOR_TEST, projection_actor.clone(), )