Browse Source

Add a taker endpoint for initiating collaborative settlement (#175)

* Add a taker endpoint for initiating collaborative settlement

For now, only logs the proposal in the logs on the maker side
fix-olivia-event-id
Mariusz 3 years ago
committed by GitHub
parent
commit
cf08326c64
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 26
      daemon/src/maker_cfd.rs
  2. 23
      daemon/src/model/cfd.rs
  3. 18
      daemon/src/routes_taker.rs
  4. 1
      daemon/src/taker.rs
  5. 37
      daemon/src/taker_cfd.rs
  6. 15
      daemon/src/wire.rs

26
daemon/src/maker_cfd.rs

@ -4,7 +4,9 @@ use crate::db::{
load_cfd_by_order_id, load_order_by_id,
};
use crate::maker_inc_connections::TakerCommand;
use crate::model::cfd::{Cfd, CfdState, CfdStateChangeEvent, CfdStateCommon, Dlc, Order, OrderId};
use crate::model::cfd::{
Cfd, CfdState, CfdStateChangeEvent, CfdStateCommon, Dlc, Order, OrderId, SettlementProposal,
};
use crate::model::{TakerId, Usd};
use crate::monitor::MonitorParams;
use crate::wallet::Wallet;
@ -142,6 +144,15 @@ impl Actor {
Ok(())
}
async fn handle_propose_settlement(&mut self, proposal: SettlementProposal) -> Result<()> {
tracing::info!(
"Received settlement proposal from the taker: {:?}",
proposal
);
// TODO: Handle the proposal
Ok(())
}
async fn handle_inc_protocol_msg(
&mut self,
taker_id: TakerId,
@ -484,6 +495,19 @@ impl Handler<TakerStreamMessage> for Actor {
wire::TakerToMaker::TakeOrder { order_id, quantity } => {
log_error!(self.handle_take_order(taker, order_id, quantity))
}
wire::TakerToMaker::ProposeSettlement {
order_id,
timestamp,
taker,
maker,
} => {
log_error!(self.handle_propose_settlement(SettlementProposal {
order_id,
timestamp,
taker,
maker
}))
}
wire::TakerToMaker::Protocol(msg) => {
log_error!(self.handle_inc_protocol_msg(taker, msg))
}

23
daemon/src/model/cfd.rs

@ -309,6 +309,15 @@ impl Display for CfdState {
}
}
/// Proposed collaborative settlement
#[derive(Debug, Clone)]
pub struct SettlementProposal {
pub order_id: OrderId,
pub timestamp: SystemTime,
pub taker: Amount,
pub maker: Amount,
}
/// Represents a cfd (including state)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Cfd {
@ -356,6 +365,20 @@ impl Cfd {
Ok(profit)
}
#[allow(dead_code)] // Not used by all binaries.
pub fn calculate_settlement(&self, _current_price: Usd) -> Result<SettlementProposal> {
// TODO: Calculate values for taker and maker
// For the time being, assume that everybody loses :)
let settlement = SettlementProposal {
order_id: self.order.id,
timestamp: SystemTime::now(),
taker: Amount::ZERO,
maker: Amount::ZERO,
};
Ok(settlement)
}
pub fn position(&self) -> Position {
match self.order.origin {
Origin::Ours => self.order.position.clone(),

18
daemon/src/routes_taker.rs

@ -82,7 +82,7 @@ pub struct CfdOrderRequest {
pub quantity: Usd,
}
#[rocket::post("/cfd", data = "<cfd_order_request>")]
#[rocket::post("/cfd/order", data = "<cfd_order_request>")]
pub async fn post_order_request(
cfd_order_request: Json<CfdOrderRequest>,
cfd_actor_inbox: &State<Address<taker_cfd::Actor>>,
@ -96,6 +96,22 @@ pub async fn post_order_request(
.expect("actor to always be available");
}
#[rocket::post("/cfd/<id>/settle")]
pub async fn post_settlement_proposal(
id: OrderId,
cfd_actor_inbox: &State<Address<taker_cfd::Actor>>,
quote_updates: &State<watch::Receiver<bitmex_price_feed::Quote>>,
) {
let current_price = quote_updates.borrow().for_taker();
cfd_actor_inbox
.do_send_async(taker_cfd::ProposeSettlement {
order_id: id,
current_price,
})
.await
.expect("actor to always be available");
}
#[rocket::get("/alive")]
pub fn get_health_check() {}

1
daemon/src/taker.rs

@ -198,6 +198,7 @@ async fn main() -> Result<()> {
rocket::routes![
routes_taker::feed,
routes_taker::post_order_request,
routes_taker::post_settlement_proposal,
routes_taker::get_health_check,
routes_taker::margin_calc,
],

37
daemon/src/taker_cfd.rs

@ -26,6 +26,11 @@ pub struct TakeOffer {
pub quantity: Usd,
}
pub struct ProposeSettlement {
pub order_id: OrderId,
pub current_price: Usd,
}
pub struct MakerStreamMessage {
pub item: Result<wire::MakerToTaker>,
}
@ -121,6 +126,27 @@ impl Actor {
Ok(())
}
async fn handle_propose_settlement(
&mut self,
order_id: OrderId,
current_price: Usd,
) -> Result<()> {
let mut conn = self.db.acquire().await?;
let cfd = load_cfd_by_order_id(order_id, &mut conn).await?;
let settlement = cfd.calculate_settlement(current_price)?;
self.send_to_maker
.do_send_async(wire::TakerToMaker::ProposeSettlement {
order_id: settlement.order_id,
timestamp: settlement.timestamp,
taker: settlement.taker,
maker: settlement.maker,
})
.await?;
Ok(())
}
async fn handle_new_order(&mut self, order: Option<Order>) -> Result<()> {
match order {
Some(mut order) => {
@ -310,6 +336,13 @@ impl Handler<TakeOffer> for Actor {
}
}
#[async_trait]
impl Handler<ProposeSettlement> for Actor {
async fn handle(&mut self, msg: ProposeSettlement, _ctx: &mut Context<Self>) {
log_error!(self.handle_propose_settlement(msg.order_id, msg.current_price));
}
}
#[async_trait]
impl Handler<MakerStreamMessage> for Actor {
async fn handle(
@ -363,6 +396,10 @@ impl Message for TakeOffer {
type Result = ();
}
impl Message for ProposeSettlement {
type Result = ();
}
// this signature is a bit different because we use `Address::attach_stream`
impl Message for MakerStreamMessage {
type Result = KeepRunning;

15
daemon/src/wire.rs

@ -13,13 +13,25 @@ use serde::{Deserialize, Serialize};
use std::fmt;
use std::marker::PhantomData;
use std::ops::RangeInclusive;
use std::time::SystemTime;
use tokio_util::codec::{Decoder, Encoder, LengthDelimitedCodec};
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type", content = "payload")]
#[allow(clippy::large_enum_variant)]
pub enum TakerToMaker {
TakeOrder { order_id: OrderId, quantity: Usd },
TakeOrder {
order_id: OrderId,
quantity: Usd,
},
ProposeSettlement {
order_id: OrderId,
timestamp: SystemTime,
#[serde(with = "::bdk::bitcoin::util::amount::serde::as_btc")]
taker: Amount,
#[serde(with = "::bdk::bitcoin::util::amount::serde::as_btc")]
maker: Amount,
},
Protocol(SetupMsg),
}
@ -27,6 +39,7 @@ impl fmt::Display for TakerToMaker {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TakerToMaker::TakeOrder { .. } => write!(f, "TakeOrder"),
TakerToMaker::ProposeSettlement { .. } => write!(f, "ProposeSettlement"),
TakerToMaker::Protocol(_) => write!(f, "Protocol"),
}
}

Loading…
Cancel
Save