Skip to content

Commit

Permalink
add stop/kickstart swap rpcs
Browse files Browse the repository at this point in the history
  • Loading branch information
mariocynicys committed Dec 6, 2024
1 parent 19b0de2 commit 10e4192
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 3 deletions.
173 changes: 171 additions & 2 deletions mm2src/mm2_main/src/lp_swap/swap_v2_rpcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ use super::maker_swap_v2::MakerSwapEvent;
use super::my_swaps_storage::{MySwapsError, MySwapsOps, MySwapsStorage};
use super::taker_swap::TakerSavedSwap;
use super::taker_swap_v2::TakerSwapEvent;
use super::{active_swaps, MySwapsFilter, SavedSwap, SavedSwapError, SavedSwapIo, LEGACY_SWAP_TYPE, MAKER_SWAP_V2_TYPE,
use super::{active_swaps, run_maker_swap, run_taker_swap, MySwapsFilter, RunMakerSwapInput, RunTakerSwapInput,
SavedSwap, SavedSwapError, SavedSwapIo, SwapsContext, LEGACY_SWAP_TYPE, MAKER_SWAP_V2_TYPE,
TAKER_SWAP_V2_TYPE};
use coins::lp_coinfind;
use common::executor::SpawnFuture;
use common::log::{error, warn};
use common::{calc_total_pages, HttpStatusCode, PagingOptions};
use derive_more::Display;
Expand All @@ -26,7 +29,6 @@ cfg_native!(
);

cfg_wasm32!(
use super::SwapsContext;
use super::maker_swap_v2::MakerSwapDbRepr;
use super::taker_swap_v2::TakerSwapDbRepr;
use crate::lp_swap::swap_wasm_db::{MySwapsFiltersTable, SavedSwapTable};
Expand Down Expand Up @@ -501,3 +503,170 @@ pub(crate) async fn active_swaps_rpc(
statuses,
})
}

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

#[derive(Display, Serialize, SerializeErrorType)]
#[serde(tag = "error_type", content = "error_data")]
pub(crate) enum StopSwapErr {
Internal(String),
NotRunning,
}

impl HttpStatusCode for StopSwapErr {
fn status_code(&self) -> StatusCode {
match self {
StopSwapErr::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
StopSwapErr::NotRunning => StatusCode::BAD_REQUEST,
}
}
}

#[derive(Serialize)]
pub(crate) struct StopSwapResponse {
result: String,
}

pub(crate) async fn stop_swap_rpc(ctx: MmArc, req: StopSwapRequest) -> MmResult<StopSwapResponse, StopSwapErr> {
let swap_ctx = SwapsContext::from_ctx(&ctx).map_err(StopSwapErr::Internal)?;
let mut running_swaps = swap_ctx.running_swaps.lock().unwrap();
let Some(position) = running_swaps.iter().position(|(swap, _)| swap.upgrade().map_or(true, |swap| swap.uuid() == &req.uuid)) else {
return MmError::err(StopSwapErr::NotRunning);
};
let (_swap, _abort_handle) = running_swaps.swap_remove(position);
Ok(StopSwapResponse {
result: "Success".to_string(),
})
}

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

#[derive(Display, Serialize, SerializeErrorType)]
#[serde(tag = "error_type", content = "error_data")]
pub(crate) enum KickStartSwapErr {
Internal(String),
AlreadyRunning,
AlreadyFinished,
NeedsCoinActivation(String),
NotFound,
}

impl HttpStatusCode for KickStartSwapErr {
fn status_code(&self) -> StatusCode {
match self {
KickStartSwapErr::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
KickStartSwapErr::AlreadyRunning
| KickStartSwapErr::AlreadyFinished
| KickStartSwapErr::NeedsCoinActivation(_) => StatusCode::BAD_REQUEST,
KickStartSwapErr::NotFound => StatusCode::NOT_FOUND,
}
}
}

#[derive(Serialize)]
pub(crate) struct KickStartSwapResponse {
result: String,
}

pub(crate) async fn kickstart_swap_rpc(
ctx: MmArc,
req: KickStartSwapRequest,
) -> MmResult<KickStartSwapResponse, KickStartSwapErr> {
// Make sure first that the swap isn't already running. Note that this is not atomic and we might still end
// up with the same swap being kickstarted twice, but we have filesystem swap locks for that. This check is
// rather for convenience.
let swap_ctx = SwapsContext::from_ctx(&ctx).map_err(KickStartSwapErr::Internal)?;
for (swap, _) in swap_ctx.running_swaps.lock().unwrap().iter() {
if let Some(swap) = swap.upgrade() {
if swap.uuid() == &req.uuid {
return MmError::err(KickStartSwapErr::AlreadyRunning);
}
}
}
// Load the swap from the DB.
let swap = match SavedSwap::load_my_swap_from_db(&ctx, req.uuid).await {
Ok(Some(s)) => s,
Ok(None) => {
return MmError::err(KickStartSwapErr::NotFound);
},
Err(e) => {
return MmError::err(KickStartSwapErr::Internal(format!(
"Error getting the swap from the DB: {e}"
)))
},
};
// Make sure that the swap isn't finished.
if swap.is_finished() {
return MmError::err(KickStartSwapErr::AlreadyFinished);
}
let maker_coin = match swap.maker_coin_ticker() {
Ok(coin) => match lp_coinfind(&ctx, &coin).await {
Ok(Some(coin)) => coin,
Ok(None) => {
return MmError::err(KickStartSwapErr::NeedsCoinActivation(format!(
"Maker coin {} must be activated",
coin
)));
},
Err(e) => {
return MmError::err(KickStartSwapErr::Internal(format!(
"Error trying to find maker coin: {e}"
)))
},
},
Err(e) => {
return MmError::err(KickStartSwapErr::Internal(format!(
"Error getting maker ticker of swap: {e}"
)));
},
};
let taker_coin = match swap.taker_coin_ticker() {
Ok(coin) => match lp_coinfind(&ctx, &coin).await {
Ok(Some(coin)) => coin,
Ok(None) => {
return MmError::err(KickStartSwapErr::NeedsCoinActivation(format!(
"Taker coin {} must be activated",
coin
)));
},
Err(e) => {
return MmError::err(KickStartSwapErr::Internal(format!(
"Error trying to find taker coin: {e}"
)))
},
},
Err(e) => {
return MmError::err(KickStartSwapErr::Internal(format!(
"Error getting taker ticker of swap: {e}"
)));
},
};
// Kickstart the swap. A new aborthandle will show up shortly for the swap.
match swap {
SavedSwap::Maker(saved_swap) => ctx.spawner().spawn(run_maker_swap(
RunMakerSwapInput::KickStart {
maker_coin,
taker_coin,
swap_uuid: saved_swap.uuid,
},
ctx,
)),
SavedSwap::Taker(saved_swap) => ctx.spawner().spawn(run_taker_swap(
RunTakerSwapInput::KickStart {
maker_coin,
taker_coin,
swap_uuid: saved_swap.uuid,
},
ctx,
)),
}
Ok(KickStartSwapResponse {
result: "Success".to_string(),
})
}
5 changes: 4 additions & 1 deletion mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use crate::lp_ordermatch::{best_orders_rpc_v2, orderbook_rpc_v2, start_simple_ma
stop_simple_market_maker_bot};
use crate::lp_stats::{add_node_to_version_stat, remove_node_from_version_stat, start_version_stat_collection,
stop_version_stat_collection, update_version_stat_collection};
use crate::lp_swap::swap_v2_rpcs::{active_swaps_rpc, my_recent_swaps_rpc, my_swap_status_rpc};
use crate::lp_swap::swap_v2_rpcs::{active_swaps_rpc, kickstart_swap_rpc, my_recent_swaps_rpc, my_swap_status_rpc,
stop_swap_rpc};
use crate::lp_swap::{get_locked_amount_rpc, max_maker_vol, recreate_swap_data, trade_preimage_rpc};
use crate::lp_wallet::{get_mnemonic_rpc, get_wallet_names_rpc};
use crate::rpc::lp_commands::db_id::get_shared_db_id;
Expand Down Expand Up @@ -192,6 +193,8 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult<Re
"max_maker_vol" => handle_mmrpc(ctx, request, max_maker_vol).await,
"my_recent_swaps" => handle_mmrpc(ctx, request, my_recent_swaps_rpc).await,
"my_swap_status" => handle_mmrpc(ctx, request, my_swap_status_rpc).await,
"stop_swap" => handle_mmrpc(ctx, request, stop_swap_rpc).await,
"kickstart_swap" => handle_mmrpc(ctx, request, kickstart_swap_rpc).await,
"my_tx_history" => handle_mmrpc(ctx, request, my_tx_history_v2_rpc).await,
"orderbook" => handle_mmrpc(ctx, request, orderbook_rpc_v2).await,
"recreate_swap_data" => handle_mmrpc(ctx, request, recreate_swap_data).await,
Expand Down

0 comments on commit 10e4192

Please sign in to comment.