diff --git a/binaries/src/bin/websocket_server.rs b/binaries/src/bin/websocket_server.rs index 09a605f7..8a05131d 100644 --- a/binaries/src/bin/websocket_server.rs +++ b/binaries/src/bin/websocket_server.rs @@ -15,6 +15,13 @@ struct Args { #[arg(long)] port: u16, + /// Enable to include orders from spot markets. This is "unsafe" because order statuses for new + /// orders from special addresses (e.g. the assistance fund and HIP-2) are not emitted so we + /// **unsafely** assume that these orders are all "Alo" limit orders. Default is false, meaning + /// that spot orders are ignored. + #[arg(long)] + include_spot_unsafe: Option, // Default is false + /// Compression level for WebSocket connections. /// Accepts values in the range `0..=9`. /// * `0` – compression disabled. @@ -36,8 +43,10 @@ async fn main() -> Result<()> { let full_address = format!("{}:{}", args.address, args.port); println!("Running websocket server on {full_address}"); + let ignore_spot = !args.include_spot_unsafe.unwrap_or(false); + let compression_level = args.websocket_compression_level.unwrap_or(/* Some compression */ 1); - run_websocket_server(&full_address, true, compression_level).await?; + run_websocket_server(&full_address, ignore_spot, compression_level).await?; Ok(()) } diff --git a/server/src/listeners/order_book/state.rs b/server/src/listeners/order_book/state.rs index 3fb74ae2..07bbb127 100644 --- a/server/src/listeners/order_book/state.rs +++ b/server/src/listeners/order_book/state.rs @@ -1,7 +1,7 @@ use crate::{ listeners::order_book::{L2Snapshots, TimedSnapshots, utils::compute_l2_snapshots}, order_book::{ - Coin, InnerOrder, Oid, + Coin, InnerOrder, Oid, Px, multi_book::{OrderBooks, Snapshots}, }, prelude::*, @@ -104,6 +104,26 @@ impl OrderBookState { #[allow(clippy::unwrap_used)] inner_order.convert_trigger(time.try_into().unwrap()); self.order_book.add_order(inner_order); + } else if diff.special_address() { + // Assume all orders from special addresses are Alo, Limit orders + let inner_order = InnerL4Order { + user: diff.user(), + coin, + side: diff.side(), + limit_px: Px::parse_from_str(diff.px().as_str())?, + sz, + oid: oid.value(), + timestamp: time, + trigger_condition: "N/A".to_string(), + is_trigger: false, + trigger_px: "0.0".to_string(), + is_position_tpsl: false, + reduce_only: false, + order_type: "Limit".to_string(), + tif: Some("Alo".to_string()), + cloid: None, + }; + self.order_book.add_order(inner_order); } else { return Err(format!("Unable to find order opening status {diff:?}").into()); } diff --git a/server/src/order_book/types.rs b/server/src/order_book/types.rs index 447eb3f5..15c4b70f 100644 --- a/server/src/order_book/types.rs +++ b/server/src/order_book/types.rs @@ -54,6 +54,9 @@ impl Oid { pub(crate) const fn new(value: u64) -> Self { Self(value) } + pub(crate) const fn value(self) -> u64 { + self.0 + } } pub(crate) trait InnerOrder: Clone { diff --git a/server/src/types/node_data.rs b/server/src/types/node_data.rs index acb6ed22..99590003 100644 --- a/server/src/types/node_data.rs +++ b/server/src/types/node_data.rs @@ -5,14 +5,18 @@ use chrono::NaiveDateTime; use serde::{Deserialize, Serialize}; use crate::{ - order_book::{Coin, Oid}, + order_book::{Coin, Oid, Side}, types::{Fill, L4Order, OrderDiff}, }; +const ASSISTANCE_FUND: Address = Address::repeat_byte(0xFE); +const HIP_2: Address = Address::repeat_byte(0xFF); + #[derive(Debug, Clone, Serialize, Deserialize)] pub(crate) struct NodeDataOrderDiff { user: Address, oid: u64, + side: Side, px: String, coin: String, pub(crate) raw_book_diff: OrderDiff, @@ -29,6 +33,18 @@ impl NodeDataOrderDiff { pub(crate) fn coin(&self) -> Coin { Coin::new(&self.coin) } + pub(crate) fn user(&self) -> Address { + self.user + } + pub(crate) fn side(&self) -> Side { + self.side + } + pub(crate) fn px(&self) -> String { + self.px.clone() + } + pub(crate) fn special_address(&self) -> bool { + self.user == ASSISTANCE_FUND || self.user == HIP_2 + } } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/server/src/types/subscription.rs b/server/src/types/subscription.rs index 64dbd548..2c5f20c8 100644 --- a/server/src/types/subscription.rs +++ b/server/src/types/subscription.rs @@ -31,7 +31,7 @@ impl Subscription { match self { Self::Trades { coin } => universe.contains(coin), Self::L2Book { coin, n_sig_figs, n_levels, mantissa } => { - if !universe.contains(coin) || coin.starts_with('@') { + if !universe.contains(coin) { info!("Invalid subscription: coin not found"); return false; } @@ -62,7 +62,7 @@ impl Subscription { true } Self::L4Book { coin } => { - if !universe.contains(coin) || coin.starts_with('@') { + if !universe.contains(coin) { info!("Invalid subscription: coin not found"); return false; }