Browse Source

Merge #707 #714

707: Contract setup `Completed` is the same for taker and maker r=thomaseizinger a=da-kami

Either of the roles has to record the outcome of the setup, which should be the same for them.
In order to handle this in our event model we need `Completed` in the model so it is not role specific.

714: Make it clear what the payout is r=thomaseizinger a=thomaseizinger

![image](https://user-images.githubusercontent.com/5486389/143502096-175eb785-299b-4b34-bd7b-c11734af439d.png)


Co-authored-by: Daniel Karzel <daniel@comit.network>
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
debug-collab-settlement
bors[bot] 3 years ago
committed by GitHub
parent
commit
8ffab97735
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      daemon/src/model/cfd.rs
  2. 18
      daemon/src/setup_taker.rs
  3. 21
      daemon/src/taker_cfd.rs
  4. 33
      taker-frontend/src/components/History.tsx

16
daemon/src/model/cfd.rs

@ -1661,6 +1661,22 @@ impl CollaborativeSettlement {
} }
} }
/// Message sent from a setup actor to the
/// cfd actor to notify that the contract setup has finished.
pub enum Completed {
NewContract {
order_id: OrderId,
dlc: Dlc,
},
Rejected {
order_id: OrderId,
},
Failed {
order_id: OrderId,
error: anyhow::Error,
},
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

18
daemon/src/setup_taker.rs

@ -1,4 +1,4 @@
use crate::model::cfd::{Cfd, CfdState, Dlc, Order, OrderId, Role}; use crate::model::cfd::{Cfd, CfdState, Completed, Dlc, Order, OrderId, Role};
use crate::model::Usd; use crate::model::Usd;
use crate::oracle::Announcement; use crate::oracle::Announcement;
use crate::setup_contract::{self, SetupParams}; use crate::setup_contract::{self, SetupParams};
@ -206,22 +206,6 @@ pub struct SetupFailed {
error: anyhow::Error, error: anyhow::Error,
} }
/// Message sent from the `setup_taker::Actor` to the
/// `taker_cfd::Actor` to notify that the contract setup has finished.
pub enum Completed {
NewContract {
order_id: OrderId,
dlc: Dlc,
},
Rejected {
order_id: OrderId,
},
Failed {
order_id: OrderId,
error: anyhow::Error,
},
}
impl xtra::Message for Started { impl xtra::Message for Started {
type Result = (); type Result = ();
} }

21
daemon/src/taker_cfd.rs

@ -1,8 +1,9 @@
use crate::cfd_actors::{self, append_cfd_state, insert_cfd_and_send_to_feed}; 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::db::{insert_order, load_cfd_by_order_id, load_order_by_id};
use crate::model::cfd::{ use crate::model::cfd::{
Cfd, CfdState, CfdStateCommon, CollaborativeSettlement, Dlc, Order, OrderId, Origin, Role, Cfd, CfdState, CfdStateCommon, CollaborativeSettlement, Completed, Dlc, Order, OrderId, Origin,
RollOverProposal, SettlementKind, SettlementProposal, UpdateCfdProposal, UpdateCfdProposals, Role, RollOverProposal, SettlementKind, SettlementProposal, UpdateCfdProposal,
UpdateCfdProposals,
}; };
use crate::model::{BitMexPriceEventId, Price, Timestamp, Usd}; use crate::model::{BitMexPriceEventId, Price, Timestamp, Usd};
use crate::monitor::{self, MonitorParams}; use crate::monitor::{self, MonitorParams};
@ -357,7 +358,7 @@ where
impl<O, M, W> Actor<O, M, W> impl<O, M, W> Actor<O, M, W>
where where
Self: xtra::Handler<setup_taker::Completed>, Self: xtra::Handler<Completed>,
O: xtra::Handler<oracle::GetAnnouncement> + xtra::Handler<oracle::MonitorAttestation>, O: xtra::Handler<oracle::GetAnnouncement> + xtra::Handler<oracle::MonitorAttestation>,
W: xtra::Handler<wallet::BuildPartyParams> + xtra::Handler<wallet::Sign>, W: xtra::Handler<wallet::BuildPartyParams> + xtra::Handler<wallet::Sign>,
{ {
@ -436,14 +437,14 @@ where
M: xtra::Handler<monitor::StartMonitoring>, M: xtra::Handler<monitor::StartMonitoring>,
W: xtra::Handler<wallet::TryBroadcastTransaction>, W: xtra::Handler<wallet::TryBroadcastTransaction>,
{ {
async fn handle_setup_completed(&mut self, msg: setup_taker::Completed) -> Result<()> { async fn handle_setup_completed(&mut self, msg: Completed) -> Result<()> {
let (order_id, dlc) = match msg { let (order_id, dlc) = match msg {
setup_taker::Completed::NewContract { order_id, dlc } => (order_id, dlc), Completed::NewContract { order_id, dlc } => (order_id, dlc),
setup_taker::Completed::Rejected { order_id } => { Completed::Rejected { order_id } => {
self.append_cfd_state_rejected(order_id).await?; self.append_cfd_state_rejected(order_id).await?;
return Ok(()); return Ok(());
} }
setup_taker::Completed::Failed { order_id, error } => { Completed::Failed { order_id, error } => {
self.append_cfd_state_setup_failed(order_id, error).await?; self.append_cfd_state_setup_failed(order_id, error).await?;
return Ok(()); return Ok(());
} }
@ -655,7 +656,7 @@ where
#[async_trait] #[async_trait]
impl<O: 'static, M: 'static, W: 'static> Handler<TakeOffer> for Actor<O, M, W> impl<O: 'static, M: 'static, W: 'static> Handler<TakeOffer> for Actor<O, M, W>
where where
Self: xtra::Handler<setup_taker::Completed>, Self: xtra::Handler<Completed>,
O: xtra::Handler<oracle::GetAnnouncement> + xtra::Handler<oracle::MonitorAttestation>, O: xtra::Handler<oracle::GetAnnouncement> + xtra::Handler<oracle::MonitorAttestation>,
W: xtra::Handler<wallet::BuildPartyParams> + xtra::Handler<wallet::Sign>, W: xtra::Handler<wallet::BuildPartyParams> + xtra::Handler<wallet::Sign>,
{ {
@ -742,13 +743,13 @@ where
} }
#[async_trait] #[async_trait]
impl<O: 'static, M: 'static, W: 'static> Handler<setup_taker::Completed> for Actor<O, M, W> impl<O: 'static, M: 'static, W: 'static> Handler<Completed> for Actor<O, M, W>
where where
O: xtra::Handler<oracle::MonitorAttestation>, O: xtra::Handler<oracle::MonitorAttestation>,
M: xtra::Handler<monitor::StartMonitoring>, M: xtra::Handler<monitor::StartMonitoring>,
W: xtra::Handler<wallet::TryBroadcastTransaction>, W: xtra::Handler<wallet::TryBroadcastTransaction>,
{ {
async fn handle(&mut self, msg: setup_taker::Completed, _ctx: &mut Context<Self>) { async fn handle(&mut self, msg: Completed, _ctx: &mut Context<Self>) {
log_error!(self.handle_setup_completed(msg)) log_error!(self.handle_setup_completed(msg))
} }
} }

33
taker-frontend/src/components/History.tsx

@ -66,9 +66,12 @@ const CfdDetails = ({ cfd }: CfdDetailsProps) => {
const quantity = `$${cfd.quantity_usd}`; const quantity = `$${cfd.quantity_usd}`;
const margin = `${Math.round((cfd.margin) * 1_000_000) / 1_000_000}`; const margin = `${Math.round((cfd.margin) * 1_000_000) / 1_000_000}`;
const liquidationPrice = `$${cfd.liquidation_price}`; const liquidationPrice = `$${cfd.liquidation_price}`;
const pAndL = Math.round((cfd.profit_btc) * 1_000_000) / 1_000_000;
const pAndLNumber = Math.round((cfd.profit_btc) * 1_000_000) / 1_000_000;
const pAndL = pAndLNumber < 0 ? `-₿${Math.abs(pAndLNumber)}` : `${Math.abs(pAndLNumber)}`;
const expiry = cfd.expiry_timestamp; const expiry = cfd.expiry_timestamp;
const profit = Math.round((cfd.margin + cfd.profit_btc) * 1_000_000) / 1_000_000; const payout = `${Math.round((cfd.margin + cfd.profit_btc) * 1_000_000) / 1_000_000}`;
const txLock = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Lock); const txLock = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Lock);
const txCommit = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Commit); const txCommit = cfd.details.tx_url_list.find((tx) => tx.label === TxLabel.Commit);
@ -82,36 +85,41 @@ const CfdDetails = ({ cfd }: CfdDetailsProps) => {
|| !(cfd.state.key === StateKey.OPEN); || !(cfd.state.key === StateKey.OPEN);
return ( return (
<HStack bg={useColorModeValue("gray.100", "gray.700")} rounded={5}> <HStack bg={useColorModeValue("gray.100", "gray.700")} rounded={5} padding={2}>
<Center rounded={5} h={"100%"}> <Center>
<Table variant="striped" colorScheme="gray" size="sm"> <Table variant="striped" colorScheme="gray" size="sm">
<Tbody> <Tbody>
<Tr> <Tr>
<Td><Text as={"b"}>Quantity</Text></Td> <Td><Text as={"b"}>Quantity</Text></Td>
<Td>{quantity}</Td> {/*TODO: Fix textAlign right hacks by using a grid instead ... */}
<Td textAlign="right">{quantity}</Td>
</Tr> </Tr>
<Tr> <Tr>
<Td><Text as={"b"}>Opening price</Text></Td> <Td><Text as={"b"}>Opening price</Text></Td>
<Td>{initialPrice}</Td> <Td textAlign="right">{initialPrice}</Td>
</Tr> </Tr>
<Tr> <Tr>
<Td><Text as={"b"}>Liquidation</Text></Td> <Td><Text as={"b"}>Liquidation</Text></Td>
<Td>{liquidationPrice}</Td> <Td textAlign="right">{liquidationPrice}</Td>
</Tr> </Tr>
<Tr> <Tr>
<Td><Text as={"b"}>Margin</Text></Td> <Td><Text as={"b"}>Margin</Text></Td>
<Td>{margin}</Td> <Td textAlign="right">{margin}</Td>
</Tr> </Tr>
<Tr> <Tr>
<Td><Text as={"b"}>Unrealized P/L</Text></Td> <Td><Text as={"b"}>Unrealized P/L</Text></Td>
<Td>{pAndL.toString()}</Td> <Td textAlign="right">{pAndL}</Td>
</Tr>
<Tr>
<Td><Text as={"b"}>Payout</Text></Td>
<Td textAlign="right">{payout}</Td>
</Tr> </Tr>
</Tbody> </Tbody>
</Table> </Table>
</Center> </Center>
<VStack> <VStack>
<Badge colorScheme={cfd.state.getColorScheme()}>{cfd.state.getLabel()}</Badge> <Badge colorScheme={cfd.state.getColorScheme()}>{cfd.state.getLabel()}</Badge>
<HStack w={"95%"}> <HStack>
<VStack> <VStack>
<TxIcon tx={txLock} /> <TxIcon tx={txLock} />
<Text>Lock</Text> <Text>Lock</Text>
@ -149,11 +157,6 @@ const CfdDetails = ({ cfd }: CfdDetailsProps) => {
</>} </>}
</HStack> </HStack>
<HStack> <HStack>
<Box w={"45%"}>
<Text fontSize={"sm"} align={"left"}>
At the current rate you would receive <b> {profit}</b>
</Text>
</Box>
<Box w={"45%"}> <Box w={"45%"}>
<Popover <Popover
placement="bottom" placement="bottom"

Loading…
Cancel
Save