Skip to main content

hypercall/
engine_enums_ext.rs

1//! Extension methods for `hypercall_db_diesel::engine_enums` types that
2//! depend on root-crate types (`EngineMessage`, `EngineCommand`, `shared::topics`).
3//!
4//! These were stripped from the extracted `hypercall-db-diesel` crate to break
5//! the circular dependency; they live here as an extension trait instead.
6
7use crate::rsm::apply::EngineCommand;
8use crate::shared::topics;
9use hypercall_db_diesel::engine_enums::{CommandType, EventType};
10use hypercall_types::{EngineMessage, MarketAction, OrderAction};
11
12pub trait CommandTypeExt {
13    fn from_command(cmd: &EngineCommand) -> CommandType;
14}
15
16impl CommandTypeExt for CommandType {
17    fn from_command(cmd: &EngineCommand) -> CommandType {
18        match cmd {
19            EngineCommand::OrderAction(m) => match m.action {
20                OrderAction::CreateOrder => CommandType::CreateOrder,
21                OrderAction::CancelOrder => CommandType::CancelOrder,
22                OrderAction::ReplaceOrder => CommandType::ReplaceOrder,
23            },
24            EngineCommand::MarketAction(m) => match m.message.action {
25                MarketAction::CreateMarket => CommandType::CreateMarket,
26                MarketAction::DeleteMarket => CommandType::DeleteMarket,
27                MarketAction::ExpireMarket => CommandType::ExpireMarket,
28            },
29            EngineCommand::LiquidationState(_) => CommandType::LiquidationState,
30            EngineCommand::TickExpiry { .. } => CommandType::TickExpiry,
31            EngineCommand::TickSnapshot { .. } => CommandType::TickSnapshot,
32            EngineCommand::PriceUpdate { .. } => CommandType::PriceUpdate,
33            EngineCommand::IvUpdate { .. } => CommandType::IvUpdate,
34            EngineCommand::TierUpdate { .. } => CommandType::TierUpdate,
35            EngineCommand::LegacyTierMarginModeUpdate { .. } => CommandType::TierUpdate,
36            EngineCommand::HypercorePositionUpdate { .. } => CommandType::HypercorePositionUpdate,
37            EngineCommand::MmpConfigUpdate { .. } => CommandType::MmpConfigUpdate,
38            EngineCommand::RfqExecute(_) => CommandType::RfqExecute,
39            EngineCommand::TradingModeUpdate { .. } => CommandType::TradingModeUpdate,
40            EngineCommand::DepositUpdate { .. } => CommandType::DepositUpdate,
41            EngineCommand::LiquidationBonusUpdate { .. } => CommandType::LiquidationBonusUpdate,
42            EngineCommand::ApproveAgent { .. } => CommandType::ApproveAgent,
43            EngineCommand::RevokeAgent { .. } => CommandType::RevokeAgent,
44            EngineCommand::NonceAdvance { .. } => CommandType::NonceAdvance,
45            EngineCommand::HypercoreEquityUpdate { .. } => CommandType::HypercoreEquityUpdate,
46            EngineCommand::OptionDepositUpdate { .. } => CommandType::OptionDepositUpdate,
47            EngineCommand::OptionWithdrawalUpdate { .. } => CommandType::OptionWithdrawalUpdate,
48            EngineCommand::CashWithdrawalUpdate { .. } => CommandType::CashWithdrawalUpdate,
49            EngineCommand::SetPmSettlementPoolConfig(_) => CommandType::SetPmSettlementPoolConfig,
50            EngineCommand::RecordPmVaultDeposit(_) => CommandType::RecordPmVaultDeposit,
51            EngineCommand::RequestPmVaultWithdrawal(_) => CommandType::RequestPmVaultWithdrawal,
52            EngineCommand::AccruePmSettlementInterest(_) => CommandType::AccruePmSettlementInterest,
53            EngineCommand::ApplyPmSettlementRepayment(_) => CommandType::ApplyPmSettlementRepayment,
54            EngineCommand::JournalPmRecoveryPlan(_) => CommandType::JournalPmRecoveryPlan,
55            EngineCommand::MarkPmRecoveryActionSubmitted(_) => {
56                CommandType::MarkPmRecoveryActionSubmitted
57            }
58            EngineCommand::ResolvePmRecoveryAction(_) => CommandType::ResolvePmRecoveryAction,
59        }
60    }
61}
62
63pub trait EventTypeExt {
64    /// Derive from an `EngineMessage` variant.
65    fn from_engine_message(msg: &EngineMessage) -> EventType;
66    /// Derive the event topic string for this event type.
67    fn topic(&self) -> &'static str;
68}
69
70impl EventTypeExt for EventType {
71    fn from_engine_message(msg: &EngineMessage) -> EventType {
72        match msg {
73            EngineMessage::OrderAction(_) => EventType::OrderAction,
74            EngineMessage::OrderUpdate(_) => EventType::OrderUpdate,
75            EngineMessage::OrderInfo(_) => EventType::OrderInfo,
76            EngineMessage::MarketAction(_) => EventType::MarketAction,
77            EngineMessage::MarketUpdate(_) => EventType::MarketUpdate,
78            EngineMessage::OrderFilled { .. } => EventType::OrderFilled,
79            EngineMessage::OrderbookUpdated(_) => EventType::OrderbookUpdated,
80            EngineMessage::L2Update(_) => EventType::L2Update,
81            EngineMessage::Trade(_) => EventType::Trade,
82            EngineMessage::TransactionRequest(_) => EventType::TransactionRequest,
83            EngineMessage::TransactionUpdate(_) => EventType::TransactionUpdate,
84            EngineMessage::MmpTriggered(_) => EventType::MmpTriggered,
85            EngineMessage::PositionExpired(_) => EventType::PositionExpired,
86            EngineMessage::TierUpdate(_) => EventType::TierUpdate,
87            EngineMessage::HypercorePositionUpdate(_) => EventType::HypercorePositionUpdate,
88            EngineMessage::LiquidationStateChange(_) => EventType::LiquidationStateChange,
89            EngineMessage::RfqFilled(_) => EventType::RfqFilled,
90        }
91    }
92
93    fn topic(&self) -> &'static str {
94        match self {
95            EventType::OrderAction => topics::TOPIC_ORDER_ACTIONS,
96            EventType::OrderUpdate => topics::TOPIC_ORDER_UPDATES,
97            EventType::OrderInfo => topics::TOPIC_ORDER_INFOS,
98            EventType::MarketAction => topics::TOPIC_MARKET_ACTIONS,
99            EventType::MarketUpdate => topics::TOPIC_MARKET_UPDATES,
100            EventType::OrderFilled => topics::TOPIC_FILLS,
101            EventType::OrderbookUpdated => topics::TOPIC_ORDERBOOK_UPDATES,
102            EventType::L2Update => topics::TOPIC_L2_UPDATES,
103            EventType::Trade => topics::TOPIC_TRADES,
104            EventType::TransactionRequest => topics::TOPIC_TRANSACTION_REQUESTS,
105            EventType::TransactionUpdate => topics::TOPIC_TRANSACTION_UPDATES,
106            EventType::MmpTriggered => topics::TOPIC_MMP_TRIGGERS,
107            EventType::PositionExpired => topics::TOPIC_POSITION_EXPIRED,
108            EventType::TierUpdate => topics::TOPIC_TIER_UPDATES,
109            EventType::HypercorePositionUpdate => topics::TOPIC_HYPERCORE_POSITION_UPDATES,
110            EventType::LiquidationStateChange => topics::TOPIC_LIQUIDATION_STATE,
111            EventType::RfqFilled => topics::TOPIC_RFQ_FILLS,
112        }
113    }
114}
115
116/// Extension trait for decoding wire-format replay commands into typed messages.
117pub trait ReplayCommandExt {
118    fn decode_command(&self) -> hypercall_types::OrderActionMessage;
119    fn decode_response(&self) -> Option<hypercall_types::OrderUpdateMessage>;
120}
121
122impl ReplayCommandExt for hypercall_db::ReplayCommand {
123    fn decode_command(&self) -> hypercall_types::OrderActionMessage {
124        assert!(
125            self.command_data.len() > 1,
126            "ReplayCommand command_data missing version/payload bytes (command_id={})",
127            self.command_id
128        );
129        rmp_serde::from_slice(&self.command_data[1..]).unwrap_or_else(|e| {
130            panic!(
131                "Failed to decode command_data msgpack for replay (command_id={}): {}",
132                self.command_id, e
133            )
134        })
135    }
136
137    fn decode_response(&self) -> Option<hypercall_types::OrderUpdateMessage> {
138        self.response_data.as_ref().map(|data| {
139            assert!(
140                data.len() > 1,
141                "ReplayCommand response_data missing version/payload bytes (command_id={})",
142                self.command_id
143            );
144            rmp_serde::from_slice(&data[1..]).unwrap_or_else(|e| {
145                panic!(
146                    "Failed to decode response_data msgpack for replay (command_id={}): {}",
147                    self.command_id, e
148                )
149            })
150        })
151    }
152}