From e0e55bdd98451f53112709bed594ced3838e31d0 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Fri, 8 Oct 2021 16:44:36 +1100 Subject: [PATCH 01/11] Remove dbg --- daemon/src/oracle.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/src/oracle.rs b/daemon/src/oracle.rs index bf352a0..1e4b212 100644 --- a/daemon/src/oracle.rs +++ b/daemon/src/oracle.rs @@ -131,7 +131,7 @@ where } }; - let attestation = dbg!(res).json::().await?; + let attestation = res.json::().await?; self.cfd_actor_address .clone() From 23ba4a41cd4dfcfbfdd33355ff2ab0b708a547ab Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Fri, 8 Oct 2021 17:30:08 +1100 Subject: [PATCH 02/11] Change to trace because most of the time it's irrelevant --- daemon/src/db.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/daemon/src/db.rs b/daemon/src/db.rs index adc5678..b45d75f 100644 --- a/daemon/src/db.rs +++ b/daemon/src/db.rs @@ -172,10 +172,9 @@ pub async fn insert_new_cfd_state_by_order_id( .await .context("loading latest state failed")?; - // make sure that the new state is different than the current one to avoid that we save the same - // state twice if mem::discriminant(&latest_cfd_state_in_db) == mem::discriminant(&new_state) { - tracing::warn!( + // Since we have states where we add information this happens quite frequently + tracing::trace!( "Same state transition for cfd with order_id {}: {}", order_id, latest_cfd_state_in_db From ad7a024c022b75f60652e33123f258ad166a42fd Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 11 Oct 2021 09:41:30 +1100 Subject: [PATCH 03/11] Separate `Attestation` struct in model The `Attestation` in the `oracle` module has `Desiarialization` rules that conflict with loading it from the db. We should not reuse domain structs between modules anyway, so this was cleaned up by introducing a dedicated `model::Attestation` and mapping to `oracle::Attestation`. --- daemon/src/maker_cfd.rs | 4 +++- daemon/src/model/cfd.rs | 30 ++++++++++++++++++++++++++++-- daemon/src/monitor.rs | 4 ++-- daemon/src/oracle.rs | 4 ++-- daemon/src/taker_cfd.rs | 4 +++- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/daemon/src/maker_cfd.rs b/daemon/src/maker_cfd.rs index 4f1405c..64a1277 100644 --- a/daemon/src/maker_cfd.rs +++ b/daemon/src/maker_cfd.rs @@ -816,7 +816,9 @@ impl Actor { let cfds = load_cfds_by_oracle_event_id(attestation.id.clone(), &mut conn).await?; for mut cfd in cfds { - cfd.handle(CfdStateChangeEvent::OracleAttestation(attestation.clone()))?; + cfd.handle(CfdStateChangeEvent::OracleAttestation( + attestation.clone().into(), + ))?; insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn).await?; self.try_cet_publication(cfd).await?; diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index 49d4984..7ab3a9b 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -1,6 +1,5 @@ use crate::model::{Leverage, OracleEventId, Percent, Position, TakerId, TradingPair, Usd}; -use crate::monitor; -use crate::oracle::Attestation; +use crate::{monitor, oracle}; use anyhow::{bail, Context, Result}; use bdk::bitcoin::secp256k1::{SecretKey, Signature}; use bdk::bitcoin::{Address, Amount, PublicKey, Script, SignedAmount, Transaction, Txid}; @@ -282,6 +281,33 @@ pub enum CfdState { }, } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct Attestation { + pub id: OracleEventId, + pub price: u64, + pub scalars: Vec, +} + +impl From for Attestation { + fn from(attestation: oracle::Attestation) -> Self { + Attestation { + id: attestation.id, + price: attestation.price, + scalars: attestation.scalars, + } + } +} + +impl From for oracle::Attestation { + fn from(attestation: Attestation) -> oracle::Attestation { + oracle::Attestation { + id: attestation.id, + price: attestation.price, + scalars: attestation.scalars, + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(tag = "type", content = "payload")] pub enum CetStatus { diff --git a/daemon/src/monitor.rs b/daemon/src/monitor.rs index c847b99..447f463 100644 --- a/daemon/src/monitor.rs +++ b/daemon/src/monitor.rs @@ -111,7 +111,7 @@ where actor.monitor_refund_finality(¶ms,cfd.order.id); } CetStatus::OracleSigned(attestation) => { - actor.monitor_cet_finality(map_cets(dlc.cets, dlc.maker_address.script_pubkey()), attestation, cfd.order.id)?; + actor.monitor_cet_finality(map_cets(dlc.cets, dlc.maker_address.script_pubkey()), attestation.into(), cfd.order.id)?; actor.monitor_commit_cet_timelock(¶ms, cfd.order.id); actor.monitor_commit_refund_timelock(¶ms, cfd.order.id); actor.monitor_refund_finality(¶ms,cfd.order.id); @@ -121,7 +121,7 @@ where actor.monitor_refund_finality(¶ms,cfd.order.id); } CetStatus::Ready(attestation) => { - actor.monitor_cet_finality(map_cets(dlc.cets, dlc.maker_address.script_pubkey()), attestation, cfd.order.id)?; + actor.monitor_cet_finality(map_cets(dlc.cets, dlc.maker_address.script_pubkey()), attestation.into(), cfd.order.id)?; actor.monitor_commit_refund_timelock(¶ms, cfd.order.id); actor.monitor_refund_finality(¶ms,cfd.order.id); } diff --git a/daemon/src/oracle.rs b/daemon/src/oracle.rs index 1e4b212..7d7df97 100644 --- a/daemon/src/oracle.rs +++ b/daemon/src/oracle.rs @@ -10,7 +10,7 @@ use reqwest::StatusCode; use rocket::time::format_description::FormatItem; use rocket::time::macros::format_description; use rocket::time::{Duration, OffsetDateTime, Time}; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; use std::collections::{HashMap, HashSet}; const OLIVIA_EVENT_TIME_FORMAT: &[FormatItem] = @@ -277,7 +277,7 @@ impl From for cfd_protocol::Announcement { // TODO: Implement real deserialization once price attestation is // implemented in `olivia` -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Deserialize, PartialEq)] #[serde(try_from = "olivia_api::Response")] pub struct Attestation { pub id: OracleEventId, diff --git a/daemon/src/taker_cfd.rs b/daemon/src/taker_cfd.rs index 9ffe227..cede6f1 100644 --- a/daemon/src/taker_cfd.rs +++ b/daemon/src/taker_cfd.rs @@ -597,7 +597,9 @@ impl Actor { let cfds = load_cfds_by_oracle_event_id(attestation.id.clone(), &mut conn).await?; for mut cfd in cfds { - cfd.handle(CfdStateChangeEvent::OracleAttestation(attestation.clone()))?; + cfd.handle(CfdStateChangeEvent::OracleAttestation( + attestation.clone().into(), + ))?; insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn).await?; self.try_cet_publication(cfd).await?; From d86fd3493bec37bcf4e1048bb60d0428915c9bcb Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 11 Oct 2021 09:47:25 +1100 Subject: [PATCH 04/11] Display `CetStatus` as part of `NotReady` error --- daemon/src/maker_cfd.rs | 5 +---- daemon/src/model/cfd.rs | 30 +++++++++++++++++++++++------- daemon/src/taker_cfd.rs | 5 +---- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/daemon/src/maker_cfd.rs b/daemon/src/maker_cfd.rs index 64a1277..4738f4f 100644 --- a/daemon/src/maker_cfd.rs +++ b/daemon/src/maker_cfd.rs @@ -840,10 +840,7 @@ impl Actor { insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state, &mut conn).await?; } Err(not_ready_yet) => { - tracing::debug!( - "Attestation received but we are not ready to publish it yet: {:#}", - not_ready_yet - ); + tracing::debug!("{:#}", not_ready_yet); return Ok(()); } }; diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index 7ab3a9b..15772c3 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -317,6 +317,17 @@ pub enum CetStatus { Ready(Attestation), } +impl fmt::Display for CetStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + CetStatus::Unprepared => write!(f, "Unprepared"), + CetStatus::TimelockExpired => write!(f, "TimelockExpired"), + CetStatus::OracleSigned(_) => write!(f, "OracleSigned"), + CetStatus::Ready(_) => write!(f, "Ready"), + } + } +} + impl CfdState { fn get_common(&self) -> CfdStateCommon { let common = match self { @@ -849,10 +860,13 @@ impl Cfd { cet_status: CetStatus::Ready(attestation), .. } => (dlc, attestation), - CfdState::OpenCommitted { .. } - | CfdState::Open { .. } - | CfdState::PendingCommit { .. } => { - return Ok(Err(NotReadyYet)); + CfdState::OpenCommitted { cet_status, .. } => { + return Ok(Err(NotReadyYet { cet_status })); + } + CfdState::Open { .. } | CfdState::PendingCommit { .. } => { + return Ok(Err(NotReadyYet { + cet_status: CetStatus::Unprepared, + })); } _ => bail!("Cannot publish CET in state {}", self.state.clone()), }; @@ -946,9 +960,11 @@ impl Cfd { } } -#[derive(thiserror::Error, Debug, Clone, Copy)] -#[error("The cfd is not ready for CET publication yet")] -pub struct NotReadyYet; +#[derive(thiserror::Error, Debug, Clone)] +#[error("The cfd is not ready for CET publication yet: {cet_status}")] +pub struct NotReadyYet { + cet_status: CetStatus, +} #[derive(Debug, Clone)] pub enum CfdStateChangeEvent { diff --git a/daemon/src/taker_cfd.rs b/daemon/src/taker_cfd.rs index cede6f1..ecc0f9c 100644 --- a/daemon/src/taker_cfd.rs +++ b/daemon/src/taker_cfd.rs @@ -621,10 +621,7 @@ impl Actor { insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state, &mut conn).await?; } Err(not_ready_yet) => { - tracing::debug!( - "Attestation received but we are not ready to publish it yet: {:#}", - not_ready_yet - ); + tracing::debug!("{:#}", not_ready_yet); return Ok(()); } }; From d55a8f0403ac9847efee2728922e681464304547 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 11 Oct 2021 09:58:10 +1100 Subject: [PATCH 05/11] Pass on attestation upon `CommitFinality` We have to properly pass on the attestation when transitioning from `PendingOpen`, `Open` or `PendingCommit` to `OpenCommitted`. --- daemon/src/model/cfd.rs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index 15772c3..4a9d20f 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -581,11 +581,20 @@ impl Cfd { } } monitor::Event::CommitFinality(_) => { - let dlc = if let PendingCommit { dlc, .. } = self.state.clone() { - dlc - } else if let PendingOpen { dlc, .. } | Open { dlc, .. } = self.state.clone() { + let (dlc, attestation) = if let PendingCommit { + dlc, attestation, .. + } = self.state.clone() + { + (dlc, attestation) + } else if let PendingOpen { + dlc, attestation, .. + } + | Open { + dlc, attestation, .. + } = self.state.clone() + { tracing::debug!(%order_id, "Was in unexpected state {}, jumping ahead to OpenCommitted", self.state); - dlc + (dlc, attestation) } else { bail!( "Cannot transition to OpenCommitted because of unexpected state {}", @@ -598,7 +607,11 @@ impl Cfd { transition_timestamp: SystemTime::now(), }, dlc, - cet_status: CetStatus::Unprepared, + cet_status: if let Some(attestation) = attestation { + CetStatus::OracleSigned(attestation) + } else { + CetStatus::Unprepared + }, } } monitor::Event::CetTimelockExpired(_) => match self.state.clone() { From 6fce3a686e3da49cc8c84383fc6ca5f4fad4b379 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 11 Oct 2021 09:59:38 +1100 Subject: [PATCH 06/11] Fix typo --- daemon/src/model/cfd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index 4a9d20f..d79ddb7 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -671,7 +671,7 @@ impl Cfd { dlc } else { bail!( - "Cannot transition to OpenCommitted because of unexpected state {}", + "Cannot transition to MustRefund because of unexpected state {}", self.state ) }; From 94b3a35abdcd25a139386f029f171afe9b00429f Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 11 Oct 2021 10:01:28 +1100 Subject: [PATCH 07/11] Add attestation to `PendingOpen` in case we receive attestation in that state --- daemon/src/model/cfd.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index d79ddb7..1f46b33 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -732,7 +732,7 @@ impl Cfd { } } CfdStateChangeEvent::OracleAttestation(attestation) => match self.state.clone() { - CfdState::Open { dlc, .. } => CfdState::Open { + CfdState::PendingOpen { dlc, .. } | CfdState::Open { dlc, .. } => CfdState::Open { common: CfdStateCommon { transition_timestamp: SystemTime::now(), }, From 9666b63cb7ef01d0331f69d63b536653e8a0c324 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 11 Oct 2021 10:07:56 +1100 Subject: [PATCH 08/11] Optional state transition and early exit Reasoning: The state transition can fail, hence the result. It can, however, happen that there is no failure, but we still did not transition to a new state. In such cases we don't want to save the state in the database because it would be an unwanted duplicated entry. --- daemon/src/maker_cfd.rs | 44 +++++++++++++++++++++++++++----------- daemon/src/model/cfd.rs | 14 ++++++++++-- daemon/src/taker_cfd.rs | 47 +++++++++++++++++++++++++++++------------ 3 files changed, 77 insertions(+), 28 deletions(-) diff --git a/daemon/src/maker_cfd.rs b/daemon/src/maker_cfd.rs index 4738f4f..2558c33 100644 --- a/daemon/src/maker_cfd.rs +++ b/daemon/src/maker_cfd.rs @@ -12,7 +12,7 @@ use crate::model::{TakerId, Usd}; use crate::monitor::MonitorParams; use crate::wallet::Wallet; use crate::{maker_inc_connections, monitor, oracle, setup_contract, wire}; -use anyhow::{Context as _, Result}; +use anyhow::{bail, Context as _, Result}; use async_trait::async_trait; use bdk::bitcoin::secp256k1::schnorrsig; use futures::channel::mpsc; @@ -617,8 +617,9 @@ impl Actor { tracing::info!("Commit transaction published on chain: {}", txid); - let new_state = cfd.handle(CfdStateChangeEvent::CommitTxSent)?; - insert_new_cfd_state_by_order_id(cfd.order.id, new_state, &mut conn).await?; + if let Some(new_state) = cfd.handle(CfdStateChangeEvent::CommitTxSent)? { + insert_new_cfd_state_by_order_id(cfd.order.id, new_state, &mut conn).await?; + } self.cfd_feed_actor_inbox .send(load_all_cfds(&mut conn).await?)?; @@ -785,15 +786,21 @@ impl Actor { let mut conn = self.db.acquire().await?; let mut cfd = load_cfd_by_order_id(order_id, &mut conn).await?; - let new_state = cfd.handle(CfdStateChangeEvent::Monitor(event))?; - insert_new_cfd_state_by_order_id(order_id, new_state.clone(), &mut conn).await?; + if cfd.handle(CfdStateChangeEvent::Monitor(event))?.is_none() { + // early exit if there was not state change + // this is for cases where we are already in a final state + return Ok(()); + } + + insert_new_cfd_state_by_order_id(order_id, cfd.state.clone(), &mut conn).await?; + self.cfd_feed_actor_inbox .send(load_all_cfds(&mut conn).await?)?; // TODO: code duplication maker/taker - if let CfdState::OpenCommitted { .. } = new_state { + if let CfdState::OpenCommitted { .. } = cfd.state { self.try_cet_publication(cfd).await?; - } else if let CfdState::MustRefund { .. } = new_state { + } else if let CfdState::MustRefund { .. } = cfd.state { let signed_refund_tx = cfd.refund_tx()?; let txid = self .wallet @@ -816,9 +823,18 @@ impl Actor { let cfds = load_cfds_by_oracle_event_id(attestation.id.clone(), &mut conn).await?; for mut cfd in cfds { - cfd.handle(CfdStateChangeEvent::OracleAttestation( - attestation.clone().into(), - ))?; + if cfd + .handle(CfdStateChangeEvent::OracleAttestation( + attestation.clone().into(), + ))? + .is_none() + { + // if we don't transition to a new state after oracle attestation we ignore the cfd + // this is for cases where we cannot handle the attestation which should be in a + // final state + continue; + } + insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn).await?; self.try_cet_publication(cfd).await?; @@ -836,8 +852,12 @@ impl Actor { let txid = self.wallet.try_broadcast_transaction(cet).await?; tracing::info!("CET published with txid {}", txid); - cfd.handle(CfdStateChangeEvent::CetSent)?; - insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state, &mut conn).await?; + if cfd.handle(CfdStateChangeEvent::CetSent)?.is_none() { + bail!("If we can get the CET we should be able to transition") + } + + insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn) + .await?; } Err(not_ready_yet) => { tracing::debug!("{:#}", not_ready_yet); diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index 1f46b33..b20eded 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -543,7 +543,7 @@ impl Cfd { #[allow(dead_code)] pub const CET_TIMELOCK: u32 = 12; - pub fn handle(&mut self, event: CfdStateChangeEvent) -> Result { + pub fn handle(&mut self, event: CfdStateChangeEvent) -> Result> { use CfdState::*; // TODO: Display impl @@ -551,6 +551,16 @@ impl Cfd { let order_id = self.order.id; + // early exit if already final + if let SetupFailed { .. } | Closed { .. } | Refunded { .. } = self.state.clone() { + tracing::trace!( + "Ignoring event {:?} because cfd already in state {}", + event, + self.state + ); + return Ok(None); + } + let new_state = match event { CfdStateChangeEvent::Monitor(event) => match event { monitor::Event::LockFinality(_) => { @@ -792,7 +802,7 @@ impl Cfd { self.state = new_state.clone(); - Ok(new_state) + Ok(Some(new_state)) } pub fn refund_tx(&self) -> Result { diff --git a/daemon/src/taker_cfd.rs b/daemon/src/taker_cfd.rs index ecc0f9c..cb252ee 100644 --- a/daemon/src/taker_cfd.rs +++ b/daemon/src/taker_cfd.rs @@ -12,7 +12,7 @@ use crate::monitor::{self, MonitorParams}; use crate::wallet::Wallet; use crate::wire::{MakerToTaker, RollOverMsg, SetupMsg}; use crate::{oracle, send_to_socket, setup_contract, wire}; -use anyhow::{Context as _, Result}; +use anyhow::{bail, Context as _, Result}; use async_trait::async_trait; use bdk::bitcoin::secp256k1::schnorrsig; use futures::channel::mpsc; @@ -541,17 +541,21 @@ impl Actor { let mut conn = self.db.acquire().await?; let mut cfd = load_cfd_by_order_id(order_id, &mut conn).await?; - let new_state = cfd.handle(CfdStateChangeEvent::Monitor(event))?; + if cfd.handle(CfdStateChangeEvent::Monitor(event))?.is_none() { + // early exit if there was not state change + // this is for cases where we are already in a final state + return Ok(()); + } - insert_new_cfd_state_by_order_id(order_id, new_state.clone(), &mut conn).await?; + insert_new_cfd_state_by_order_id(order_id, cfd.state.clone(), &mut conn).await?; self.cfd_feed_actor_inbox .send(load_all_cfds(&mut conn).await?)?; // TODO: code duplicateion maker/taker - if let CfdState::OpenCommitted { .. } = new_state { + if let CfdState::OpenCommitted { .. } = cfd.state { self.try_cet_publication(cfd).await?; - } else if let CfdState::MustRefund { .. } = new_state { + } else if let CfdState::MustRefund { .. } = cfd.state { let signed_refund_tx = cfd.refund_tx()?; let txid = self .wallet @@ -576,14 +580,16 @@ impl Actor { .try_broadcast_transaction(signed_commit_tx) .await?; - tracing::info!("Commit transaction published on chain: {}", txid); - - let new_state = cfd.handle(CfdStateChangeEvent::CommitTxSent)?; - insert_new_cfd_state_by_order_id(cfd.order.id, new_state, &mut conn).await?; + if cfd.handle(CfdStateChangeEvent::CommitTxSent)?.is_none() { + bail!("If we can get the commit tx we should be able to transition") + } + insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn).await?; self.cfd_feed_actor_inbox .send(load_all_cfds(&mut conn).await?)?; + tracing::info!("Commit transaction published on chain: {}", txid); + Ok(()) } @@ -597,9 +603,18 @@ impl Actor { let cfds = load_cfds_by_oracle_event_id(attestation.id.clone(), &mut conn).await?; for mut cfd in cfds { - cfd.handle(CfdStateChangeEvent::OracleAttestation( - attestation.clone().into(), - ))?; + if cfd + .handle(CfdStateChangeEvent::OracleAttestation( + attestation.clone().into(), + ))? + .is_none() + { + // if we don't transition to a new state after oracle attestation we ignore the cfd + // this is for cases where we cannot handle the attestation which should be in a + // final state + continue; + } + insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn).await?; self.try_cet_publication(cfd).await?; @@ -617,8 +632,12 @@ impl Actor { let txid = self.wallet.try_broadcast_transaction(cet).await?; tracing::info!("CET published with txid {}", txid); - cfd.handle(CfdStateChangeEvent::CetSent)?; - insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state, &mut conn).await?; + if cfd.handle(CfdStateChangeEvent::CetSent)?.is_none() { + bail!("If we can get the CET we should be able to transition") + } + + insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn) + .await?; } Err(not_ready_yet) => { tracing::debug!("{:#}", not_ready_yet); From cea476c6062d6bdd23b9133583d09ef1a6e241b7 Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 11 Oct 2021 10:12:59 +1100 Subject: [PATCH 09/11] More resilient loop error handling We are looping over multiple CFDs when trying to publish the CET. If we fail inside the loop then the next CFD(s) are not processed and CETs might not get published properly. This should make the code more resilient. --- daemon/src/maker_cfd.rs | 5 ++++- daemon/src/taker_cfd.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/daemon/src/maker_cfd.rs b/daemon/src/maker_cfd.rs index 2558c33..f4a138e 100644 --- a/daemon/src/maker_cfd.rs +++ b/daemon/src/maker_cfd.rs @@ -837,7 +837,10 @@ impl Actor { insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn).await?; - self.try_cet_publication(cfd).await?; + if let Err(e) = self.try_cet_publication(cfd).await { + tracing::error!("Error when trying to publish CET: {:#}", e); + continue; + } } Ok(()) diff --git a/daemon/src/taker_cfd.rs b/daemon/src/taker_cfd.rs index cb252ee..783ecaa 100644 --- a/daemon/src/taker_cfd.rs +++ b/daemon/src/taker_cfd.rs @@ -617,7 +617,10 @@ impl Actor { insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn).await?; - self.try_cet_publication(cfd).await?; + if let Err(e) = self.try_cet_publication(cfd).await { + tracing::error!("Error when trying to publish CET: {:#}", e); + continue; + } } Ok(()) From d6aed063fc2d047dcd01cab3952b0222232fc63d Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 11 Oct 2021 10:13:51 +1100 Subject: [PATCH 10/11] Missing CFD feed updates --- daemon/src/maker_cfd.rs | 5 +++++ daemon/src/taker_cfd.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/daemon/src/maker_cfd.rs b/daemon/src/maker_cfd.rs index f4a138e..b91e0a6 100644 --- a/daemon/src/maker_cfd.rs +++ b/daemon/src/maker_cfd.rs @@ -836,6 +836,8 @@ impl Actor { } insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn).await?; + self.cfd_feed_actor_inbox + .send(load_all_cfds(&mut conn).await?)?; if let Err(e) = self.try_cet_publication(cfd).await { tracing::error!("Error when trying to publish CET: {:#}", e); @@ -861,6 +863,9 @@ impl Actor { insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn) .await?; + + self.cfd_feed_actor_inbox + .send(load_all_cfds(&mut conn).await?)?; } Err(not_ready_yet) => { tracing::debug!("{:#}", not_ready_yet); diff --git a/daemon/src/taker_cfd.rs b/daemon/src/taker_cfd.rs index 783ecaa..5a7dd7a 100644 --- a/daemon/src/taker_cfd.rs +++ b/daemon/src/taker_cfd.rs @@ -616,6 +616,8 @@ impl Actor { } insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn).await?; + self.cfd_feed_actor_inbox + .send(load_all_cfds(&mut conn).await?)?; if let Err(e) = self.try_cet_publication(cfd).await { tracing::error!("Error when trying to publish CET: {:#}", e); @@ -641,6 +643,9 @@ impl Actor { insert_new_cfd_state_by_order_id(cfd.order.id, cfd.state.clone(), &mut conn) .await?; + + self.cfd_feed_actor_inbox + .send(load_all_cfds(&mut conn).await?)?; } Err(not_ready_yet) => { tracing::debug!("{:#}", not_ready_yet); From b470a9d4fca5a17f8d9993b499f61c755b6e275c Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 11 Oct 2021 10:16:17 +1100 Subject: [PATCH 11/11] Save Bitcoin amount `as_sat` in db The DLC does not concern the UI, hence the amounts should be handles in satoshi. Note: This commit enforces db reset of CFDs that are stored in `as_btc`. --- daemon/src/model/cfd.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index b20eded..30953f5 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -1367,9 +1367,9 @@ pub struct Dlc { pub cets: HashMap>, pub refund: (Transaction, Signature), - #[serde(with = "::bdk::bitcoin::util::amount::serde::as_btc")] + #[serde(with = "::bdk::bitcoin::util::amount::serde::as_sat")] pub maker_lock_amount: Amount, - #[serde(with = "::bdk::bitcoin::util::amount::serde::as_btc")] + #[serde(with = "::bdk::bitcoin::util::amount::serde::as_sat")] pub taker_lock_amount: Amount, pub revoked_commit: Vec,