From bd92f375530beb6fdc3467a3643c952884e0bf90 Mon Sep 17 00:00:00 2001 From: Patrick Amato <51000544+pathoam@users.noreply.github.com> Date: Wed, 10 Jul 2019 23:22:33 -0600 Subject: [PATCH] Terminology (#4995) * update exchange program: tradeOrder->Order, tradeRequest->OrderRequest, tradeCancel->OrderCancel * Update bench-exchange: tradeOrder -> Order * update bench exchange Readme --- bench-exchange/README.md | 99 +++++++++---------- bench-exchange/src/bench.rs | 4 +- bench-exchange/src/order_book.rs | 10 +- .../exchange_api/src/exchange_instruction.rs | 20 ++-- .../exchange_api/src/exchange_processor.rs | 28 +++--- programs/exchange_api/src/exchange_state.rs | 8 +- 6 files changed, 81 insertions(+), 88 deletions(-) diff --git a/bench-exchange/README.md b/bench-exchange/README.md index 45c939f64..e895b5e46 100644 --- a/bench-exchange/README.md +++ b/bench-exchange/README.md @@ -6,10 +6,10 @@ learn how to start and interact with the exchange. ### Table of Contents [Overview](#Overview)
-[Premiss](#Premiss)
+[Premise](#Premise)
[Exchange startup](#Exchange-startup)
-[Trade requests](#Trade-requests)
-[Trade cancellations](#Trade-cancellations)
+[Order Requests](#Trade-requests)
+[Order Cancellations](#Trade-cancellations)
[Trade swap](#Trade-swap)
[Exchange program operations](#Exchange-program-operations)
[Quotes and OHLCV](#Quotes-and-OHLCV)
@@ -22,9 +22,9 @@ An exchange is a marketplace where one asset can be traded for another. This demo demonstrates one way to host an exchange on the Solana blockchain by emulating a currency exchange. -The assets are virtual tokens held by investors who may post trade requests to +The assets are virtual tokens held by investors who may post order requests to the exchange. A Swapper monitors the exchange and posts swap requests for -matching trade orders. All the transactions can execute concurrently. +matching orders. All the transactions can execute concurrently. ## Premise @@ -59,43 +59,43 @@ matching trade orders. All the transactions can execute concurrently. ratios are represented as fixed point numbers. The fixed point scaler is defined in [exchange_state.rs](https://github.com/solana-labs/solana/blob/c2fdd1362a029dcf89c8907c562d2079d977df11/programs/exchange_api/src/exchange_state.rs#L7) -- Trade request +- Order request - A Solana transaction executed by the exchange requesting the trade of one - type of token for another. Trade requests are made up of the token pair, + type of token for another. order requests are made up of the token pair, the direction of the trade, quantity of the primary token, the price ratio, and the two token accounts to be credited/deducted. An example trade request looks like "T AB 5 2" which reads "Exchange 5 A tokens to B tokens at a price ratio of 1:2" A fulfilled trade would result in 5 A tokens deducted and 10 B tokens credited to the trade initiator's token accounts. - Successful trade requests result in a trade order. -- Trade order - - The result of a successful trade request. Trade orders are stored in - accounts owned by the submitter of the trade request. They can only be + Successful order requests result in an order. +- Order + - The result of a successful order request. orders are stored in + accounts owned by the submitter of the order request. They can only be canceled by their owner but can be used by anyone in a trade swap. They - contain the same information as the trade request. + contain the same information as the order request. - Price spread - - The difference between the two matching trade orders. The spread is the + - The difference between the two matching orders. The spread is the profit of the Swapper initiating the swap request. - Swap requirements - Policies that result in a successful trade swap. - Swap request - - A request to exchange tokens between to trade orders + - A request to exchange tokens between to orders - Trade swap - - A successful trade. A swap consists of two matching trade orders that meet + - A successful trade. A swap consists of two matching orders that meet swap requirements. A trade swap may not wholly satisfy one or both of the - trade orders in which case the trade orders are adjusted appropriately. As + orders in which case the orders are adjusted appropriately. As long as the swap requirements are met there will be an exchange of tokens between accounts. Any price spread is deposited into the Swapper's profit account. All trade swaps are recorded in a new account for posterity. - Investor - Individual investors who hold a number of tokens and wish to trade them on the exchange. Investors operate as Solana thin clients who own a set of - accounts containing tokens and/or trade requests. Investors post + accounts containing tokens and/or order requests. Investors post transactions to the exchange in order to request tokens and post or cancel - trade requests. + order requests. - Swapper - An agent who facilitates trading between investors. Swappers operate as - Solana thin clients who monitor all the trade orders looking for a trade + Solana thin clients who monitor all the orders looking for a trade match. Once found, the Swapper issues a swap request to the exchange. Swappers are the engine of the exchange and are rewarded for their efforts by accumulating the price spreads of the swaps they initiate. Swappers also @@ -123,7 +123,7 @@ the investors that trades submitted after that point will be analyzed. +open orders.--> Investors will initially query the exchange to discover their current balance for each type of token. If the investor does not already have an account for @@ -181,19 +181,19 @@ pub enum ExchangeInstruction { } ``` -## Trade requests +## Order Requests When an investor decides to exchange a token of one type for another, they -submit a transaction to the Solana Blockchain containing a trade request, which, -if successful, is turned into a trade order. Trade orders do not expire but are -cancellable. When a trade order is created, tokens are deducted from a token -account and the trade order acts as an escrow. The tokens are held until the -trade order is fulfilled or canceled. If the direction is `To`, then the number +submit a transaction to the Solana Blockchain containing an order request, which, +if successful, is turned into an order. orders do not expire but are +cancellable. When an order is created, tokens are deducted from a token +account and the order acts as an escrow. The tokens are held until the +order is fulfilled or canceled. If the direction is `To`, then the number of `tokens` are deducted from the primary account, if `From` then `tokens` -multiplied by `price` are deducted from the secondary account. Trade orders are +multiplied by `price` are deducted from the secondary account. orders are no longer valid when the number of `tokens` goes to zero, at which point they -can no longer be used. ```rust @@ -205,7 +205,7 @@ pub enum Direction { From, } -pub struct TradeRequestInfo { +pub struct OrderRequestInfo { /// Direction of trade pub direction: Direction, @@ -224,7 +224,7 @@ pub struct TradeRequestInfo { } pub enum ExchangeInstruction { - /// Trade request + /// order request /// key 0 - Signer /// key 1 - Account in which to record the swap /// key 2 - Token account associated with this trade @@ -233,7 +233,7 @@ pub enum ExchangeInstruction { /// Trade accounts are populated with this structure pub struct TradeOrderInfo { - /// Owner of the trade order + /// Owner of the order pub owner: Pubkey, /// Direction of the exchange pub direction: Direction, @@ -252,7 +252,7 @@ pub struct TradeOrderInfo { } ``` -## Trade cancellations +## Order cancellations An investor may cancel a trade at anytime, but only trades they own. If the cancellation is successful, any tokens held in escrow are returned to the @@ -260,9 +260,9 @@ account from which they came. ```rust pub enum ExchangeInstruction { - /// Trade cancellation + /// order cancellation /// key 0 - Signer - /// key 1 -Trade order to cancel + /// key 1 -order to cancel TradeCancellation, } ``` @@ -270,14 +270,14 @@ pub enum ExchangeInstruction { ## Trade swaps The Swapper is monitoring the accounts assigned to the exchange program and -building a trade-order table. The trade order table is used to identify -matching trade orders which could be fulfilled. When a match is found the +building a trade-order table. The order table is used to identify +matching orders which could be fulfilled. When a match is found the Swapper should issue a swap request. Swap requests may not satisfy the entirety of either order, but the exchange will greedily fulfill it. Any leftover tokens -in either account will keep the trade order valid for further swap requests in +in either account will keep the order valid for further swap requests in the future. -Matching trade orders are defined by the following swap requirements: +Matching orders are defined by the following swap requirements: - Opposite polarity (one `To` and one `From`) - Operate on the same token pair @@ -379,8 +379,8 @@ pub enum ExchangeInstruction { /// Trade swap request /// key 0 - Signer /// key 1 - Account in which to record the swap - /// key 2 - 'To' trade order - /// key 3 - `From` trade order + /// key 2 - 'To' order + /// key 3 - `From` order /// key 4 - Token account associated with the To Trade /// key 5 - Token account associated with From trade /// key 6 - Token account in which to deposit the Swappers profit from the swap. @@ -391,9 +391,9 @@ pub enum ExchangeInstruction { pub struct TradeSwapInfo { /// Pair swapped pub pair: TokenPair, - /// `To` trade order + /// `To` order pub to_trade_order: Pubkey, - /// `From` trade order + /// `From` order pub from_trade_order: Pubkey, /// Number of primary tokens exchanged pub primary_tokens: u64, @@ -424,22 +424,22 @@ pub enum ExchangeInstruction { /// the exchange has a limitless number of tokens it can transfer. TransferRequest(Token, u64), - /// Trade request + /// order request /// key 0 - Signer /// key 1 - Account in which to record the swap /// key 2 - Token account associated with this trade TradeRequest(TradeRequestInfo), - /// Trade cancellation + /// order cancellation /// key 0 - Signer - /// key 1 -Trade order to cancel + /// key 1 -order to cancel TradeCancellation, /// Trade swap request /// key 0 - Signer /// key 1 - Account in which to record the swap - /// key 2 - 'To' trade order - /// key 3 - `From` trade order + /// key 2 - 'To' order + /// key 3 - `From` order /// key 4 - Token account associated with the To Trade /// key 5 - Token account associated with From trade /// key 6 - Token account in which to deposit the Swappers profit from the swap. @@ -478,6 +478,3 @@ To also see the cluster messages: ```bash $ RUST_LOG=solana_bench_exchange=info,solana=info cargo test --release -- --nocapture test_exchange_local_cluster ``` - - - diff --git a/bench-exchange/src/bench.rs b/bench-exchange/src/bench.rs index 2f5e81a9f..82b5f2f91 100644 --- a/bench-exchange/src/bench.rs +++ b/bench-exchange/src/bench.rs @@ -332,7 +332,7 @@ fn do_tx_transfers( struct TradeInfo { trade_account: Pubkey, - order_info: TradeOrderInfo, + order_info: OrderInfo, } #[allow(clippy::too_many_arguments)] fn swapper( @@ -538,7 +538,7 @@ fn trader( } else { Direction::To }; - let order_info = TradeOrderInfo { + let order_info = OrderInfo { /// Owner of the trade order owner: Pubkey::default(), // don't care direction, diff --git a/bench-exchange/src/order_book.rs b/bench-exchange/src/order_book.rs index 7af79f5f3..87a9aefa5 100644 --- a/bench-exchange/src/order_book.rs +++ b/bench-exchange/src/order_book.rs @@ -10,7 +10,7 @@ use std::{error, fmt}; #[derive(Clone, Debug, Eq, PartialEq)] pub struct ToOrder { pub pubkey: Pubkey, - pub info: TradeOrderInfo, + pub info: OrderInfo, } impl Ord for ToOrder { @@ -26,7 +26,7 @@ impl PartialOrd for ToOrder { #[derive(Clone, Debug, Eq, PartialEq)] pub struct FromOrder { pub pubkey: Pubkey, - pub info: TradeOrderInfo, + pub info: OrderInfo, } impl Ord for FromOrder { @@ -95,11 +95,7 @@ impl OrderBook { // pub fn cancel(&mut self, pubkey: Pubkey) -> Result<(), Box> { // Ok(()) // } - pub fn push( - &mut self, - pubkey: Pubkey, - info: TradeOrderInfo, - ) -> Result<(), Box> { + pub fn push(&mut self, pubkey: Pubkey, info: OrderInfo) -> Result<(), Box> { check_trade(info.direction, info.tokens, info.price)?; match info.direction { Direction::To => { diff --git a/programs/exchange_api/src/exchange_instruction.rs b/programs/exchange_api/src/exchange_instruction.rs index 390f1b8e9..4c8c43e15 100644 --- a/programs/exchange_api/src/exchange_instruction.rs +++ b/programs/exchange_api/src/exchange_instruction.rs @@ -7,7 +7,7 @@ use solana_sdk::instruction::{AccountMeta, Instruction}; use solana_sdk::pubkey::Pubkey; #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub struct TradeRequestInfo { +pub struct OrderRequestInfo { /// Direction of trade pub direction: Direction, @@ -35,16 +35,16 @@ pub enum ExchangeInstruction { /// the exchange has a limitless number of tokens it can transfer. TransferRequest(Token, u64), - /// Trade request + /// Order request /// key 0 - Signer /// key 1 - Account in which to record the trade order /// key 2 - Token account to source tokens from - TradeRequest(TradeRequestInfo), + OrderRequest(OrderRequestInfo), - /// Trade cancellation + /// Order cancellation /// key 0 - Signer - /// key 1 - Trade order to cancel - TradeCancellation, + /// key 1 - Order to cancel + OrderCancellation, /// Trade swap request /// key 0 - Signer @@ -97,7 +97,7 @@ pub fn trade_request( ]; Instruction::new( id(), - &ExchangeInstruction::TradeRequest(TradeRequestInfo { + &ExchangeInstruction::OrderRequest(OrderRequestInfo { direction, pair, tokens, @@ -107,12 +107,12 @@ pub fn trade_request( ) } -pub fn trade_cancellation(owner: &Pubkey, trade: &Pubkey) -> Instruction { +pub fn order_cancellation(owner: &Pubkey, order: &Pubkey) -> Instruction { let account_metas = vec![ AccountMeta::new(*owner, true), - AccountMeta::new(*trade, false), + AccountMeta::new(*order, false), ]; - Instruction::new(id(), &ExchangeInstruction::TradeCancellation, account_metas) + Instruction::new(id(), &ExchangeInstruction::OrderCancellation, account_metas) } pub fn swap_request( diff --git a/programs/exchange_api/src/exchange_processor.rs b/programs/exchange_api/src/exchange_processor.rs index 722caadc4..6adcb037d 100644 --- a/programs/exchange_api/src/exchange_processor.rs +++ b/programs/exchange_api/src/exchange_processor.rs @@ -39,7 +39,7 @@ impl ExchangeProcessor { } } - fn deserialize_trade(data: &[u8]) -> Result { + fn deserialize_trade(data: &[u8]) -> Result { let state: ExchangeState = bincode::deserialize(data).map_err(Self::map_to_invalid_arg)?; if let ExchangeState::Trade(info) = state { Ok(info) @@ -60,7 +60,7 @@ impl ExchangeProcessor { } } - fn trade_to_token_account(trade: &TradeOrderInfo) -> TokenAccountInfo { + fn trade_to_token_account(trade: &OrderInfo) -> TokenAccountInfo { // Turn trade order into token account let token = match trade.direction { @@ -75,8 +75,8 @@ impl ExchangeProcessor { fn calculate_swap( scaler: u64, - to_trade: &mut TradeOrderInfo, - from_trade: &mut TradeOrderInfo, + to_trade: &mut OrderInfo, + from_trade: &mut OrderInfo, profit_account: &mut TokenAccountInfo, ) -> Result<(), InstructionError> { if to_trade.tokens == 0 || from_trade.tokens == 0 { @@ -261,7 +261,7 @@ impl ExchangeProcessor { fn do_trade_request( keyed_accounts: &mut [KeyedAccount], - info: &TradeRequestInfo, + info: &OrderRequestInfo, ) -> Result<(), InstructionError> { const OWNER_INDEX: usize = 0; const TRADE_INDEX: usize = 1; @@ -299,7 +299,7 @@ impl ExchangeProcessor { inc_new_counter_info!("exchange_processor-trades", 1, 1000, 1000); Self::serialize( - &ExchangeState::Trade(TradeOrderInfo { + &ExchangeState::Trade(OrderInfo { owner: *keyed_accounts[OWNER_INDEX].unsigned_key(), direction: info.direction, pair: info.pair, @@ -315,7 +315,7 @@ impl ExchangeProcessor { ) } - fn do_trade_cancellation(keyed_accounts: &mut [KeyedAccount]) -> Result<(), InstructionError> { + fn do_order_cancellation(keyed_accounts: &mut [KeyedAccount]) -> Result<(), InstructionError> { const OWNER_INDEX: usize = 0; const TRADE_INDEX: usize = 1; @@ -446,11 +446,11 @@ pub fn process_instruction( ExchangeInstruction::TransferRequest(token, tokens) => { ExchangeProcessor::do_transfer_request(keyed_accounts, token, tokens) } - ExchangeInstruction::TradeRequest(info) => { + ExchangeInstruction::OrderRequest(info) => { ExchangeProcessor::do_trade_request(keyed_accounts, &info) } - ExchangeInstruction::TradeCancellation => { - ExchangeProcessor::do_trade_cancellation(keyed_accounts) + ExchangeInstruction::OrderCancellation => { + ExchangeProcessor::do_order_cancellation(keyed_accounts) } ExchangeInstruction::SwapRequest => ExchangeProcessor::do_swap_request(keyed_accounts), } @@ -487,8 +487,8 @@ mod test { secondary_tokens, secondary_price, ); - let mut to_trade = TradeOrderInfo::default(); - let mut from_trade = TradeOrderInfo::default().direction(Direction::From); + let mut to_trade = OrderInfo::default(); + let mut from_trade = OrderInfo::default().direction(Direction::From); let mut profit_account = TokenAccountInfo::default(); to_trade.tokens = primary_tokens; @@ -714,7 +714,7 @@ mod test { // check results assert_eq!( - TradeOrderInfo { + OrderInfo { owner: owner.pubkey(), direction: Direction::To, pair: TokenPair::AB, @@ -773,7 +773,7 @@ mod test { // check results assert_eq!( - TradeOrderInfo { + OrderInfo { owner: owner.pubkey(), direction: Direction::To, pair: TokenPair::AB, diff --git a/programs/exchange_api/src/exchange_state.rs b/programs/exchange_api/src/exchange_state.rs index 911148afb..f1e39efb1 100644 --- a/programs/exchange_api/src/exchange_state.rs +++ b/programs/exchange_api/src/exchange_state.rs @@ -150,7 +150,7 @@ impl fmt::Display for Direction { /// Trade accounts are populated with this structure #[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)] -pub struct TradeOrderInfo { +pub struct OrderInfo { /// Owner of the trade order pub owner: Pubkey, /// Direction of the exchange @@ -167,7 +167,7 @@ pub struct TradeOrderInfo { /// token account by the owner. pub tokens_settled: u64, } -impl Default for TradeOrderInfo { +impl Default for OrderInfo { fn default() -> Self { Self { owner: Pubkey::default(), @@ -179,7 +179,7 @@ impl Default for TradeOrderInfo { } } } -impl TradeOrderInfo { +impl OrderInfo { pub fn pair(mut self, pair: TokenPair) -> Self { self.pair = pair; self @@ -228,7 +228,7 @@ pub enum ExchangeState { // Token account Account(TokenAccountInfo), // Trade order account - Trade(TradeOrderInfo), + Trade(OrderInfo), Invalid, } impl Default for ExchangeState {