Browse Source

Merge #340 #341

340: No reachable panics r=thomaseizinger a=thomaseizinger

- Don't return plain-text errors to the user
- Don't expose panicking code paths to the user


341: Taker routes channels r=luckysori a=luckysori



Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Lucas Soriano del Pino <l.soriano.del.pino@gmail.com>
testing
bors[bot] 3 years ago
committed by GitHub
parent
commit
260b06b747
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 61
      daemon/src/routes_maker.rs
  2. 27
      daemon/src/routes_taker.rs
  3. 10
      daemon/src/taker.rs
  4. 64
      daemon/src/taker_cfd.rs

61
daemon/src/routes_maker.rs

@ -148,58 +148,35 @@ pub fn post_cfd_action(
action: CfdAction, action: CfdAction,
cfd_action_channel: &State<Box<dyn MessageChannel<maker_cfd::CfdAction>>>, cfd_action_channel: &State<Box<dyn MessageChannel<maker_cfd::CfdAction>>>,
_auth: Authenticated, _auth: Authenticated,
) -> Result<status::Accepted<()>, status::BadRequest<String>> { ) -> Result<status::Accepted<()>, status::Custom<()>> {
use maker_cfd::CfdAction::*; use maker_cfd::CfdAction::*;
match action { let result = match action {
CfdAction::AcceptOrder => { CfdAction::AcceptOrder => cfd_action_channel.do_send(AcceptOrder { order_id: id }),
cfd_action_channel CfdAction::RejectOrder => cfd_action_channel.do_send(RejectOrder { order_id: id }),
.do_send(AcceptOrder { order_id: id })
.expect("actor to always be available");
}
CfdAction::RejectOrder => {
cfd_action_channel
.do_send(RejectOrder { order_id: id })
.expect("actor to always be available");
}
CfdAction::AcceptSettlement => { CfdAction::AcceptSettlement => {
cfd_action_channel cfd_action_channel.do_send(AcceptSettlement { order_id: id })
.do_send(AcceptSettlement { order_id: id })
.expect("actor to always be available");
} }
CfdAction::RejectSettlement => { CfdAction::RejectSettlement => {
cfd_action_channel cfd_action_channel.do_send(RejectSettlement { order_id: id })
.do_send(RejectSettlement { order_id: id })
.expect("actor to always be available");
}
CfdAction::AcceptRollOver => {
cfd_action_channel
.do_send(AcceptRollOver { order_id: id })
.expect("actor to always be available");
}
CfdAction::RejectRollOver => {
cfd_action_channel
.do_send(RejectRollOver { order_id: id })
.expect("actor to always be available");
}
CfdAction::Commit => {
cfd_action_channel
.do_send(Commit { order_id: id })
.expect("actor to always be available");
} }
CfdAction::AcceptRollOver => cfd_action_channel.do_send(AcceptRollOver { order_id: id }),
CfdAction::RejectRollOver => cfd_action_channel.do_send(RejectRollOver { order_id: id }),
CfdAction::Commit => cfd_action_channel.do_send(Commit { order_id: id }),
CfdAction::Settle => { CfdAction::Settle => {
return Err(status::BadRequest(Some( tracing::error!("Collaborative settlement can only be triggered by taker");
"Collaborative settlement can only be triggered by taker".to_string(),
))); return Err(status::Custom(Status::BadRequest, ()));
} }
CfdAction::RollOver => { CfdAction::RollOver => {
return Err(status::BadRequest(Some( tracing::error!("RollOver proposal can only be triggered by taker");
"RollOver proposal can only be triggered by taker".to_string(),
))); return Err(status::Custom(Status::BadRequest, ()));
} }
} };
Ok(status::Accepted(None)) result
.map(|()| status::Accepted(None))
.map_err(|_| status::Custom(Status::InternalServerError, ()))
} }
#[rocket::get("/alive")] #[rocket::get("/alive")]

27
daemon/src/routes_taker.rs

@ -15,7 +15,7 @@ use std::borrow::Cow;
use std::path::PathBuf; use std::path::PathBuf;
use tokio::select; use tokio::select;
use tokio::sync::watch; use tokio::sync::watch;
use xtra::Address; use xtra::prelude::MessageChannel;
#[rocket::get("/feed")] #[rocket::get("/feed")]
pub async fn feed( pub async fn feed(
@ -104,14 +104,13 @@ pub struct CfdOrderRequest {
#[rocket::post("/cfd/order", data = "<cfd_order_request>")] #[rocket::post("/cfd/order", data = "<cfd_order_request>")]
pub async fn post_order_request( pub async fn post_order_request(
cfd_order_request: Json<CfdOrderRequest>, cfd_order_request: Json<CfdOrderRequest>,
cfd_actor_inbox: &State<Address<taker_cfd::Actor>>, take_offer_channel: &State<Box<dyn MessageChannel<taker_cfd::TakeOffer>>>,
) { ) {
cfd_actor_inbox take_offer_channel
.do_send_async(taker_cfd::TakeOffer { .do_send(taker_cfd::TakeOffer {
order_id: cfd_order_request.order_id, order_id: cfd_order_request.order_id,
quantity: cfd_order_request.quantity, quantity: cfd_order_request.quantity,
}) })
.await
.expect("actor to always be available"); .expect("actor to always be available");
} }
@ -119,9 +118,10 @@ pub async fn post_order_request(
pub async fn post_cfd_action( pub async fn post_cfd_action(
id: OrderId, id: OrderId,
action: CfdAction, action: CfdAction,
cfd_actor_address: &State<Address<taker_cfd::Actor>>, cfd_action_channel: &State<Box<dyn MessageChannel<taker_cfd::CfdAction>>>,
quote_updates: &State<watch::Receiver<bitmex_price_feed::Quote>>, quote_updates: &State<watch::Receiver<bitmex_price_feed::Quote>>,
) -> Result<status::Accepted<()>, status::BadRequest<String>> { ) -> Result<status::Accepted<()>, status::BadRequest<String>> {
use taker_cfd::CfdAction::*;
match action { match action {
CfdAction::AcceptOrder CfdAction::AcceptOrder
| CfdAction::RejectOrder | CfdAction::RejectOrder
@ -132,25 +132,22 @@ pub async fn post_cfd_action(
return Err(status::BadRequest(None)); return Err(status::BadRequest(None));
} }
CfdAction::Commit => { CfdAction::Commit => {
cfd_actor_address cfd_action_channel
.do_send_async(taker_cfd::Commit { order_id: id }) .do_send(Commit { order_id: id })
.await
.map_err(|e| status::BadRequest(Some(e.to_string())))?; .map_err(|e| status::BadRequest(Some(e.to_string())))?;
} }
CfdAction::Settle => { CfdAction::Settle => {
let current_price = quote_updates.borrow().for_taker(); let current_price = quote_updates.borrow().for_taker();
cfd_actor_address cfd_action_channel
.do_send_async(taker_cfd::ProposeSettlement { .do_send(ProposeSettlement {
order_id: id, order_id: id,
current_price, current_price,
}) })
.await
.expect("actor to always be available"); .expect("actor to always be available");
} }
CfdAction::RollOver => { CfdAction::RollOver => {
cfd_actor_address cfd_action_channel
.do_send_async(taker_cfd::ProposeRollOver { order_id: id }) .do_send(ProposeRollOver { order_id: id })
.await
.expect("actor to always be available"); .expect("actor to always be available");
} }
} }

10
daemon/src/taker.rs

@ -23,6 +23,7 @@ use std::time::Duration;
use tokio::sync::watch; use tokio::sync::watch;
use tokio_util::codec::FramedRead; use tokio_util::codec::FramedRead;
use tracing_subscriber::filter::LevelFilter; use tracing_subscriber::filter::LevelFilter;
use xtra::prelude::MessageChannel;
use xtra::spawn::TokioGlobalSpawnExt; use xtra::spawn::TokioGlobalSpawnExt;
use xtra::Actor; use xtra::Actor;
@ -264,7 +265,14 @@ async fn main() -> Result<()> {
.await .await
.unwrap(); .unwrap();
Ok(rocket.manage(cfd_actor_inbox).manage(cfd_feed_receiver)) let take_offer_channel =
MessageChannel::<taker_cfd::TakeOffer>::clone_channel(&cfd_actor_inbox);
let cfd_action_channel =
MessageChannel::<taker_cfd::CfdAction>::clone_channel(&cfd_actor_inbox);
Ok(rocket
.manage(take_offer_channel)
.manage(cfd_action_channel)
.manage(cfd_feed_receiver))
}, },
)) ))
.mount( .mount(

64
daemon/src/taker_cfd.rs

@ -26,13 +26,17 @@ pub struct TakeOffer {
pub quantity: Usd, pub quantity: Usd,
} }
pub struct ProposeSettlement { pub enum CfdAction {
pub order_id: OrderId, ProposeSettlement {
pub current_price: Usd, order_id: OrderId,
} current_price: Usd,
},
pub struct ProposeRollOver { ProposeRollOver {
pub order_id: OrderId, order_id: OrderId,
},
Commit {
order_id: OrderId,
},
} }
pub struct MakerStreamMessage { pub struct MakerStreamMessage {
@ -49,10 +53,6 @@ pub struct CfdRollOverCompleted {
pub dlc: Result<Dlc>, pub dlc: Result<Dlc>,
} }
pub struct Commit {
pub order_id: OrderId,
}
enum SetupState { enum SetupState {
Active { Active {
sender: mpsc::UnboundedSender<SetupMsg>, sender: mpsc::UnboundedSender<SetupMsg>,
@ -569,16 +569,23 @@ impl Handler<TakeOffer> for Actor {
} }
#[async_trait] #[async_trait]
impl Handler<ProposeSettlement> for Actor { impl Handler<CfdAction> for Actor {
async fn handle(&mut self, msg: ProposeSettlement, _ctx: &mut Context<Self>) { async fn handle(&mut self, msg: CfdAction, _ctx: &mut Context<Self>) {
log_error!(self.handle_propose_settlement(msg.order_id, msg.current_price)); use CfdAction::*;
}
}
#[async_trait] if let Err(e) = match msg {
impl Handler<ProposeRollOver> for Actor { Commit { order_id } => self.handle_commit(order_id).await,
async fn handle(&mut self, msg: ProposeRollOver, _ctx: &mut Context<Self>) { ProposeSettlement {
log_error!(self.handle_propose_roll_over(msg.order_id)); order_id,
current_price,
} => {
self.handle_propose_settlement(order_id, current_price)
.await
}
ProposeRollOver { order_id } => self.handle_propose_roll_over(order_id).await,
} {
tracing::error!("Message handler failed: {:#}", e);
}
} }
} }
@ -663,22 +670,11 @@ impl Handler<oracle::Attestation> for Actor {
} }
} }
#[async_trait]
impl Handler<Commit> for Actor {
async fn handle(&mut self, msg: Commit, _ctx: &mut Context<Self>) {
log_error!(self.handle_commit(msg.order_id))
}
}
impl Message for TakeOffer { impl Message for TakeOffer {
type Result = (); type Result = ();
} }
impl Message for ProposeSettlement { impl Message for CfdAction {
type Result = ();
}
impl Message for ProposeRollOver {
type Result = (); type Result = ();
} }
@ -695,8 +691,4 @@ impl Message for CfdRollOverCompleted {
type Result = (); type Result = ();
} }
impl Message for Commit {
type Result = ();
}
impl xtra::Actor for Actor {} impl xtra::Actor for Actor {}

Loading…
Cancel
Save