DeepBook 订单
订单簿结构
DeepBook 采用了一种超高效的方法来存储订单。每个池存储未成交的挂单。吃单在提交订单的同一事务中即时成交。买单和卖单分别存储,每个都有一个两级嵌套的 Crit-bit 树。第一级 Crit-bit 树使用挂单的价格排序,第二级 Crit-bit 树使用挂单的订单 id 排序。
下单
DeepBook 支持市价单和限价单的下单。DeepBook 还支持一些限价单的配置,这将在 API 部分介绍。当用户提交市价单时,它将立即在提交市价单的同一事务中与订单簿上的现有挂单匹配。当用户提交限价单时,限价单首先作为吃单与现有的挂单匹配。如果订单无法完全成交,剩余数量可以作为挂单注入或丢弃,具体取决于限价单的配置。有关更多详细信息,请参见 API 部分。
struct Order has store, drop {
// For each pool, order id is incremental and unique for each opening order.
// Orders that are submitted earlier have lower order ids.
// 64 bits are sufficient for order ids, whereas 32 bits are not.
// Assuming a maximum TPS of 100K/s of Sui chain, it would take (1<<63) / 100000 / 3600 / 24 / 365 = 2924712 years to reach the full capacity.
// The highest bit of the order id denotes the order type, 0 for bid, 1 for ask.
order_id: u64,
// Only used for limit orders.
price: u64,
quantity: u64,
is_bid: bool,
// Order can only be canceled by the owner.
owner: ID,
// Expiration timestamp in ms.
expire_timestamp: u64,
}
订单匹配
订单匹配发生在吃单订单提交到 CLOB 时,没有中央实体或曲柄参与。吃单订单与 CLOB 中的现有挂单在提交吃单订单的同一事务中匹配。
订单追踪
DeepBook 支持高效追踪挂单。每个未成交的挂单都与一个唯一的 u64 订单 id 关联,用户可以使用订单 id 与 Sui RPC 调用一起查询订单状态。用户还可以订阅 DeepBook 发出的与订单状态变化相关的事件流。DeepBook 目前支持以下事件,OrderPlaced
、OrderFilled
和 OrderCanceled
。
/// Emitted when a maker order is injected into the order book.
struct OrderPlaced<phantom BaseAsset, phantom QuoteAsset> has copy, store, drop {
order_id: u64,
is_bid: bool,
owner: ID,
base_asset_quantity_placed: u64,
price: u64
}
/// Emitted when a maker order is canceled.
struct OrderCanceled<phantom BaseAsset, phantom QuoteAsset> has copy, store, drop {
order_id: u64,
is_bid: bool,
owner: ID,
base_asset_quantity_canceled: u64,
price: u64
}
/// Emitted only when a maker order is filled.
struct OrderFilled<phantom BaseAsset, phantom QuoteAsset> has copy, store, drop {
order_id: u64,
is_bid: bool,
owner: ID,
total_quantity: u64,
base_asset_quantity_filled: u64,
base_asset_quantity_remaining: u64,
price: u64
}
以下示例使用Sui TypeScript SDK通过 WebSocket 连接以监听事件。
const local_client = new SuiClient({ url: 'https://fullnode.mainnet.sui.io:443/' });
const deepbook_client = new DeepBookClient(local_client);
const deepbook = '0x000000000000000000000000000000000000000000000000000000000000dee9';
const deepbookClobEventsFilter = {
MoveModule: { package: deepbook, module: 'clob_v2' },
};
// Note that these names must be exact
const moveEventsFilter = {
MoveEventType:
'0xdee9::clob_v2::OrderPlaced<0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5::coin::COIN, 0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>',
};
const orderFilledFilter = {
MoveEventType:
'0xdee9::clob_v2::OrderFilled<0xaf8cd5edc19c4512f4259f0bee101a40d41ebed738ade5874359610ef8eeced5::coin::COIN, 0x5d4b302506645c37ff133b98c4b50a5ae14841659738d6d733d59d0d217a93bf::coin::COIN>',
};
const poolFilter = {
MoveEventField: {
path: '/pool_id',
value: '0xd9e45ab5440d61cc52e3b2bd915cdd643146f7593d587c715bc7bfa48311d826',
},
};
deepbook_client.suiClient.subscribeEvent({
filter: moveEventsFilter,
onMessage(event) {
console.log(event);
// handle subscription notification message here
},
});