|
|
@ -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 => { |
|
|
|
let (dlc, attestation ) = match self.state.clone() { |
|
|
|
}; |
|
|
|
|
|
|
|
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.
|
|
|
|
///
|
|
|
|