From 9fc8c58db56983e1eb7bed6b9d166989fed6874f Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Mon, 18 Sep 2023 18:42:48 +0100 Subject: [PATCH] More --- .../exchange_bot/impl/src/commands/quote.rs | 49 +++++++------------ .../impl/src/commands/withdraw.rs | 12 ++--- .../canisters/exchange_bot/impl/src/lib.rs | 4 ++ .../impl/src/model/commands_pending.rs | 11 +++-- .../impl/src/model/messages_pending.rs | 4 ++ 5 files changed, 38 insertions(+), 42 deletions(-) diff --git a/backend/canisters/exchange_bot/impl/src/commands/quote.rs b/backend/canisters/exchange_bot/impl/src/commands/quote.rs index 0564e4985c..fadce7cc31 100644 --- a/backend/canisters/exchange_bot/impl/src/commands/quote.rs +++ b/backend/canisters/exchange_bot/impl/src/commands/quote.rs @@ -1,15 +1,13 @@ use crate::commands::common_errors::CommonErrors; -use crate::commands::{build_error_response, Command, CommandParser, ParseMessageResult}; +use crate::commands::{build_error_response, Command, CommandParser, CommandSubTaskResult, ParseMessageResult}; use crate::swap_client::SwapClient; use crate::{mutate_state, RuntimeState}; use exchange_bot_canister::ExchangeId; -use itertools::Itertools; use lazy_static::lazy_static; use ledger_utils::format_crypto_amount; use rand::Rng; use regex::{Regex, RegexBuilder}; use serde::{Deserialize, Serialize}; -use std::fmt::{Display, Formatter}; use std::str::FromStr; use std::sync::{Arc, Mutex}; use types::{MessageContent, MessageId, TimestampMillis, TokenInfo, UserId}; @@ -74,24 +72,7 @@ pub struct QuoteCommand { pub amount: u128, pub exchange_ids: Vec, pub message_id: MessageId, - pub quote_statuses: Vec<(ExchangeId, QuoteStatus)>, -} - -#[derive(Serialize, Deserialize, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] -pub enum QuoteStatus { - Success(u128, String), - Failed(String), - Pending, -} - -impl Display for QuoteStatus { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - QuoteStatus::Success(_, text) => f.write_str(text), - QuoteStatus::Failed(_) => f.write_str("Failed"), - QuoteStatus::Pending => f.write_str("Pending"), - } - } + pub quote_statuses: Vec<(ExchangeId, CommandSubTaskResult)>, } impl QuoteCommand { @@ -104,7 +85,10 @@ impl QuoteCommand { let clients = state.get_all_swap_clients(input_token.clone(), output_token.clone()); if !clients.is_empty() { - let quote_statuses = clients.iter().map(|c| (c.exchange_id(), QuoteStatus::Pending)).collect(); + let quote_statuses = clients + .iter() + .map(|c| (c.exchange_id(), CommandSubTaskResult::Pending)) + .collect(); Ok(QuoteCommand { created: state.env.now(), @@ -148,7 +132,7 @@ impl QuoteCommand { self.input_token.token.token_symbol(), self.output_token.token.token_symbol() ); - for (exchange_id, status) in self.quote_statuses.iter().sorted_unstable_by_key(|(_, s)| s) { + for (exchange_id, status) in self.quote_statuses.iter() { let exchange_name = exchange_id.to_string(); let status_text = status.to_string(); text.push_str(&format!("\n{exchange_name}: {status_text}")); @@ -156,27 +140,30 @@ impl QuoteCommand { text } - fn set_status(&mut self, exchange_id: ExchangeId, new_status: QuoteStatus) { - if let Some(status) = self + fn set_quote_result(&mut self, exchange_id: ExchangeId, result: CommandSubTaskResult) { + if let Some(r) = self .quote_statuses .iter_mut() .find(|(e, _)| *e == exchange_id) .map(|(_, s)| s) { - *status = new_status; + *r = result; } } } async fn quote_single(amount: u128, client: Box, wrapped_command: Arc>) { - let result = client.quote(amount).await; + let response = client.quote(amount).await; let mut command = wrapped_command.lock().unwrap(); - let status = match result { - Ok(amount_out) => QuoteStatus::Success(amount_out, format_crypto_amount(amount_out, command.output_token.decimals)), - Err(error) => QuoteStatus::Failed(format!("{error:?}")), + let result = match response { + Ok(amount_out) => CommandSubTaskResult::Complete( + amount_out, + Some(format_crypto_amount(amount_out, command.output_token.decimals)), + ), + Err(error) => CommandSubTaskResult::Failed(format!("{error:?}")), }; - command.set_status(client.exchange_id(), status); + command.set_quote_result(client.exchange_id(), result); let message_text = command.build_message_text(); diff --git a/backend/canisters/exchange_bot/impl/src/commands/withdraw.rs b/backend/canisters/exchange_bot/impl/src/commands/withdraw.rs index c9dd25f177..6701040ca4 100644 --- a/backend/canisters/exchange_bot/impl/src/commands/withdraw.rs +++ b/backend/canisters/exchange_bot/impl/src/commands/withdraw.rs @@ -141,14 +141,10 @@ impl WithdrawCommand { } async fn withdraw(mut self, amount: u128, now_nanos: TimestampNanos) { - self.sub_tasks.withdraw = if amount <= self.token.fee { - CommandSubTaskResult::NotRequired - } else { - match transfer_to_user(self.user_id, &self.token, amount, now_nanos).await { - Ok(Ok(block_index)) => CommandSubTaskResult::Complete(block_index, None), - Ok(Err(error)) => CommandSubTaskResult::Failed(format!("{error:?}")), - Err(error) => CommandSubTaskResult::Failed(format!("{error:?}")), - } + self.sub_tasks.withdraw = match transfer_to_user(self.user_id, &self.token, amount, now_nanos).await { + Ok(Ok(block_index)) => CommandSubTaskResult::Complete(block_index, None), + Ok(Err(error)) => CommandSubTaskResult::Failed(format!("{error:?}")), + Err(error) => CommandSubTaskResult::Failed(format!("{error:?}")), }; mutate_state(|state| self.on_updated(state)); } diff --git a/backend/canisters/exchange_bot/impl/src/lib.rs b/backend/canisters/exchange_bot/impl/src/lib.rs index 2e8746e104..4d280d9736 100644 --- a/backend/canisters/exchange_bot/impl/src/lib.rs +++ b/backend/canisters/exchange_bot/impl/src/lib.rs @@ -106,6 +106,8 @@ impl RuntimeState { wasm_version: WASM_VERSION.with(|v| **v.borrow()), git_commit_id: utils::git::git_commit_id().to_string(), governance_principals: self.data.governance_principals.iter().copied().collect(), + queued_commands: self.data.commands_pending.len() as u32, + queued_messages: self.data.messages_pending.len() as u32, canister_ids: CanisterIds { local_user_index: self.data.local_user_index_canister_id, cycles_dispenser: self.data.cycles_dispenser_canister_id, @@ -233,6 +235,8 @@ pub struct Metrics { pub wasm_version: BuildVersion, pub git_commit_id: String, pub governance_principals: Vec, + pub queued_commands: u32, + pub queued_messages: u32, pub canister_ids: CanisterIds, } diff --git a/backend/canisters/exchange_bot/impl/src/model/commands_pending.rs b/backend/canisters/exchange_bot/impl/src/model/commands_pending.rs index e536f1b0ed..36b7016e35 100644 --- a/backend/canisters/exchange_bot/impl/src/model/commands_pending.rs +++ b/backend/canisters/exchange_bot/impl/src/model/commands_pending.rs @@ -1,18 +1,23 @@ use crate::commands::Command; use serde::{Deserialize, Serialize}; +use std::collections::VecDeque; #[derive(Serialize, Deserialize, Default)] pub struct CommandsPending { - commands: Vec, + commands: VecDeque, } impl CommandsPending { pub fn push(&mut self, command: Command) { - self.commands.push(command); + self.commands.push_back(command); } pub fn pop(&mut self) -> Option { - self.commands.pop() + self.commands.pop_front() + } + + pub fn len(&self) -> usize { + self.commands.len() } pub fn is_empty(&self) -> bool { diff --git a/backend/canisters/exchange_bot/impl/src/model/messages_pending.rs b/backend/canisters/exchange_bot/impl/src/model/messages_pending.rs index da0351b2bf..28c1049bed 100644 --- a/backend/canisters/exchange_bot/impl/src/model/messages_pending.rs +++ b/backend/canisters/exchange_bot/impl/src/model/messages_pending.rs @@ -26,6 +26,10 @@ impl MessagesPending { self.messages.contains_key(&(user_id, message_id)) } + pub fn len(&self) -> usize { + self.messages.len() + } + pub fn is_empty(&self) -> bool { self.messages.is_empty() }