Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simple market maker bot #1066

Merged
merged 84 commits into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from 60 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
90562a6
feat(simple_trading_bot): draft for simple trading bot implementation…
Milerius Sep 13, 2021
86039aa
feat(simple_trading_bot): remove spurious use of a non-public data st…
Milerius Sep 13, 2021
896fa3f
feat(simple_trading_bot): remove unused HashSet inclusion
Milerius Sep 13, 2021
a3178fb
feat(simple_trading_bot): remove spurious usage of return.
Milerius Sep 13, 2021
638f3d6
enhancements(simple_trading_bot): fix needless_borrow warnings
Milerius Sep 13, 2021
d280897
enhancements(simple_trading_bot): rustfmt
Milerius Sep 13, 2021
f5a72ef
enhancements(simple_trading_bot): rustfmt
Milerius Sep 13, 2021
b160430
Merge branch 'dev' of https://github.com/KomodoPlatform/atomicDEX-API…
Milerius Sep 14, 2021
1ad4506
feat(simple_trading_bot): add iteration through maker_orders
Milerius Sep 14, 2021
b280e0c
Merge branch 'dev' of https://github.com/KomodoPlatform/atomicDEX-API…
Milerius Sep 14, 2021
890344d
feat(simple_trading_bot): change price url to komodo.live
Milerius Sep 14, 2021
fc28665
enhancements(simple_trading_bot): first iteration of fix based on the…
Milerius Sep 14, 2021
bac1e6c
enhancements(simple_trading_bot): confs can be negative, switching to…
Milerius Sep 14, 2021
c82bc04
enhancements(simple_trading_bot): use match expression when parsing n…
Milerius Sep 14, 2021
ddf3d96
enhancements(simple_trading_bot): use an enum for the trading bot states
Milerius Sep 15, 2021
8ef6883
enhancements(simple_trading_bot): use mmnumber instead of string.
Milerius Sep 15, 2021
9e6fa27
enhancements(simple_trading_bot): introducing TradingPair data structure
Milerius Sep 15, 2021
c07c90d
enhancements(simple_trading_bot): rename functor, make it more expres…
Milerius Sep 15, 2021
7bc9f1c
enhancements(simple_trading_bot): make lp_bot_tests a submodule of mm…
Milerius Sep 15, 2021
85f7d1a
enhancements(simple_trading_bot): make lp_bot a submodule of lp_order…
Milerius Sep 15, 2021
eb67a8d
enhancements(simple_trading_bot): don't use clone on a copiable data
Milerius Sep 15, 2021
abb55ed
feat(simple_trading_bot): add skeleton for creating orders
Milerius Sep 15, 2021
456fddb
feat(simple_trading_bot): continue implementation of creating single …
Milerius Sep 15, 2021
28f5b43
feat(clippy): fix various clippy warnings
Milerius Sep 15, 2021
7d8dbf8
feat(clippy): fix various clippy warnings
Milerius Sep 15, 2021
4868e0f
feat(price): add calculated price
Milerius Sep 15, 2021
05d07e7
feat(simple_market_maker): add more checks and fix clippy warnings
Milerius Sep 16, 2021
122af29
feat(simple_market_maker): simplify coin_find_and_checks
Milerius Sep 16, 2021
858b9be
feat(simple_market_maker): fix condition
Milerius Sep 16, 2021
b1c7c88
feat(simple_market_maker): finalize the creation of the order.
Milerius Sep 16, 2021
60599cc
feat(simple_market_maker): finalize with volume and min_volume
Milerius Sep 16, 2021
8211804
feat(simple_market_maker): add simple_market_maker_tests.rs
Milerius Sep 16, 2021
0dde0f9
fix(simple_market_maker): use the good TradingBotContext
Milerius Sep 16, 2021
d4cfa2b
feat(simple_market_maker): change approach for error checking
Milerius Sep 17, 2021
93a7f37
enhancements(simple_market_maker): review fixing
Milerius Sep 17, 2021
74e7fe2
enhancements(market_maker_bot): use MmNumber instead of string
Milerius Sep 17, 2021
89231eb
enhancements(market_maker_bot): use match expression instead of chain…
Milerius Sep 19, 2021
904ec2f
enhancements(market_maker_bot): fix code review comments
Milerius Sep 19, 2021
daa5130
enhancements(market_maker_bot): fix code review comments
Milerius Sep 19, 2021
c2f8656
enhancements(market_maker_bot): fix unit tests
Milerius Sep 19, 2021
fae2b48
feat(market_maker_bot): continue update maker order
Milerius Sep 20, 2021
242c3b0
feat(market_maker_bot): added first vwap version
Milerius Sep 21, 2021
12ad889
feat(market_maker_bot): add unit tests for vwap
Milerius Sep 21, 2021
15caeec
feat(market_maker_bot): more unit tests
Milerius Sep 21, 2021
7df25f6
feat(simple_market_maker): add last vwap unit tests
Milerius Sep 22, 2021
e99856b
feat(simple_market_maker): refactor some code
Milerius Sep 22, 2021
351f977
Merge branch 'dev' of https://github.com/KomodoPlatform/atomicDEX-API…
Milerius Sep 23, 2021
4d427d2
feat(simple_market_maker): continue refactor
Milerius Sep 23, 2021
98a7284
feat(simple_market_maker): move price service
Milerius Sep 23, 2021
79d646f
feat(simple_market_maker): continue refactoring
Milerius Sep 23, 2021
620aa76
feat(market_maker): implement the cancelling of pending orders
Milerius Sep 23, 2021
aa31c6a
feat(market_maker): fix unit tests
Milerius Sep 23, 2021
80b1ba8
feat(market_maker): fix review comments
Milerius Sep 24, 2021
b11d364
feat(market_maker): fix review comments
Milerius Sep 24, 2021
00d4e38
feat(simple_market_maker): use a proper error for balance
Milerius Sep 25, 2021
81c641c
feat(simple_market_maker): use a lp_findpair like functions
Milerius Sep 25, 2021
9d53fa3
feat(get_non_zero_balance): implement get_non_zero_balance in lp_coins
Milerius Sep 27, 2021
f57b48f
feat(simple_market_maker_bot): fix nonzerobalance
Milerius Sep 27, 2021
6ac98b7
feat(simple_market_maker_bot): add multiple spawn for order update
Milerius Sep 27, 2021
2906c8d
Merge branch 'dev' of https://github.com/KomodoPlatform/atomicDEX-API…
Milerius Sep 27, 2021
d77a110
enhancement(review): simplify update/creation order
Milerius Sep 30, 2021
21674d4
enhancement(review): simplify cex rates
Milerius Sep 30, 2021
51cc462
enhancement(review): simplify mm error creation in cancel_order
Milerius Sep 30, 2021
1b5bde4
enhancement(review): rename min_volume -> min_volume_percentage from …
Milerius Sep 30, 2021
be541a0
enhancement(review): refactor vwap calculation
Milerius Sep 30, 2021
476c659
feat(review): clippy warnings
Milerius Sep 30, 2021
641331d
Merge branch 'dev' of https://github.com/KomodoPlatform/atomicDEX-API…
Milerius Oct 4, 2021
4d2d4e1
feat(bot): cancel order only managed by the trading bot.
Milerius Oct 4, 2021
60a6ba4
feat(simple_market_maker): fix review comments
Milerius Oct 5, 2021
853e48e
feat(simple_market_maker): fix review comments
Milerius Oct 5, 2021
6c917c2
feat(simple_market_maker): change valid trades approach, remove usele…
Milerius Oct 5, 2021
fc72387
feat(simple_market_maker): continue review fixing
Milerius Oct 5, 2021
abd7f75
feat(simple_market_maker): continue review fixing
Milerius Oct 5, 2021
9db2ed9
feat(simple_market_maker): clippy fix
Milerius Oct 5, 2021
6fe1e78
feat(simple_market_maker_bot): use option for timestamp
Milerius Oct 6, 2021
d347c2d
feat(simple_market_maker_bot): simplify asynchrounous code
Milerius Oct 6, 2021
e0512aa
feat(bot): simplify order creation
Milerius Oct 6, 2021
36d5a7c
feat(sync): sync with dev
Milerius Oct 6, 2021
a667c4d
Merge branch 'dev' of https://github.com/KomodoPlatform/atomicDEX-API…
Milerius Oct 8, 2021
7d6e219
feat(simple_market_maker): fix review iteration
Milerius Oct 8, 2021
cf2e96c
feat(clippy): fix clippy warnings
Milerius Oct 8, 2021
4f2dc9c
feat(time): don't use unwrap for system time it can failed
Milerius Oct 11, 2021
b36feb9
feat(bot): add support for custom price url default to KMD one
Milerius Oct 12, 2021
98d324e
feat(bot): add support for V2 endpoint and ticker groups
Milerius Oct 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion mm2src/coins/lp_coins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#[macro_use] extern crate ser_error_derive;

use async_trait::async_trait;
use bigdecimal::{BigDecimal, ParseBigDecimalError};
use bigdecimal::{BigDecimal, ParseBigDecimalError, Zero};
use common::executor::{spawn, Timer};
use common::mm_ctx::{from_ctx, MmArc, MmWeak};
use common::mm_error::prelude::*;
Expand Down Expand Up @@ -118,6 +118,7 @@ cfg_wasm32! {

pub type BalanceResult<T> = Result<T, MmError<BalanceError>>;
pub type BalanceFut<T> = Box<dyn Future<Item = T, Error = MmError<BalanceError>> + Send>;
pub type NonZeroBalanceFut<T> = Box<dyn Future<Item = T, Error = MmError<GetNonZeroBalance>> + Send>;
pub type NumConversResult<T> = Result<T, MmError<NumConversError>>;
pub type WithdrawResult = Result<TransactionDetails, MmError<WithdrawError>>;
pub type WithdrawFut = Box<dyn Future<Item = TransactionDetails, Error = MmError<WithdrawError>> + Send>;
Expand Down Expand Up @@ -331,6 +332,16 @@ pub trait MarketCoinOps {

fn my_address(&self) -> Result<String, String>;

fn get_non_zero_balance(&self) -> NonZeroBalanceFut<MmNumber> {
let closure = |spendable: BigDecimal| {
if spendable.is_zero() {
return MmError::err(GetNonZeroBalance::BalanceIsZero);
}
Ok(MmNumber::from(spendable))
};
Box::new(self.my_spendable_balance().map_err(From::from).and_then(closure))
}

fn my_balance(&self) -> BalanceFut<CoinBalance>;

fn my_spendable_balance(&self) -> BalanceFut<BigDecimal> {
Expand Down Expand Up @@ -684,6 +695,18 @@ pub enum BalanceError {
Internal(String),
}

#[derive(Debug, PartialEq, Display)]
pub enum GetNonZeroBalance {
#[display(fmt = "Internal error when retrieving balance - skipping")]
artemii235 marked this conversation as resolved.
Show resolved Hide resolved
MyBalanceError(BalanceError),
#[display(fmt = "Balance is zero - skipping")]
BalanceIsZero,
}

impl From<BalanceError> for GetNonZeroBalance {
fn from(e: BalanceError) -> Self { GetNonZeroBalance::MyBalanceError(e) }
}

impl From<NumConversError> for BalanceError {
fn from(e: NumConversError) -> Self { BalanceError::Internal(e.to_string()) }
}
Expand Down
2 changes: 2 additions & 0 deletions mm2src/common/mm_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub struct MmCtx {
pub stop_listeners: Mutex<Vec<StopListenerCallback>>,
/// The context belonging to the `ordermatch` mod: `OrdermatchContext`.
pub ordermatch_ctx: Mutex<Option<Arc<dyn Any + 'static + Send + Sync>>>,
pub simple_market_maker_bot_ctx: Mutex<Option<Arc<dyn Any + 'static + Send + Sync>>>,
pub p2p_ctx: Mutex<Option<Arc<dyn Any + 'static + Send + Sync>>>,
pub peer_id: Constructible<String>,
/// The context belonging to the `coins` crate: `CoinsContext`.
Expand Down Expand Up @@ -111,6 +112,7 @@ impl MmCtx {
ffi_handle: Constructible::default(),
stop_listeners: Mutex::new(Vec::new()),
ordermatch_ctx: Mutex::new(None),
simple_market_maker_bot_ctx: Mutex::new(None),
p2p_ctx: Mutex::new(None),
peer_id: Constructible::default(),
coins_ctx: Mutex::new(None),
Expand Down
168 changes: 133 additions & 35 deletions mm2src/lp_ordermatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ cfg_wasm32! {
}

#[path = "lp_ordermatch/best_orders.rs"] mod best_orders;
#[path = "lp_ordermatch/lp_bot.rs"] mod lp_bot;
pub use lp_bot::{process_price_request, start_simple_market_maker_bot, stop_simple_market_maker_bot,
StartSimpleMakerBotRequest};
#[path = "lp_ordermatch/my_orders_storage.rs"]
mod my_orders_storage;
#[path = "lp_ordermatch/new_protocol.rs"] mod new_protocol;
Expand Down Expand Up @@ -112,6 +115,18 @@ const TRIE_ORDER_HISTORY_TIMEOUT: u64 = 3;
type AlbOrderedOrderbookPair = String;
type PubkeyOrders = Vec<(Uuid, OrderbookP2PItem)>;

#[derive(Debug, Serialize, Deserialize)]
pub struct CancelAllOrdersResponse {
cancelled: Vec<Uuid>,
currently_matching: Vec<Uuid>,
}

#[derive(Debug, Deserialize, Display, Serialize, SerializeErrorType)]
#[serde(tag = "error_type", content = "error_data")]
pub enum CancelAllOrdersError {
LegacyError(String),
}

impl From<(new_protocol::MakerOrderCreated, String)> for OrderbookItem {
fn from(tuple: (new_protocol::MakerOrderCreated, String)) -> OrderbookItem {
let (order, pubkey) = tuple;
Expand Down Expand Up @@ -3577,7 +3592,7 @@ impl OrderbookItem {
fn get_true() -> bool { true }

#[derive(Deserialize)]
struct SetPriceReq {
pub struct SetPriceReq {
base: String,
rel: String,
price: MmNumber,
Expand All @@ -3597,7 +3612,7 @@ struct SetPriceReq {
}

#[derive(Deserialize)]
struct MakerOrderUpdateReq {
pub struct MakerOrderUpdateReq {
uuid: Uuid,
new_price: Option<MmNumber>,
max: Option<bool>,
Expand Down Expand Up @@ -3757,7 +3772,7 @@ impl<'a> From<&'a MakerOrder> for MakerOrderForRpc<'a> {
/// https://github.com/KomodoPlatform/atomicDEX-API/issues/794
async fn cancel_orders_on_error<T, E>(ctx: &MmArc, req: &SetPriceReq, error: E) -> Result<T, E> {
if req.cancel_previous {
let ordermatch_ctx = OrdermatchContext::from_ctx(&ctx).unwrap();
let ordermatch_ctx = OrdermatchContext::from_ctx(ctx).unwrap();
cancel_previous_maker_orders(ctx, &ordermatch_ctx, &req.base, &req.rel).await;
}
Err(error)
Expand All @@ -3780,53 +3795,51 @@ async fn get_max_volume(ctx: &MmArc, my_coin: &MmCoinEnum, other_coin: &MmCoinEn
))
}

pub async fn set_price(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, String> {
let req: SetPriceReq = try_s!(json::from_value(req));

let base_coin: MmCoinEnum = match try_s!(lp_coinfind(&ctx, &req.base).await) {
pub async fn create_maker_order(ctx: &MmArc, req: SetPriceReq) -> Result<MakerOrder, String> {
let base_coin: MmCoinEnum = match try_s!(lp_coinfind(ctx, &req.base).await) {
Some(coin) => coin,
None => return ERR!("Base coin {} is not found", req.base),
};

let rel_coin: MmCoinEnum = match try_s!(lp_coinfind(&ctx, &req.rel).await) {
let rel_coin: MmCoinEnum = match try_s!(lp_coinfind(ctx, &req.rel).await) {
Some(coin) => coin,
None => return ERR!("Rel coin {} is not found", req.rel),
};

if base_coin.wallet_only(&ctx) {
if base_coin.wallet_only(ctx) {
return ERR!("Base coin {} is wallet only", req.base);
}
if rel_coin.wallet_only(&ctx) {
if rel_coin.wallet_only(ctx) {
return ERR!("Rel coin {} is wallet only", req.rel);
}

let volume = if req.max {
try_s!(
get_max_volume(&ctx, &base_coin, &rel_coin)
.or_else(|e| cancel_orders_on_error(&ctx, &req, e))
get_max_volume(ctx, &base_coin, &rel_coin)
.or_else(|e| cancel_orders_on_error(ctx, &req, e))
.await
)
} else {
try_s!(
check_balance_for_maker_swap(
&ctx,
ctx,
&base_coin,
&rel_coin,
req.volume.clone(),
None,
None,
FeeApproxStage::OrderIssue
)
.or_else(|e| cancel_orders_on_error(&ctx, &req, e))
.or_else(|e| cancel_orders_on_error(ctx, &req, e))
.await
);
req.volume.clone()
};

let ordermatch_ctx = try_s!(OrdermatchContext::from_ctx(&ctx));
let ordermatch_ctx = try_s!(OrdermatchContext::from_ctx(ctx));

if req.cancel_previous {
cancel_previous_maker_orders(&ctx, &ordermatch_ctx, &req.base, &req.rel).await;
cancel_previous_maker_orders(ctx, &ordermatch_ctx, &req.base, &req.rel).await;
}

let conf_settings = OrderConfirmationsSettings {
Expand All @@ -3845,7 +3858,7 @@ pub async fn set_price(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, Strin
let new_order = try_s!(builder.build());

let request_orderbook = false;
try_s!(subscribe_to_orderbook_topic(&ctx, &new_order.base, &new_order.rel, request_orderbook).await);
try_s!(subscribe_to_orderbook_topic(ctx, &new_order.base, &new_order.rel, request_orderbook).await);
save_my_new_maker_order(ctx.clone(), &new_order).await;
maker_order_created_p2p_notify(
ctx.clone(),
Expand All @@ -3854,12 +3867,17 @@ pub async fn set_price(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, Strin
rel_coin.coin_protocol_info(),
)
.await;
let rpc_result = MakerOrderForRpc::from(&new_order);
let res = try_s!(json::to_vec(&json!({ "result": rpc_result })));

let mut my_orders = ordermatch_ctx.my_maker_orders.lock().await;
my_orders.insert(new_order.uuid, new_order);
my_orders.insert(new_order.uuid, new_order.clone());
Ok(new_order)
artemii235 marked this conversation as resolved.
Show resolved Hide resolved
}

pub async fn set_price(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, String> {
let req: SetPriceReq = try_s!(json::from_value(req));
let maker_order = create_maker_order(&ctx, req).await?;
let rpc_result = MakerOrderForRpc::from(&maker_order);
let res = try_s!(json::to_vec(&json!({ "result": rpc_result })));
Ok(try_s!(Response::builder().body(res)))
}

Expand Down Expand Up @@ -3898,10 +3916,8 @@ async fn cancel_previous_maker_orders(
*my_maker_orders = my_actual_maker_orders;
}

pub async fn update_maker_order(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, String> {
let req: MakerOrderUpdateReq = try_s!(json::from_value(req));

let ordermatch_ctx = try_s!(OrdermatchContext::from_ctx(&ctx));
pub async fn update_maker_order(ctx: &MmArc, req: MakerOrderUpdateReq) -> Result<MakerOrder, String> {
let ordermatch_ctx = try_s!(OrdermatchContext::from_ctx(ctx));
let my_maker_orders = ordermatch_ctx.my_maker_orders.lock().await;

let (base_coin, rel_coin, original_price, original_volume, updated_conf_settings, matches, reserved_amount) =
Expand All @@ -3911,13 +3927,13 @@ pub async fn update_maker_order(ctx: MmArc, req: Json) -> Result<Response<Vec<u8
return ERR!("Can't update an order that has ongoing matches");
}
let base = order.base.as_str();
let base_coin: MmCoinEnum = match try_s!(lp_coinfind(&ctx, base).await) {
let base_coin: MmCoinEnum = match try_s!(lp_coinfind(ctx, base).await) {
Some(coin) => coin,
None => return ERR!("Base coin {} has been removed from config", base),
};

let rel = order.rel.as_str();
let rel_coin: MmCoinEnum = match try_s!(lp_coinfind(&ctx, rel).await) {
let rel_coin: MmCoinEnum = match try_s!(lp_coinfind(ctx, rel).await) {
Some(coin) => coin,
None => return ERR!("Rel coin {} has been removed from config", rel),
};
Expand Down Expand Up @@ -3976,7 +3992,7 @@ pub async fn update_maker_order(ctx: MmArc, req: Json) -> Result<Response<Vec<u8

// Calculate order volume and add to update_msg if new_volume is found in the request
let new_volume = if req.max.unwrap_or(false) {
let max_volume = try_s!(get_max_volume(&ctx, &base_coin, &rel_coin).await) + reserved_amount.clone();
let max_volume = try_s!(get_max_volume(ctx, &base_coin, &rel_coin).await) + reserved_amount.clone();
update_msg.with_new_max_volume(max_volume.clone().into());
max_volume
} else if Option::is_some(&req.volume_delta) {
Expand All @@ -3986,7 +4002,7 @@ pub async fn update_maker_order(ctx: MmArc, req: Json) -> Result<Response<Vec<u8
}
try_s!(
check_balance_for_maker_swap(
&ctx,
ctx,
&base_coin,
&rel_coin,
volume.clone(),
Expand Down Expand Up @@ -4020,7 +4036,7 @@ pub async fn update_maker_order(ctx: MmArc, req: Json) -> Result<Response<Vec<u8
));

let mut my_maker_orders = ordermatch_ctx.my_maker_orders.lock().await;
let (rpc_result, base, rel) = match my_maker_orders.get_mut(&req.uuid) {
match my_maker_orders.get_mut(&req.uuid) {
None => return ERR!("Order with UUID: {} has been deleted", req.uuid),
Some(order) => {
if order.matches.len() != matches.len() || !order.matches.keys().all(|k| matches.contains_key(k)) {
Expand All @@ -4031,11 +4047,17 @@ pub async fn update_maker_order(ctx: MmArc, req: Json) -> Result<Response<Vec<u8
order.apply_updated(&update_msg);
save_maker_order_on_update(ctx.clone(), order, new_change).await;
update_msg.with_new_max_volume((new_volume - reserved_amount).into());
(MakerOrderForRpc::from(&*order), order.base.as_str(), order.rel.as_str())
maker_order_updated_p2p_notify(ctx.clone(), order.base.as_str(), order.rel.as_str(), update_msg).await;
Ok(order.clone())
},
};
}
}

pub async fn update_maker_order_rpc(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, String> {
let req: MakerOrderUpdateReq = try_s!(json::from_value(req));
let order = try_s!(update_maker_order(&ctx, req).await);
let rpc_result = MakerOrderForRpc::from(&order);
let res = try_s!(json::to_vec(&json!({ "result": rpc_result })));
maker_order_updated_p2p_notify(ctx.clone(), base, rel, update_msg).await;

Ok(try_s!(Response::builder().body(res)))
}
Expand Down Expand Up @@ -4258,11 +4280,73 @@ pub async fn orders_history_by_filter(ctx: MmArc, req: Json) -> Result<Response<
}

#[derive(Deserialize)]
struct CancelOrderReq {
pub struct CancelOrderReq {
uuid: Uuid,
}

pub async fn cancel_order(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, String> {
#[derive(Debug, Deserialize, Serialize, SerializeErrorType, Display)]
#[serde(tag = "error_type", content = "error_data")]
pub enum CancelOrderError {
#[display(fmt = "Cannot retrieve order match context.")]
CannotRetrieveOrderMatchContext,
#[display(fmt = "Order {} is being matched now, can't cancel", uuid)]
OrderBeingMatched { uuid: Uuid },
#[display(fmt = "Order {} not found", uuid)]
UUIDNotFound { uuid: Uuid },
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CancelOrderResponse {
result: String,
}

pub async fn cancel_order(ctx: MmArc, req: CancelOrderReq) -> Result<CancelOrderResponse, MmError<CancelOrderError>> {
let ordermatch_ctx = match OrdermatchContext::from_ctx(&ctx) {
Ok(x) => x,
Err(_) => return Err(MmError::new(CancelOrderError::CannotRetrieveOrderMatchContext)),
artemii235 marked this conversation as resolved.
Show resolved Hide resolved
};
let mut maker_orders = ordermatch_ctx.my_maker_orders.lock().await;
match maker_orders.entry(req.uuid) {
Entry::Occupied(order) => {
if !order.get().is_cancellable() {
return MmError::err(CancelOrderError::OrderBeingMatched { uuid: req.uuid });
}
let order = order.remove();
maker_order_cancelled_p2p_notify(ctx.clone(), &order).await;
delete_my_maker_order(ctx, order, MakerOrderCancellationReason::Cancelled)
.compat()
.await
.ok();
return Ok(CancelOrderResponse {
result: "success".to_string(),
});
},
// look for taker order with provided uuid
Entry::Vacant(_) => (),
}

let mut taker_orders = ordermatch_ctx.my_taker_orders.lock().await;
match taker_orders.entry(req.uuid) {
Entry::Occupied(order) => {
if !order.get().is_cancellable() {
return MmError::err(CancelOrderError::UUIDNotFound { uuid: req.uuid });
}
let order = order.remove();
delete_my_taker_order(ctx, order, TakerOrderCancellationReason::Cancelled)
.compat()
.await
.ok();
return Ok(CancelOrderResponse {
result: "success".to_string(),
});
},
// error is returned
Entry::Vacant(_) => (),
}
MmError::err(CancelOrderError::UUIDNotFound { uuid: req.uuid })
}

pub async fn cancel_order_rpc(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, String> {
let req: CancelOrderReq = try_s!(json::from_value(req));

let ordermatch_ctx = try_s!(OrdermatchContext::from_ctx(&ctx));
Expand Down Expand Up @@ -4609,7 +4693,21 @@ pub async fn cancel_orders_by(ctx: &MmArc, cancel_by: CancelBy) -> Result<(Vec<U
Ok((cancelled, currently_matching))
}

pub async fn cancel_all_orders(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, String> {
pub async fn cancel_all_orders(
ctx: MmArc,
cancel_by: CancelBy,
) -> Result<CancelAllOrdersResponse, MmError<CancelAllOrdersError>> {
let (cancelled, currently_matching) = match cancel_orders_by(&ctx, cancel_by).await {
artemii235 marked this conversation as resolved.
Show resolved Hide resolved
Ok(x) => x,
Err(err) => return Err(MmError::new(CancelAllOrdersError::LegacyError(err))),
};
Ok(CancelAllOrdersResponse {
cancelled,
currently_matching,
})
}

pub async fn cancel_all_orders_rpc(ctx: MmArc, req: Json) -> Result<Response<Vec<u8>>, String> {
let cancel_by: CancelBy = try_s!(json::from_value(req["cancel_by"].clone()));

let (cancelled, currently_matching) = try_s!(cancel_orders_by(&ctx, cancel_by).await);
Expand Down
Loading