Skip to content
Permalink
Browse files

Add cancellable field to my_orders and order_status.

Turn get_my_info of swap to be option as sometimes swap is not started
so first event can be different (StartFailed).
  • Loading branch information...
artemii235 committed Jun 17, 2019
1 parent dee09ea commit d8b03f338656e8340f8eb21a34cc5a98eb927512
Showing with 152 additions and 30 deletions.
  1. +70 −12 mm2src/lp_ordermatch.rs
  2. +13 −18 mm2src/lp_swap.rs
  3. +69 −0 mm2src/ordermatch_tests.rs
@@ -74,6 +74,12 @@ struct TakerOrder {
matches: HashMap<Uuid, TakerMatch>
}

impl TakerOrder {
fn is_cancellable(&self) -> bool {
self.matches.is_empty()
}
}

/// Result of match_reserved function
#[derive(Debug, PartialEq)]
enum MatchReservedResult {
@@ -127,6 +133,16 @@ impl MakerOrder {
);
&self.max_base_vol - reserved
}

fn is_cancellable(&self) -> bool {
for (_, order_match) in self.matches.iter() {
// if there's at least 1 ongoing match the order is not cancellable
if order_match.connected.is_none() && order_match.connect.is_none() {
return false;
}
}
true
}
}

impl Into<MakerOrder> for TakerOrder {
@@ -897,16 +913,15 @@ pub fn order_status(ctx: MmArc, req: Json) -> HyRes {
if let Some(order) = maker_orders.get(&req.uuid) {
return rpc_response(200, json!({
"type": "Maker",
"order": order,
"available_amount": order.available_amount(),
"order": MakerOrderForRpc::from(order),
}).to_string());
}

let taker_orders = try_h!(ordermatch_ctx.my_taker_orders.lock());
if let Some(order) = taker_orders.get(&req.uuid) {
return rpc_response(200, json!({
"type": "Taker",
"order": order,
"order": TakerOrderForRpc::from(order),
}).to_string());
}

@@ -923,9 +938,13 @@ pub fn cancel_order(ctx: MmArc, req: Json) -> HyRes {

let ordermatch_ctx = try_h!(OrdermatchContext::from_ctx(&ctx));
let mut maker_orders = try_h!(ordermatch_ctx.my_maker_orders.lock());
match maker_orders.remove(&req.uuid) {
Some(mut order) => {
match maker_orders.entry(req.uuid) {
Entry::Occupied(order) => {
if !order.get().is_cancellable() {
return rpc_err_response(500, &format!("Order {} is being matched now, can't cancel", req.uuid));
}
let mut cancelled_orders = try_h!(ordermatch_ctx.cancelled_orders.lock());
let mut order = order.remove();
// TODO cancel means setting the volume to 0 as of now, should refactor
order.max_base_vol = 0.into();
delete_my_maker_order(&ctx, &order);
@@ -935,33 +954,72 @@ pub fn cancel_order(ctx: MmArc, req: Json) -> HyRes {
}).to_string())
},
// look for taker order with provided uuid
None => (),
Entry::Vacant(_) => (),
}

let mut taker_orders = try_h!(ordermatch_ctx.my_taker_orders.lock());
match taker_orders.remove(&req.uuid) {
Some(order) => {
match taker_orders.entry(req.uuid) {
Entry::Occupied(order) => {
if !order.get().is_cancellable() {
return rpc_err_response(500, &format!("Order {} is being matched now, can't cancel", req.uuid));
}
let order = order.remove();
delete_my_taker_order(&ctx, &order);
return rpc_response(200, json!({
"result": "success"
}).to_string())
},
// error is returned
None => (),
Entry::Vacant(_) => (),
}

rpc_err_response(404, &format!("Order with uuid {} is not found", req.uuid))
}

#[derive(Serialize)]
struct MakerOrderForRpc<'a> {
#[serde(flatten)]
order: &'a MakerOrder,
cancellable: bool,
available_amount: BigDecimal,
}

impl<'a> From<&'a MakerOrder> for MakerOrderForRpc<'a> {
fn from(order: &'a MakerOrder) -> MakerOrderForRpc {
MakerOrderForRpc {
order,
cancellable: order.is_cancellable(),
available_amount: order.available_amount(),
}
}
}

#[derive(Serialize)]
struct TakerOrderForRpc<'a> {
#[serde(flatten)]
order: &'a TakerOrder,
cancellable: bool
}

impl<'a> From<&'a TakerOrder> for TakerOrderForRpc<'a> {
fn from(order: &'a TakerOrder) -> TakerOrderForRpc {
TakerOrderForRpc {
order,
cancellable: order.is_cancellable(),
}
}
}

pub fn my_orders(ctx: MmArc) -> HyRes {
let ordermatch_ctx = try_h!(OrdermatchContext::from_ctx(&ctx));
let maker_orders = try_h!(ordermatch_ctx.my_maker_orders.lock());
let taker_orders = try_h!(ordermatch_ctx.my_taker_orders.lock());

let maker_orders_for_rpc: HashMap<_, _> = maker_orders.iter().map(|(uuid, order)| (uuid, MakerOrderForRpc::from(order))).collect();
let taker_orders_for_rpc: HashMap<_, _> = taker_orders.iter().map(|(uuid, order)| (uuid, TakerOrderForRpc::from(order))).collect();
rpc_response(200, json!({
"result": {
"maker_orders": *maker_orders,
"taker_orders": *taker_orders,
"maker_orders": maker_orders_for_rpc,
"taker_orders": taker_orders_for_rpc,
}
}).to_string())
}
@@ -562,39 +562,39 @@ impl SavedSwap {
}
}

fn get_my_info(&self) -> Result<MySwapInfo, String> {
fn get_my_info(&self) -> Option<MySwapInfo> {
match self {
SavedSwap::Maker(swap) => {
match swap.events.first() {
Some(event) => match &event.event {
MakerSwapEvent::Started(data) => {
Ok(MySwapInfo {
Some(MySwapInfo {
my_coin: data.maker_coin.clone(),
other_coin: data.taker_coin.clone(),
my_amount: data.maker_amount.clone(),
other_amount: data.taker_amount.clone(),
started_at: data.started_at,
})
},
_ => ERR!("Swap first event is not `Started`"),
_ => None,
},
None => ERR!("Swap events are empty"),
None => None,
}
},
SavedSwap::Taker(swap) => match swap.events.first() {
Some(event) => match &event.event {
TakerSwapEvent::Started(data) => {
Ok(MySwapInfo {
Some(MySwapInfo {
my_coin: data.taker_coin.clone(),
other_coin: data.maker_coin.clone(),
my_amount: data.taker_amount.clone(),
other_amount: data.maker_amount.clone(),
started_at: data.started_at,
})
},
_ => ERR!("Swap first event is not `Started`"),
_ => None,
},
None => ERR!("Swap events are empty"),
None => None,
},
}
}
@@ -1889,7 +1889,7 @@ pub fn my_swap_status(ctx: MmArc, req: Json) -> HyRes {
}).to_string());
}
let status: SavedSwap = try_h!(json::from_slice(&content));
let my_info = try_h!(status.get_my_info());
let my_info = status.get_my_info();
let mut json = try_h!(json::to_value(status));
json["my_info"] = try_h!(json::to_value(my_info));

@@ -2013,16 +2013,11 @@ pub fn my_recent_swaps(ctx: MmArc, req: Json) -> HyRes {
// iterate over file entries trying to parse the file contents and add to result vector
let swaps: Vec<Json> = entries.iter().skip(skip).take(limit as usize).map(|(_, entry)|
match json::from_slice::<SavedSwap>(&slurp(&entry.path())) {
Ok(swap) => match swap.get_my_info() {
Ok(info) => {
let mut json = unwrap!(json::to_value(swap));
json["my_info"] = unwrap!(json::to_value(info));
json
},
Err(e) => {
log!("Error " (e) " getting my_swap_info of swap " (swap.uuid()));
Json::Null
},
Ok(swap) => {
let my_info = swap.get_my_info();
let mut json = unwrap!(json::to_value(swap));
json["my_info"] = unwrap!(json::to_value(my_info));
json
},
Err(e) => {
log!("Error " (e) " parsing JSON from " (entry.path().display()));
@@ -441,3 +441,72 @@ fn test_taker_match_reserved() {

assert_eq!(MatchReservedResult::NotMatched, order.match_reserved(&reserved));
}

#[test]
fn test_taker_order_cancellable() {
let request = TakerRequest {
base: "BASE".into(),
rel: "REL".into(),
uuid: Uuid::new_v4(),
method: "request".into(),
dest_pub_key: H256Json::default(),
sender_pubkey: H256Json::default(),
base_amount: 1.into(),
rel_amount: 2.into(),
action: TakerAction::Buy,
};

let order = TakerOrder {
request,
matches: HashMap::new(),
created_at: now_ms()
};

assert!(order.is_cancellable());

let request = TakerRequest {
base: "BASE".into(),
rel: "REL".into(),
uuid: Uuid::new_v4(),
method: "request".into(),
dest_pub_key: H256Json::default(),
sender_pubkey: H256Json::default(),
base_amount: 1.into(),
rel_amount: 2.into(),
action: TakerAction::Buy,
};

let mut order = TakerOrder {
request,
matches: HashMap::new(),
created_at: now_ms()
};

order.matches.insert(
Uuid::new_v4(),
TakerMatch {
last_updated: now_ms(),
reserved: MakerReserved {
method: "reserved".into(),
base: "BASE".into(),
rel: "REL".into(),
base_amount: 1.into(),
rel_amount: 3.into(),
sender_pubkey: H256Json::default(),
dest_pub_key: H256Json::default(),
maker_order_uuid: Uuid::new_v4(),
taker_order_uuid: Uuid::new_v4(),
},
connect: TakerConnect {
method: "connect".into(),
sender_pubkey: H256Json::default(),
dest_pub_key: H256Json::default(),
maker_order_uuid: Uuid::new_v4(),
taker_order_uuid: Uuid::new_v4(),
},
connected: None,
}
);

assert!(!order.is_cancellable());
}

0 comments on commit d8b03f3

Please sign in to comment.
You can’t perform that action at this time.