Skip to content

Commit

Permalink
frank/market & oracle maps (#17)
Browse files Browse the repository at this point in the history
* marketmaps

* remove unused imports

* rename marketindex trait

* remove visibility

* small marketmap refactor, add get market and slot in drift client

* wip oraclemap

* cargo fmt all

* oraclemap (w/o switchover)

* add additional filters op to usermap

* remove debug print

* clean up oraclemap event subscription

* minor change

* oracle switchovers

* clippy

* pr comments

* remove debug print

* remove duplicate

* retry logic for dropped ws

* pubsub creation retry logic

* Delete .DS_Store
  • Loading branch information
soundsonacid authored Mar 22, 2024
1 parent 6b3e753 commit 2855dd7
Show file tree
Hide file tree
Showing 16 changed files with 1,312 additions and 74 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ spl-associated-token-account = "1.1.2"
anchor-client = "0.27.0"
anchor-lang = "*"
bytes = "*"
futures = "0.3.30"
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div align="center">
<img height="120x" src="https://uploads-ssl.webflow.com/611580035ad59b20437eb024/616f97a42f5637c4517d0193_Logo%20(1)%20(1).png" />

<h1 style="margin-top:20px;">Drift Protocol v2 (Rust SDK)</h1>
<h1 style="margin-top:20px;">drift-rs</h1>

<p>
<a href="https://crates.io/crates/drift-sdk"><img alt="Crates.io" src="https://img.shields.io/crates/v/drift-sdk.img" /></a>
Expand All @@ -11,9 +11,9 @@
</p>
</div>

# Drift Protocol v2 (Rust SDK)
# drift-rs

Rust SDK for building off chain clients for interacting with the [Drift V2](https://github.com/drift-labs/protocol-v2) protocol.
Experimental, high performance Rust SDK for building off chain clients for interacting with the [Drift V2](https://github.com/drift-labs/protocol-v2) protocol.

## Setup

Expand Down
14 changes: 7 additions & 7 deletions src/dlob/dlob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::dlob::dlob_node::{
use crate::dlob::market::{get_order_lists, Exchange, Market, OpenOrders, SubType};
use crate::event_emitter::Event;
use crate::math::order::is_resting_limit_order;
use crate::usermap::Usermap;
use crate::usermap::UserMap;
use crate::utils::market_type_to_string;

#[derive(Clone)]
Expand Down Expand Up @@ -43,7 +43,7 @@ impl DLOB {
}
}

pub fn build_from_usermap(&mut self, usermap: &Usermap, slot: u64) {
pub fn build_from_usermap(&mut self, usermap: &UserMap, slot: u64) {
usermap.usermap.iter().par_bridge().for_each(|user_ref| {
let user = user_ref.value();
let user_key = user_ref.key();
Expand Down Expand Up @@ -98,14 +98,14 @@ impl DLOB {
.get_mut(&market_index)
.expect(format!("Market index {} not found", market_index).as_str());

let (order_list, subtype, node_type) = market.get_info_for_order_insert(&order, slot);
let (order_list, subtype, node_type) = market.get_info_for_order_insert(order, slot);

let node = create_node(node_type, order.clone(), user_account);
let node = create_node(node_type, *order, user_account);

if let Some(order_list) = order_list {
match subtype {
SubType::Bid => order_list.insert_bid(node.clone()),
SubType::Ask => order_list.insert_ask(node.clone()),
SubType::Bid => order_list.insert_bid(node),
SubType::Ask => order_list.insert_ask(node),
_ => {}
}
} else {
Expand All @@ -117,7 +117,7 @@ impl DLOB {
let order_signature = get_order_signature(order_id, user_account);
for order_list in get_order_lists(&self.exchange) {
if let Some(node) = order_list.get_node(&order_signature) {
return Some(node.get_order().clone());
return Some(*node.get_order());
}
}

Expand Down
28 changes: 18 additions & 10 deletions src/dlob/dlob_builder.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
use crate::{
dlob::dlob::DLOB,
event_emitter::{Event, EventEmitter},
slot_subscriber::SlotSubscriber,
usermap::Usermap,
SdkResult,
dlob::dlob::DLOB, event_emitter::EventEmitter, slot_subscriber::SlotSubscriber,
usermap::UserMap, SdkResult,
};

pub struct DLOBBuilder {
slot_subscriber: SlotSubscriber,
usermap: Usermap,
usermap: UserMap,
rebuild_frequency: u64,
dlob: DLOB,
event_emitter: EventEmitter,
Expand All @@ -17,7 +14,7 @@ pub struct DLOBBuilder {
impl DLOBBuilder {
pub fn new(
slot_subscriber: SlotSubscriber,
usermap: Usermap,
usermap: UserMap,
rebuild_frequency: u64,
) -> DLOBBuilder {
DLOBBuilder {
Expand Down Expand Up @@ -56,6 +53,7 @@ impl DLOBBuilder {
#[cfg(test)]
mod tests {
use super::*;
use crate::memcmp::get_user_with_order_filter;
use crate::utils::get_ws_url;
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::commitment_config::CommitmentLevel;
Expand All @@ -70,7 +68,12 @@ mod tests {
};

let slot_subscriber = SlotSubscriber::new(get_ws_url(&endpoint.clone()).unwrap());
let usermap = Usermap::new(commitment, endpoint, true);
let mut usermap = UserMap::new(
commitment,
endpoint,
true,
Some(vec![get_user_with_order_filter()]),
);
let mut dlob_builder = DLOBBuilder::new(slot_subscriber, usermap, 30);

dlob_builder
Expand All @@ -90,13 +93,18 @@ mod tests {
#[tokio::test]
#[cfg(rpc_tests)]
async fn test_build_time() {
let endpoint = "url".to_string();
let endpoint = "rpc".to_string();
let commitment = CommitmentConfig {
commitment: CommitmentLevel::Processed,
};

let mut slot_subscriber = SlotSubscriber::new(get_ws_url(&endpoint.clone()).unwrap());
let mut usermap = Usermap::new(commitment, endpoint, true);
let mut usermap = UserMap::new(
commitment,
endpoint,
true,
Some(vec![get_user_with_order_filter()]),
);
let _ = slot_subscriber.subscribe().await;
let _ = usermap.subscribe().await;

Expand Down
2 changes: 1 addition & 1 deletion src/dlob/dlob_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ pub(crate) fn create_node(node_type: NodeType, order: Order, user_account: Pubke
}

pub(crate) fn get_order_signature(order_id: u32, user_account: Pubkey) -> String {
format!("{}-{}", order_id, user_account.to_string())
format!("{}-{}", order_id, user_account)
}

#[cfg(test)]
Expand Down
8 changes: 3 additions & 5 deletions src/dlob/market.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,10 @@ impl Market {
NodeType::Market
} else if order.oracle_price_offset != 0 {
NodeType::FloatingLimit
} else if is_resting_limit_order(order, slot) {
NodeType::RestingLimit
} else {
if is_resting_limit_order(order, slot) {
NodeType::RestingLimit
} else {
NodeType::TakingLimit
}
NodeType::TakingLimit
};

let order_list = match node_type {
Expand Down
10 changes: 5 additions & 5 deletions src/dlob/order_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ impl Orderlist {

pub fn insert_bid(&mut self, node: Node) {
let order_sig = get_order_signature(node.get_order().order_id, node.get_user_account());
self.order_sigs.insert(order_sig.clone(), node.clone());
self.order_sigs.insert(order_sig.clone(), node);
let directional = DirectionalNode::new(node, self.bid_sort_direction);
self.bids.push(directional);
}

pub fn insert_ask(&mut self, node: Node) {
let order_sig = get_order_signature(node.get_order().order_id, node.get_user_account());
self.order_sigs.insert(order_sig.clone(), node.clone());
self.order_sigs.insert(order_sig.clone(), node);
let directional = DirectionalNode::new(node, self.ask_sort_direction);
self.asks.push(directional);
}

pub fn get_best_bid(&mut self) -> Option<Node> {
if let Some(node) = self.bids.pop().map(|node| node.node.clone()) {
if let Some(node) = self.bids.pop().map(|node| node.node) {
let order_sig = get_order_signature(node.get_order().order_id, node.get_user_account());
if self.order_sigs.contains_key(&order_sig) {
self.order_sigs.remove(&order_sig);
Expand All @@ -50,7 +50,7 @@ impl Orderlist {
}

pub fn get_best_ask(&mut self) -> Option<Node> {
if let Some(node) = self.asks.pop().map(|node| node.node.clone()) {
if let Some(node) = self.asks.pop().map(|node| node.node) {
let order_sig = get_order_signature(node.get_order().order_id, node.get_user_account());
if self.order_sigs.contains_key(&order_sig) {
self.order_sigs.remove(&order_sig);
Expand All @@ -61,7 +61,7 @@ impl Orderlist {
}

pub fn get_node(&self, order_sig: &String) -> Option<Node> {
self.order_sigs.get(order_sig).map(|node| node.clone())
self.order_sigs.get(order_sig).map(|node| *node)
}

pub fn bids_empty(&self) -> bool {
Expand Down
Loading

0 comments on commit 2855dd7

Please sign in to comment.