Browse Source

Merge #316

316: Provide more feedback to the user during collaborative settlement r=klochowicz a=klochowicz

Fixes #309

Co-authored-by: Mariusz Klochowicz <mariusz@klochowicz.com>
refactor/no-log-handler
bors[bot] 3 years ago
committed by GitHub
parent
commit
cb38e617b3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      daemon/src/maker_cfd.rs
  2. 48
      daemon/src/model/cfd.rs
  3. 6
      daemon/src/monitor.rs
  4. 1
      daemon/src/oracle.rs
  5. 41
      daemon/src/to_sse_event.rs
  6. 5
      frontend/src/components/Types.tsx

8
daemon/src/maker_cfd.rs

@ -307,6 +307,8 @@ impl Actor {
TimestampedTransaction::new(tx.clone(), dlc.script_pubkey_for(cfd.role())),
))?;
insert_new_cfd_state_by_order_id(cfd.order.id, &cfd.state, &mut conn).await?;
self.cfd_feed_actor_inbox
.send(load_all_cfds(&mut conn).await?)?;
let spend_tx = dlc.finalize_spend_transaction((tx, sig_maker), sig_taker)?;
@ -317,12 +319,6 @@ impl Actor {
.context("Broadcasting spend transaction")?;
tracing::info!("Close transaction published with txid {}", txid);
cfd.handle(CfdStateChangeEvent::CloseSent(TimestampedTransaction::new(
spend_tx,
dlc.script_pubkey_for(cfd.role()),
)))?;
insert_new_cfd_state_by_order_id(cfd.order.id, &cfd.state, &mut conn).await?;
self.current_agreed_proposals
.remove(&order_id)
.context("remove accepted proposal after signing")?;

48
daemon/src/model/cfd.rs

@ -253,17 +253,6 @@ pub enum CfdState {
attestation: Attestation,
},
/// The collaborative close transaction was published but is not final yet.
///
/// This state applies to taker and maker.
/// This state is needed, because otherwise the user does not get any feedback.
PendingClose {
common: CfdStateCommon,
dlc: Dlc,
attestation: Option<Attestation>,
collaborative_close: TimestampedTransaction,
},
/// The position was closed collaboratively or non-collaboratively
///
/// This state applies to taker and maker.
@ -408,7 +397,6 @@ impl CfdState {
CfdState::SetupFailed { common, .. } => common,
CfdState::PendingCommit { common, .. } => common,
CfdState::PendingCet { common, .. } => common,
CfdState::PendingClose { common, .. } => common,
CfdState::Closed { common, .. } => common,
};
@ -425,10 +413,6 @@ impl CfdState {
collaborative_close,
..
} => collaborative_close.clone(),
CfdState::PendingClose {
collaborative_close,
..
} => Some(collaborative_close.clone()),
_ => None,
}
}
@ -476,9 +460,6 @@ impl fmt::Display for CfdState {
CfdState::PendingCet { .. } => {
write!(f, "Pending CET")
}
CfdState::PendingClose { .. } => {
write!(f, "Pending Close")
}
CfdState::Closed { .. } => {
write!(f, "Closed")
}
@ -584,7 +565,6 @@ impl Cfd {
Ok((p_n_l, p_n_l_percent))
}
#[allow(dead_code)] // Not used by all binaries.
pub fn calculate_settlement(&self, current_price: Usd) -> Result<SettlementProposal> {
let payout_curve =
payout_curve::calculate(self.order.price, self.quantity_usd, self.order.leverage)?;
@ -946,26 +926,6 @@ impl Cfd {
self.state
),
},
CfdStateChangeEvent::CloseSent(collaborative_close) => match self.state.clone() {
CfdState::Open {
common,
dlc,
attestation,
collaborative_close : Some(_),
} => CfdState::PendingClose {
common,
dlc,
attestation,
collaborative_close,
},
CfdState::Open {
collaborative_close : None,
..
} => bail!("Cannot transition to PendingClose because Open state did not record a settlement proposal beforehand"),
_ => bail!(
"Cannot transition to PendingClose because of unexpected state {}",
self.state)
}
};
self.state = new_state.clone();
@ -1161,7 +1121,6 @@ impl Cfd {
| CfdState::Accepted { .. }
| CfdState::Rejected { .. }
| CfdState::ContractSetup { .. }
| CfdState::PendingClose { .. }
| CfdState::Closed { .. }
| CfdState::MustRefund { .. }
| CfdState::Refunded { .. }
@ -1201,7 +1160,6 @@ impl Cfd {
| CfdState::PendingOpen { .. }
| CfdState::Open { .. }
| CfdState::PendingCommit { .. }
| CfdState::PendingClose { .. }
| CfdState::Closed { .. }
| CfdState::OpenCommitted { .. }
| CfdState::MustRefund { .. }
@ -1216,10 +1174,6 @@ impl Cfd {
collaborative_close: Some(collaborative_close),
..
}
| CfdState::PendingClose {
collaborative_close,
..
}
| CfdState::Closed {
payout: Payout::CollaborativeClose(collaborative_close),
..
@ -1282,8 +1236,6 @@ pub enum CfdStateChangeEvent {
CetSent,
/// Settlement proposal was signed by the taker and sent to the maker
ProposalSigned(TimestampedTransaction),
/// Maker signed and finalized the close transaction with both signatures
CloseSent(TimestampedTransaction),
}
/// Returns the Profit/Loss (P/L) as Bitcoin. Losses are capped by the provided margin

6
daemon/src/monitor.rs

@ -126,12 +126,6 @@ impl Actor<bdk::electrum_client::Client> {
actor.monitor_commit_refund_timelock(&params, cfd.order.id);
actor.monitor_refund_finality(&params,cfd.order.id);
}
CfdState::PendingClose { collaborative_close, .. } => {
let transaction = collaborative_close.tx;
let close_params = (transaction.txid(),
transaction.output.first().expect("have output").script_pubkey.clone());
actor.monitor_close_finality(close_params,cfd.order.id);
}
CfdState::MustRefund { dlc, .. } => {
let params = MonitorParams::from_dlc_and_timelocks(dlc.clone(), cfd.refund_timelock_in_blocks());
actor.cfds.insert(cfd.order.id, params.clone());

1
daemon/src/oracle.rs

@ -88,7 +88,6 @@ impl Actor {
| CfdState::Accepted { .. }
| CfdState::Rejected { .. }
| CfdState::ContractSetup { .. }
| CfdState::PendingClose { .. }
// Final states
| CfdState::Closed { .. }

41
daemon/src/to_sse_event.rs

@ -326,7 +326,21 @@ fn to_cfd_state(
direction: SettlementKind::Incoming,
..
}) => CfdState::IncomingSettlementProposal,
Some(UpdateCfdProposal::RollOverProposal {
direction: SettlementKind::Outgoing,
..
}) => CfdState::OutgoingRollOverProposal,
Some(UpdateCfdProposal::RollOverProposal {
direction: SettlementKind::Incoming,
..
}) => CfdState::IncomingRollOverProposal,
None => match cfd_state {
// Filled in collaborative close in Open means that we're awaiting
// a collaborative closure
model::cfd::CfdState::Open {
collaborative_close: Some(_),
..
} => CfdState::PendingClose,
model::cfd::CfdState::OutgoingOrderRequest { .. } => CfdState::OutgoingOrderRequest,
model::cfd::CfdState::IncomingOrderRequest { .. } => CfdState::IncomingOrderRequest,
model::cfd::CfdState::Accepted { .. } => CfdState::Accepted,
@ -340,17 +354,8 @@ fn to_cfd_state(
model::cfd::CfdState::SetupFailed { .. } => CfdState::SetupFailed,
model::cfd::CfdState::PendingCommit { .. } => CfdState::PendingCommit,
model::cfd::CfdState::PendingCet { .. } => CfdState::PendingCet,
model::cfd::CfdState::PendingClose { .. } => CfdState::PendingClose,
model::cfd::CfdState::Closed { .. } => CfdState::Closed,
},
Some(UpdateCfdProposal::RollOverProposal {
direction: SettlementKind::Outgoing,
..
}) => CfdState::OutgoingRollOverProposal,
Some(UpdateCfdProposal::RollOverProposal {
direction: SettlementKind::Incoming,
..
}) => CfdState::IncomingRollOverProposal,
}
}
@ -360,11 +365,22 @@ fn to_tx_url_list(state: model::cfd::CfdState, network: Network) -> Vec<TxUrl> {
let tx_ub = TxUrlBuilder::new(network);
match state {
PendingOpen { dlc, .. } | Open { dlc, .. } => {
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![
@ -386,7 +402,6 @@ fn to_tx_url_list(state: model::cfd::CfdState, network: Network) -> Vec<TxUrl> {
Refunded { dlc, .. } => vec![tx_ub.refund(&dlc)],
OutgoingOrderRequest { .. }
| IncomingOrderRequest { .. }
| PendingClose { .. }
| Accepted { .. }
| Rejected { .. }
| ContractSetup { .. }
@ -435,6 +450,10 @@ fn available_actions(state: CfdState, role: Role) -> Vec<CfdAction> {
(CfdState::OutgoingSettlementProposal { .. }, Role::Maker) => {
vec![CfdAction::Commit]
}
// User is awaiting collaborative close, commit is left as a safeguard
(CfdState::PendingClose { .. }, _) => {
vec![CfdAction::Commit]
}
(CfdState::Open { .. }, Role::Taker) => {
vec![CfdAction::RollOver, CfdAction::Commit, CfdAction::Settle]
}

5
frontend/src/components/Types.tsx

@ -82,6 +82,8 @@ export class State {
return "Open";
case StateKey.PENDING_COMMIT:
return "Pending Commit";
case StateKey.PENDING_CLOSE:
return "Pending Close";
case StateKey.OPEN_COMMITTED:
return "Open (commit-tx published)";
case StateKey.INCOMING_SETTLEMENT_PROPOSAL:
@ -123,6 +125,7 @@ export class State {
case StateKey.OPEN_COMMITTED:
case StateKey.MUST_REFUND:
case StateKey.PENDING_CET:
case StateKey.PENDING_CLOSE:
return orange;
case StateKey.OUTGOING_ORDER_REQUEST:
@ -158,6 +161,7 @@ export class State {
case StateKey.OUTGOING_SETTLEMENT_PROPOSAL:
case StateKey.OUTGOING_ROLL_OVER_PROPOSAL:
case StateKey.PENDING_CET:
case StateKey.PENDING_CLOSE:
return StateGroupKey.OPEN;
case StateKey.INCOMING_SETTLEMENT_PROPOSAL:
@ -195,6 +199,7 @@ const enum StateKey {
CONTRACT_SETUP = "ContractSetup",
PENDING_OPEN = "PendingOpen",
OPEN = "Open",
PENDING_CLOSE = "PendingClose",
PENDING_COMMIT = "PendingCommit",
PENDING_CET = "PendingCet",
OPEN_COMMITTED = "OpenCommitted",

Loading…
Cancel
Save