Browse Source

Split `Cfd#handle` function into multiple

We always constructed the specific enum variant at the call site.
Might as well call a particular function which is simpler.
reconnect-to-maker
Thomas Eizinger 3 years ago
parent
commit
a1dd85f481
No known key found for this signature in database GPG Key ID: 651AC83A6C6C8B96
  1. 11
      daemon/src/cfd_actors.rs
  2. 13
      daemon/src/maker_cfd.rs
  3. 124
      daemon/src/model/cfd.rs
  4. 11
      daemon/src/taker_cfd.rs

11
daemon/src/cfd_actors.rs

@ -1,5 +1,5 @@
use crate::db::load_cfd_by_order_id;
use crate::model::cfd::{Attestation, Cfd, CfdState, CfdStateChangeEvent, OrderId};
use crate::model::cfd::{Attestation, Cfd, CfdState, OrderId};
use crate::{db, monitor, oracle, try_continue, wallet};
use anyhow::{bail, Context, Result};
use sqlx::pool::PoolConnection;
@ -50,7 +50,7 @@ where
.context("Failed to send transaction")?;
tracing::info!("CET published with txid {}", txid);
if cfd.handle(CfdStateChangeEvent::CetSent)?.is_none() {
if cfd.handle_cet_sent()?.is_none() {
bail!("If we can get the CET we should be able to transition")
}
@ -78,7 +78,7 @@ where
let mut cfd = db::load_cfd_by_order_id(order_id, conn).await?;
if cfd.handle(CfdStateChangeEvent::Monitor(event))?.is_none() {
if cfd.handle_monitoring_event(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(());
@ -122,7 +122,7 @@ where
.await?
.context("Failed to publish commit tx")?;
if cfd.handle(CfdStateChangeEvent::CommitTxSent)?.is_none() {
if cfd.handle_commit_tx_sent()?.is_none() {
bail!("If we can get the commit tx we should be able to transition")
}
@ -160,8 +160,7 @@ where
cfd.role(),
));
let new_state =
try_continue!(cfd.handle(CfdStateChangeEvent::OracleAttestation(attestation)));
let new_state = try_continue!(cfd.handle_oracle_attestation(attestation));
if new_state.is_none() {
// if we don't transition to a new state after oracle attestation we ignore the cfd

13
daemon/src/maker_cfd.rs

@ -1,9 +1,8 @@
use crate::cfd_actors::{self, append_cfd_state, insert_cfd_and_send_to_feed};
use crate::db::{insert_order, load_cfd_by_order_id, load_order_by_id};
use crate::model::cfd::{
Cfd, CfdState, CfdStateChangeEvent, CfdStateCommon, CollaborativeSettlement, Dlc, Order,
OrderId, Origin, Role, RollOverProposal, SettlementKind, SettlementProposal, UpdateCfdProposal,
UpdateCfdProposals,
Cfd, CfdState, CfdStateCommon, CollaborativeSettlement, Dlc, Order, OrderId, Origin, Role,
RollOverProposal, SettlementKind, SettlementProposal, UpdateCfdProposal, UpdateCfdProposals,
};
use crate::model::{Price, TakerId, Timestamp, Usd};
use crate::monitor::MonitorParams;
@ -875,9 +874,11 @@ where
let (tx, sig_maker) = dlc.close_transaction(proposal)?;
let own_script_pubkey = dlc.script_pubkey_for(cfd.role());
cfd.handle(CfdStateChangeEvent::ProposalSigned(
CollaborativeSettlement::new(tx.clone(), own_script_pubkey.clone(), proposal.price)?,
))?;
cfd.handle_proposal_signed(CollaborativeSettlement::new(
tx.clone(),
own_script_pubkey.clone(),
proposal.price,
)?)?;
append_cfd_state(&cfd, &mut conn, &self.cfd_feed_actor_inbox).await?;
let spend_tx = dlc.finalize_spend_transaction((tx, sig_maker), sig_taker)?;

124
daemon/src/model/cfd.rs

@ -698,18 +698,15 @@ impl Cfd {
pub const CET_TIMELOCK: u32 = 12;
pub fn handle(&mut self, event: CfdStateChangeEvent) -> Result<Option<CfdState>> {
pub fn handle_monitoring_event(&mut self, event: monitor::Event) -> Result<Option<CfdState>> {
use CfdState::*;
// TODO: Display impl
tracing::info!("Cfd state change event {:?}", event);
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 {}",
"Ignoring monitoring event {:?} because cfd already in state {}",
event,
self.state
);
@ -717,7 +714,6 @@ impl Cfd {
}
let new_state = match event {
CfdStateChangeEvent::Monitor(event) => match event {
monitor::Event::LockFinality(_) => {
if let PendingOpen { dlc, .. } = self.state.clone() {
CfdState::Open {
@ -785,11 +781,12 @@ impl Cfd {
}
}
monitor::Event::CloseFinality(_) => {
let collaborative_close = self.collaborative_close().context("No collaborative close after reaching collaborative close finality")?;
let collaborative_close = self.collaborative_close().context(
"No collaborative close after reaching collaborative close finality",
)?;
CfdState::closed(Payout::CollaborativeClose(collaborative_close))
},
}
monitor::Event::CetTimelockExpired(_) => match self.state.clone() {
CfdState::OpenCommitted {
dlc,
@ -871,16 +868,31 @@ impl Cfd {
monitor::Event::RevokedTransactionFound(_) => {
todo!("Punish bad counterparty")
}
},
CfdStateChangeEvent::CommitTxSent => {
};
self.state = new_state.clone();
Ok(Some(new_state))
}
pub fn handle_commit_tx_sent(&mut self) -> Result<Option<CfdState>> {
use CfdState::*;
// early exit if already final
if let SetupFailed { .. } | Closed { .. } | Refunded { .. } = self.state.clone() {
tracing::trace!(
"Ignoring sent commit transaction because cfd already in state {}",
self.state
);
return Ok(None);
}
let (dlc, attestation) = match self.state.clone() {
PendingOpen {
dlc, attestation, ..
} => (dlc, attestation),
Open {
dlc,
attestation,
..
dlc, attestation, ..
} => (dlc, attestation),
_ => {
bail!(
@ -890,15 +902,33 @@ impl Cfd {
}
};
PendingCommit {
self.state = PendingCommit {
common: CfdStateCommon {
transition_timestamp: Timestamp::now()?,
},
dlc,
attestation,
};
Ok(Some(self.state.clone()))
}
pub fn handle_oracle_attestation(
&mut self,
attestation: Attestation,
) -> Result<Option<CfdState>> {
use CfdState::*;
// early exit if already final
if let SetupFailed { .. } | Closed { .. } | Refunded { .. } = self.state.clone() {
tracing::trace!(
"Ignoring oracle attestation because cfd already in state {}",
self.state
);
return Ok(None);
}
CfdStateChangeEvent::OracleAttestation(attestation) => match self.state.clone() {
let new_state = match self.state.clone() {
CfdState::PendingOpen { dlc, .. } => CfdState::PendingOpen {
common: CfdStateCommon {
transition_timestamp: Timestamp::now()?,
@ -914,10 +944,7 @@ impl Cfd {
attestation: Some(attestation),
collaborative_close: None,
},
CfdState::PendingCommit {
dlc,
..
} => CfdState::PendingCommit {
CfdState::PendingCommit { dlc, .. } => CfdState::PendingCommit {
common: CfdStateCommon {
transition_timestamp: Timestamp::now()?,
},
@ -950,23 +977,57 @@ impl Cfd {
"Cannot transition to OpenCommitted because of unexpected state {}",
self.state
),
},
CfdStateChangeEvent::CetSent => {
};
self.state = new_state.clone();
Ok(Some(new_state))
}
pub fn handle_cet_sent(&mut self) -> Result<Option<CfdState>> {
use CfdState::*;
// early exit if already final
if let SetupFailed { .. } | Closed { .. } | Refunded { .. } = self.state.clone() {
tracing::trace!(
"Ignoring pending CET because cfd already in state {}",
self.state
);
return Ok(None);
}
let dlc = self.dlc().context("No DLC available after CET was sent")?;
let attestation = self
.attestation()
.context("No attestation available after CET was sent")?;
CfdState::PendingCet {
self.state = CfdState::PendingCet {
common: CfdStateCommon {
transition_timestamp: Timestamp::now()?,
},
dlc,
attestation,
};
Ok(Some(self.state.clone()))
}
},
CfdStateChangeEvent::ProposalSigned(collaborative_close) => match self.state.clone() {
pub fn handle_proposal_signed(
&mut self,
collaborative_close: CollaborativeSettlement,
) -> Result<Option<CfdState>> {
use CfdState::*;
// early exit if already final
if let SetupFailed { .. } | Closed { .. } | Refunded { .. } = self.state.clone() {
tracing::trace!(
"Ignoring collaborative settlement because cfd already in state {}",
self.state
);
return Ok(None);
}
let new_state = match self.state.clone() {
CfdState::Open {
common,
dlc,
@ -982,7 +1043,6 @@ impl Cfd {
"Cannot add proposed settlement details to state because of unexpected state {}",
self.state
),
},
};
self.state = new_state.clone();
@ -1282,18 +1342,6 @@ pub struct NotReadyYet {
cet_status: CetStatus,
}
#[derive(Debug, Clone)]
pub enum CfdStateChangeEvent {
// TODO: group other events by actors into enums and add them here so we can bundle all
// transitions into cfd.transition_to(...)
Monitor(monitor::Event),
CommitTxSent,
OracleAttestation(Attestation),
CetSent,
/// Settlement proposal was signed by the taker and sent to the maker
ProposalSigned(CollaborativeSettlement),
}
pub trait AsBlocks {
/// Calculates the duration in Bitcoin blocks.
///

11
daemon/src/taker_cfd.rs

@ -1,9 +1,8 @@
use crate::cfd_actors::{self, append_cfd_state, insert_cfd_and_send_to_feed};
use crate::db::{insert_order, load_cfd_by_order_id, load_order_by_id};
use crate::model::cfd::{
Cfd, CfdState, CfdStateChangeEvent, CfdStateCommon, CollaborativeSettlement, Dlc, Order,
OrderId, Origin, Role, RollOverProposal, SettlementKind, SettlementProposal, UpdateCfdProposal,
UpdateCfdProposals,
Cfd, CfdState, CfdStateCommon, CollaborativeSettlement, Dlc, Order, OrderId, Origin, Role,
RollOverProposal, SettlementKind, SettlementProposal, UpdateCfdProposal, UpdateCfdProposals,
};
use crate::model::{BitMexPriceEventId, Price, Timestamp, Usd};
use crate::monitor::{self, MonitorParams};
@ -660,13 +659,11 @@ where
sig_taker,
})?;
cfd.handle(CfdStateChangeEvent::ProposalSigned(
CollaborativeSettlement::new(
cfd.handle_proposal_signed(CollaborativeSettlement::new(
tx.clone(),
dlc.script_pubkey_for(cfd.role()),
proposal.price,
)?,
))?;
)?)?;
append_cfd_state(&cfd, &mut conn, &self.cfd_feed_actor_inbox).await?;
self.remove_pending_proposal(&order_id)?;

Loading…
Cancel
Save