From 612f81008869eedc6593d2a0534a6d6c02ae0634 Mon Sep 17 00:00:00 2001 From: Mariusz Klochowicz Date: Mon, 29 Nov 2021 09:57:54 +1030 Subject: [PATCH] Move TxUrl assembly into a separate module Creating transactions' URLs is a functionality that doesn't need to be tightly-coupled with other modules. --- daemon/src/lib.rs | 1 + daemon/src/to_sse_event.rs | 118 ++----------------------------------- daemon/src/tx.rs | 113 +++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 114 deletions(-) create mode 100644 daemon/src/tx.rs diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index 22e6414..0813f7d 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -49,6 +49,7 @@ pub mod taker_cfd; pub mod to_sse_event; pub mod tokio_ext; pub mod try_continue; +pub mod tx; pub mod wallet; pub mod wallet_sync; pub mod wire; diff --git a/daemon/src/to_sse_event.rs b/daemon/src/to_sse_event.rs index b83846e..444a841 100644 --- a/daemon/src/to_sse_event.rs +++ b/daemon/src/to_sse_event.rs @@ -1,11 +1,10 @@ use crate::connection::ConnectionStatus; -use crate::model::cfd::{ - Dlc, OrderId, Payout, Role, SettlementKind, UpdateCfdProposal, UpdateCfdProposals, -}; +use crate::model::cfd::{OrderId, Role, SettlementKind, UpdateCfdProposal, UpdateCfdProposals}; use crate::model::{Leverage, Position, Timestamp, TradingPair}; use crate::projection::{CfdOrder, Identity, Price, Quote, Usd}; +use crate::tx::{self, TxUrl}; use crate::{bitmex_price_feed, model}; -use bdk::bitcoin::{Amount, Network, SignedAmount, Txid}; +use bdk::bitcoin::{Amount, Network, SignedAmount}; use rocket::request::FromParam; use rocket::response::stream::Event; use rust_decimal::Decimal; @@ -51,65 +50,6 @@ pub struct CfdDetails { payout: Option, } -#[derive(Debug, Clone, Serialize)] -pub struct TxUrl { - pub label: TxLabel, - pub url: String, -} - -impl TxUrl { - pub fn new(txid: Txid, network: Network, label: TxLabel) -> Self { - Self { - label, - url: match network { - Network::Bitcoin => format!("https://mempool.space/tx/{}", txid), - Network::Testnet => format!("https://mempool.space/testnet/tx/{}", txid), - Network::Signet => format!("https://mempool.space/signet/tx/{}", txid), - Network::Regtest => txid.to_string(), - }, - } - } -} - -struct TxUrlBuilder { - network: Network, -} - -impl TxUrlBuilder { - pub fn new(network: Network) -> Self { - Self { network } - } - - pub fn lock(&self, dlc: &Dlc) -> TxUrl { - TxUrl::new(dlc.lock.0.txid(), self.network, TxLabel::Lock) - } - - pub fn commit(&self, dlc: &Dlc) -> TxUrl { - TxUrl::new(dlc.commit.0.txid(), self.network, TxLabel::Commit) - } - - pub fn cet(&self, txid: Txid) -> TxUrl { - TxUrl::new(txid, self.network, TxLabel::Cet) - } - - pub fn collaborative_close(&self, txid: Txid) -> TxUrl { - TxUrl::new(txid, self.network, TxLabel::Collaborative) - } - - pub fn refund(&self, dlc: &Dlc) -> TxUrl { - TxUrl::new(dlc.refund.0.txid(), self.network, TxLabel::Refund) - } -} - -#[derive(Debug, Clone, Serialize)] -pub enum TxLabel { - Lock, - Commit, - Cet, - Refund, - Collaborative, -} - #[derive(Debug, derive_more::Display, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub enum CfdAction { @@ -218,7 +158,7 @@ impl ToSseEvent for CfdsWithAuxData { let state = to_cfd_state(&cfd.state, pending_proposal); let details = CfdDetails { - tx_url_list: to_tx_url_list(cfd.state.clone(), network), + tx_url_list: tx::to_tx_url_list(cfd.state.clone(), network), payout: cfd.payout(), }; @@ -342,56 +282,6 @@ fn to_cfd_state( } } -fn to_tx_url_list(state: model::cfd::CfdState, network: Network) -> Vec { - use model::cfd::CfdState::*; - - let tx_ub = TxUrlBuilder::new(network); - - match state { - PendingOpen { dlc, .. } => { - vec![tx_ub.lock(&dlc)] - } - PendingCommit { dlc, .. } => vec![tx_ub.lock(&dlc), tx_ub.commit(&dlc)], - OpenCommitted { dlc, .. } => vec![tx_ub.lock(&dlc), tx_ub.commit(&dlc)], - Open { - dlc, - collaborative_close, - .. - } => { - let mut tx_urls = vec![tx_ub.lock(&dlc)]; - if let Some(collaborative_close) = collaborative_close { - tx_urls.push(tx_ub.collaborative_close(collaborative_close.tx.txid())); - } - tx_urls - } - PendingCet { - dlc, attestation, .. - } => vec![ - tx_ub.lock(&dlc), - tx_ub.commit(&dlc), - tx_ub.cet(attestation.txid()), - ], - Closed { - payout: Payout::Cet(attestation), - .. - } => vec![tx_ub.cet(attestation.txid())], - Closed { - payout: Payout::CollaborativeClose(collaborative_close), - .. - } => { - vec![tx_ub.collaborative_close(collaborative_close.tx.txid())] - } - PendingRefund { dlc, .. } => vec![tx_ub.lock(&dlc), tx_ub.commit(&dlc), tx_ub.refund(&dlc)], - Refunded { dlc, .. } => vec![tx_ub.refund(&dlc)], - OutgoingOrderRequest { .. } - | IncomingOrderRequest { .. } - | Accepted { .. } - | Rejected { .. } - | ContractSetup { .. } - | SetupFailed { .. } => vec![], - } -} - impl ToSseEvent for Quote { fn to_sse_event(&self) -> Event { Event::json(self).event("quote") diff --git a/daemon/src/tx.rs b/daemon/src/tx.rs new file mode 100644 index 0000000..8d452b0 --- /dev/null +++ b/daemon/src/tx.rs @@ -0,0 +1,113 @@ +use bdk::bitcoin::{Network, Txid}; +use serde::Serialize; + +use crate::model::cfd; + +#[derive(Debug, Clone, Serialize)] +pub struct TxUrl { + pub label: TxLabel, + pub url: String, +} + +impl TxUrl { + pub fn new(txid: Txid, network: Network, label: TxLabel) -> Self { + Self { + label, + url: match network { + Network::Bitcoin => format!("https://mempool.space/tx/{}", txid), + Network::Testnet => format!("https://mempool.space/testnet/tx/{}", txid), + Network::Signet => format!("https://mempool.space/signet/tx/{}", txid), + Network::Regtest => txid.to_string(), + }, + } + } +} + +pub fn to_tx_url_list(state: cfd::CfdState, network: Network) -> Vec { + use cfd::CfdState::*; + + let tx_ub = TxUrlBuilder::new(network); + + match state { + PendingOpen { dlc, .. } => { + vec![tx_ub.lock(&dlc)] + } + PendingCommit { dlc, .. } => vec![tx_ub.lock(&dlc), tx_ub.commit(&dlc)], + OpenCommitted { dlc, .. } => vec![tx_ub.lock(&dlc), tx_ub.commit(&dlc)], + Open { + dlc, + collaborative_close, + .. + } => { + let mut tx_urls = vec![tx_ub.lock(&dlc)]; + if let Some(collaborative_close) = collaborative_close { + tx_urls.push(tx_ub.collaborative_close(collaborative_close.tx.txid())); + } + tx_urls + } + PendingCet { + dlc, attestation, .. + } => vec![ + tx_ub.lock(&dlc), + tx_ub.commit(&dlc), + tx_ub.cet(attestation.txid()), + ], + Closed { + payout: cfd::Payout::Cet(attestation), + .. + } => vec![tx_ub.cet(attestation.txid())], + Closed { + payout: cfd::Payout::CollaborativeClose(collaborative_close), + .. + } => { + vec![tx_ub.collaborative_close(collaborative_close.tx.txid())] + } + PendingRefund { dlc, .. } => vec![tx_ub.lock(&dlc), tx_ub.commit(&dlc), tx_ub.refund(&dlc)], + Refunded { dlc, .. } => vec![tx_ub.refund(&dlc)], + OutgoingOrderRequest { .. } + | IncomingOrderRequest { .. } + | Accepted { .. } + | Rejected { .. } + | ContractSetup { .. } + | SetupFailed { .. } => vec![], + } +} + +struct TxUrlBuilder { + network: Network, +} + +impl TxUrlBuilder { + pub fn new(network: Network) -> Self { + Self { network } + } + + pub fn lock(&self, dlc: &cfd::Dlc) -> TxUrl { + TxUrl::new(dlc.lock.0.txid(), self.network, TxLabel::Lock) + } + + pub fn commit(&self, dlc: &cfd::Dlc) -> TxUrl { + TxUrl::new(dlc.commit.0.txid(), self.network, TxLabel::Commit) + } + + pub fn cet(&self, txid: Txid) -> TxUrl { + TxUrl::new(txid, self.network, TxLabel::Cet) + } + + pub fn collaborative_close(&self, txid: Txid) -> TxUrl { + TxUrl::new(txid, self.network, TxLabel::Collaborative) + } + + pub fn refund(&self, dlc: &cfd::Dlc) -> TxUrl { + TxUrl::new(dlc.refund.0.txid(), self.network, TxLabel::Refund) + } +} + +#[derive(Debug, Clone, Serialize)] +pub enum TxLabel { + Lock, + Commit, + Cet, + Refund, + Collaborative, +}