exchange update: replace direction (#5362)
* replace direction with OrderSide * bench exchange: update direction uses to OrderSide
This commit is contained in:
parent
3b752876ac
commit
0b0b679120
|
@ -527,21 +527,21 @@ fn trader<T>(
|
||||||
let mut trade_infos = vec![];
|
let mut trade_infos = vec![];
|
||||||
let start = account_group * batch_size as usize;
|
let start = account_group * batch_size as usize;
|
||||||
let end = account_group * batch_size as usize + batch_size as usize;
|
let end = account_group * batch_size as usize + batch_size as usize;
|
||||||
let mut direction = Direction::To;
|
let mut side = OrderSide::Ask;
|
||||||
for (signer, trade, src) in izip!(
|
for (signer, trade, src) in izip!(
|
||||||
signers[start..end].iter(),
|
signers[start..end].iter(),
|
||||||
trade_keys,
|
trade_keys,
|
||||||
srcs[start..end].iter(),
|
srcs[start..end].iter(),
|
||||||
) {
|
) {
|
||||||
direction = if direction == Direction::To {
|
side = if side == OrderSide::Ask {
|
||||||
Direction::From
|
OrderSide::Bid
|
||||||
} else {
|
} else {
|
||||||
Direction::To
|
OrderSide::Ask
|
||||||
};
|
};
|
||||||
let order_info = OrderInfo {
|
let order_info = OrderInfo {
|
||||||
/// Owner of the trade order
|
/// Owner of the trade order
|
||||||
owner: Pubkey::default(), // don't care
|
owner: Pubkey::default(), // don't care
|
||||||
direction,
|
side,
|
||||||
pair,
|
pair,
|
||||||
tokens,
|
tokens,
|
||||||
price,
|
price,
|
||||||
|
@ -551,7 +551,7 @@ fn trader<T>(
|
||||||
trade_account: trade.pubkey(),
|
trade_account: trade.pubkey(),
|
||||||
order_info,
|
order_info,
|
||||||
});
|
});
|
||||||
trades.push((signer, trade.pubkey(), direction, src));
|
trades.push((signer, trade.pubkey(), side, src));
|
||||||
}
|
}
|
||||||
account_group = (account_group + 1) % account_groups as usize;
|
account_group = (account_group + 1) % account_groups as usize;
|
||||||
|
|
||||||
|
@ -562,7 +562,7 @@ fn trader<T>(
|
||||||
trades.chunks(chunk_size).for_each(|chunk| {
|
trades.chunks(chunk_size).for_each(|chunk| {
|
||||||
let trades_txs: Vec<_> = chunk
|
let trades_txs: Vec<_> = chunk
|
||||||
.par_iter()
|
.par_iter()
|
||||||
.map(|(signer, trade, direction, src)| {
|
.map(|(signer, trade, side, src)| {
|
||||||
let s: &Keypair = &signer;
|
let s: &Keypair = &signer;
|
||||||
let owner = &signer.pubkey();
|
let owner = &signer.pubkey();
|
||||||
let space = mem::size_of::<ExchangeState>() as u64;
|
let space = mem::size_of::<ExchangeState>() as u64;
|
||||||
|
@ -571,7 +571,7 @@ fn trader<T>(
|
||||||
vec![
|
vec![
|
||||||
system_instruction::create_account(owner, trade, 1, space, &id()),
|
system_instruction::create_account(owner, trade, 1, space, &id()),
|
||||||
exchange_instruction::trade_request(
|
exchange_instruction::trade_request(
|
||||||
owner, trade, *direction, pair, tokens, price, src,
|
owner, trade, *side, pair, tokens, price, src,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
blockhash,
|
blockhash,
|
||||||
|
|
|
@ -96,12 +96,12 @@ impl OrderBook {
|
||||||
// Ok(())
|
// Ok(())
|
||||||
// }
|
// }
|
||||||
pub fn push(&mut self, pubkey: Pubkey, info: OrderInfo) -> Result<(), Box<dyn error::Error>> {
|
pub fn push(&mut self, pubkey: Pubkey, info: OrderInfo) -> Result<(), Box<dyn error::Error>> {
|
||||||
check_trade(info.direction, info.tokens, info.price)?;
|
check_trade(info.side, info.tokens, info.price)?;
|
||||||
match info.direction {
|
match info.side {
|
||||||
Direction::To => {
|
OrderSide::Ask => {
|
||||||
self.to_ab.push(ToOrder { pubkey, info });
|
self.to_ab.push(ToOrder { pubkey, info });
|
||||||
}
|
}
|
||||||
Direction::From => {
|
OrderSide::Bid => {
|
||||||
self.from_ab.push(FromOrder { pubkey, info });
|
self.from_ab.push(FromOrder { pubkey, info });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,13 @@ use solana_sdk::pubkey::Pubkey;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct OrderRequestInfo {
|
pub struct OrderRequestInfo {
|
||||||
/// Direction of trade
|
/// Side of market of the order (bid/ask)
|
||||||
pub direction: Direction,
|
pub side: OrderSide,
|
||||||
|
|
||||||
/// Token pair to trade
|
/// Token pair to trade
|
||||||
pub pair: AssetPair,
|
pub pair: AssetPair,
|
||||||
|
|
||||||
/// Number of tokens to exchange; refers to the primary or the secondary depending on the direction
|
/// Number of tokens to exchange; refers to the primary or the secondary depending on the order side
|
||||||
pub tokens: u64,
|
pub tokens: u64,
|
||||||
|
|
||||||
/// The price ratio the primary price over the secondary price. The primary price is fixed
|
/// The price ratio the primary price over the secondary price. The primary price is fixed
|
||||||
|
@ -84,7 +84,7 @@ pub fn transfer_request(
|
||||||
pub fn trade_request(
|
pub fn trade_request(
|
||||||
owner: &Pubkey,
|
owner: &Pubkey,
|
||||||
trade: &Pubkey,
|
trade: &Pubkey,
|
||||||
direction: Direction,
|
side: OrderSide,
|
||||||
pair: AssetPair,
|
pair: AssetPair,
|
||||||
tokens: u64,
|
tokens: u64,
|
||||||
price: u64,
|
price: u64,
|
||||||
|
@ -98,7 +98,7 @@ pub fn trade_request(
|
||||||
Instruction::new(
|
Instruction::new(
|
||||||
id(),
|
id(),
|
||||||
&ExchangeInstruction::OrderRequest(OrderRequestInfo {
|
&ExchangeInstruction::OrderRequest(OrderRequestInfo {
|
||||||
direction,
|
side,
|
||||||
pair,
|
pair,
|
||||||
tokens,
|
tokens,
|
||||||
price,
|
price,
|
||||||
|
|
|
@ -63,9 +63,9 @@ impl ExchangeProcessor {
|
||||||
fn trade_to_token_account(trade: &OrderInfo) -> TokenAccountInfo {
|
fn trade_to_token_account(trade: &OrderInfo) -> TokenAccountInfo {
|
||||||
// Turn trade order into token account
|
// Turn trade order into token account
|
||||||
|
|
||||||
let token = match trade.direction {
|
let token = match trade.side {
|
||||||
Direction::To => trade.pair.Quote,
|
OrderSide::Ask => trade.pair.Quote,
|
||||||
Direction::From => trade.pair.Base,
|
OrderSide::Bid => trade.pair.Base,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut account = TokenAccountInfo::default().owner(&trade.owner);
|
let mut account = TokenAccountInfo::default().owner(&trade.owner);
|
||||||
|
@ -224,9 +224,9 @@ impl ExchangeProcessor {
|
||||||
Err(InstructionError::GenericError)?
|
Err(InstructionError::GenericError)?
|
||||||
}
|
}
|
||||||
|
|
||||||
let from_token = match from_trade.direction {
|
let from_token = match from_trade.side {
|
||||||
Direction::To => from_trade.pair.Quote,
|
OrderSide::Ask => from_trade.pair.Quote,
|
||||||
Direction::From => from_trade.pair.Base,
|
OrderSide::Bid => from_trade.pair.Base,
|
||||||
};
|
};
|
||||||
if token != from_token {
|
if token != from_token {
|
||||||
error!("Trade to transfer from does not hold correct token");
|
error!("Trade to transfer from does not hold correct token");
|
||||||
|
@ -280,16 +280,16 @@ impl ExchangeProcessor {
|
||||||
error!("Signer does not own account");
|
error!("Signer does not own account");
|
||||||
Err(InstructionError::GenericError)?
|
Err(InstructionError::GenericError)?
|
||||||
}
|
}
|
||||||
let from_token = match info.direction {
|
let from_token = match info.side {
|
||||||
Direction::To => info.pair.Base,
|
OrderSide::Ask => info.pair.Base,
|
||||||
Direction::From => info.pair.Quote,
|
OrderSide::Bid => info.pair.Quote,
|
||||||
};
|
};
|
||||||
if account.tokens[from_token] < info.tokens {
|
if account.tokens[from_token] < info.tokens {
|
||||||
error!("From token balance is too low");
|
error!("From token balance is too low");
|
||||||
Err(InstructionError::GenericError)?
|
Err(InstructionError::GenericError)?
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = check_trade(info.direction, info.tokens, info.price) {
|
if let Err(e) = check_trade(info.side, info.tokens, info.price) {
|
||||||
bincode::serialize(&e).unwrap();
|
bincode::serialize(&e).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ impl ExchangeProcessor {
|
||||||
Self::serialize(
|
Self::serialize(
|
||||||
&ExchangeState::Trade(OrderInfo {
|
&ExchangeState::Trade(OrderInfo {
|
||||||
owner: *keyed_accounts[OWNER_INDEX].unsigned_key(),
|
owner: *keyed_accounts[OWNER_INDEX].unsigned_key(),
|
||||||
direction: info.direction,
|
side: info.side,
|
||||||
pair: info.pair,
|
pair: info.pair,
|
||||||
tokens: info.tokens,
|
tokens: info.tokens,
|
||||||
price: info.price,
|
price: info.price,
|
||||||
|
@ -331,9 +331,9 @@ impl ExchangeProcessor {
|
||||||
Err(InstructionError::GenericError)?
|
Err(InstructionError::GenericError)?
|
||||||
}
|
}
|
||||||
|
|
||||||
let token = match order.direction {
|
let token = match order.side {
|
||||||
Direction::To => order.pair.Base,
|
OrderSide::Ask => order.pair.Base,
|
||||||
Direction::From => order.pair.Quote,
|
OrderSide::Bid => order.pair.Quote,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut account = TokenAccountInfo::default().owner(&order.owner);
|
let mut account = TokenAccountInfo::default().owner(&order.owner);
|
||||||
|
@ -363,11 +363,11 @@ impl ExchangeProcessor {
|
||||||
let mut profit_account =
|
let mut profit_account =
|
||||||
Self::deserialize_account(&keyed_accounts[PROFIT_ACCOUNT_INDEX].account.data)?;
|
Self::deserialize_account(&keyed_accounts[PROFIT_ACCOUNT_INDEX].account.data)?;
|
||||||
|
|
||||||
if to_order.direction != Direction::To {
|
if to_order.side != OrderSide::Ask {
|
||||||
error!("To trade is not a To");
|
error!("To trade is not a To");
|
||||||
Err(InstructionError::InvalidArgument)?
|
Err(InstructionError::InvalidArgument)?
|
||||||
}
|
}
|
||||||
if from_order.direction != Direction::From {
|
if from_order.side != OrderSide::Bid {
|
||||||
error!("From trade is not a From");
|
error!("From trade is not a From");
|
||||||
Err(InstructionError::InvalidArgument)?
|
Err(InstructionError::InvalidArgument)?
|
||||||
}
|
}
|
||||||
|
@ -375,8 +375,8 @@ impl ExchangeProcessor {
|
||||||
error!("Mismatched token pairs");
|
error!("Mismatched token pairs");
|
||||||
Err(InstructionError::InvalidArgument)?
|
Err(InstructionError::InvalidArgument)?
|
||||||
}
|
}
|
||||||
if to_order.direction == from_order.direction {
|
if to_order.side == from_order.side {
|
||||||
error!("Matching trade directions");
|
error!("Matching trade sides");
|
||||||
Err(InstructionError::InvalidArgument)?
|
Err(InstructionError::InvalidArgument)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ mod test {
|
||||||
secondary_price,
|
secondary_price,
|
||||||
);
|
);
|
||||||
let mut to_trade = OrderInfo::default();
|
let mut to_trade = OrderInfo::default();
|
||||||
let mut from_trade = OrderInfo::default().direction(Direction::From);
|
let mut from_trade = OrderInfo::default().side(OrderSide::Bid);
|
||||||
let mut profit_account = TokenAccountInfo::default();
|
let mut profit_account = TokenAccountInfo::default();
|
||||||
|
|
||||||
to_trade.tokens = primary_tokens;
|
to_trade.tokens = primary_tokens;
|
||||||
|
@ -602,7 +602,7 @@ mod test {
|
||||||
fn trade(
|
fn trade(
|
||||||
client: &BankClient,
|
client: &BankClient,
|
||||||
owner: &Keypair,
|
owner: &Keypair,
|
||||||
direction: Direction,
|
side: OrderSide,
|
||||||
pair: AssetPair,
|
pair: AssetPair,
|
||||||
from_token: Token,
|
from_token: Token,
|
||||||
src_tokens: u64,
|
src_tokens: u64,
|
||||||
|
@ -616,7 +616,7 @@ mod test {
|
||||||
let instruction = exchange_instruction::trade_request(
|
let instruction = exchange_instruction::trade_request(
|
||||||
&owner.pubkey(),
|
&owner.pubkey(),
|
||||||
&trade,
|
&trade,
|
||||||
direction,
|
side,
|
||||||
pair,
|
pair,
|
||||||
trade_tokens,
|
trade_tokens,
|
||||||
price,
|
price,
|
||||||
|
@ -700,7 +700,7 @@ mod test {
|
||||||
let (trade, src) = trade(
|
let (trade, src) = trade(
|
||||||
&client,
|
&client,
|
||||||
&owner,
|
&owner,
|
||||||
Direction::To,
|
OrderSide::Ask,
|
||||||
AssetPair::default(),
|
AssetPair::default(),
|
||||||
Token::A,
|
Token::A,
|
||||||
42,
|
42,
|
||||||
|
@ -716,7 +716,7 @@ mod test {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
OrderInfo {
|
OrderInfo {
|
||||||
owner: owner.pubkey(),
|
owner: owner.pubkey(),
|
||||||
direction: Direction::To,
|
side: OrderSide::Ask,
|
||||||
pair: AssetPair::default(),
|
pair: AssetPair::default(),
|
||||||
tokens: 2,
|
tokens: 2,
|
||||||
price: 1000,
|
price: 1000,
|
||||||
|
@ -742,7 +742,7 @@ mod test {
|
||||||
let (to_trade, _) = trade(
|
let (to_trade, _) = trade(
|
||||||
&client,
|
&client,
|
||||||
&owner,
|
&owner,
|
||||||
Direction::To,
|
OrderSide::Ask,
|
||||||
AssetPair::default(),
|
AssetPair::default(),
|
||||||
Token::A,
|
Token::A,
|
||||||
2,
|
2,
|
||||||
|
@ -752,7 +752,7 @@ mod test {
|
||||||
let (from_trade, _) = trade(
|
let (from_trade, _) = trade(
|
||||||
&client,
|
&client,
|
||||||
&owner,
|
&owner,
|
||||||
Direction::From,
|
OrderSide::Bid,
|
||||||
AssetPair::default(),
|
AssetPair::default(),
|
||||||
Token::B,
|
Token::B,
|
||||||
3,
|
3,
|
||||||
|
@ -775,7 +775,7 @@ mod test {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
OrderInfo {
|
OrderInfo {
|
||||||
owner: owner.pubkey(),
|
owner: owner.pubkey(),
|
||||||
direction: Direction::To,
|
side: OrderSide::Ask,
|
||||||
pair: AssetPair::default(),
|
pair: AssetPair::default(),
|
||||||
tokens: 1,
|
tokens: 1,
|
||||||
price: 2000,
|
price: 2000,
|
||||||
|
@ -809,7 +809,7 @@ mod test {
|
||||||
let (to_trade, _) = trade(
|
let (to_trade, _) = trade(
|
||||||
&client,
|
&client,
|
||||||
&owner,
|
&owner,
|
||||||
Direction::To,
|
OrderSide::Ask,
|
||||||
AssetPair::default(),
|
AssetPair::default(),
|
||||||
Token::A,
|
Token::A,
|
||||||
3,
|
3,
|
||||||
|
@ -819,7 +819,7 @@ mod test {
|
||||||
let (from_trade, _) = trade(
|
let (from_trade, _) = trade(
|
||||||
&client,
|
&client,
|
||||||
&owner,
|
&owner,
|
||||||
Direction::From,
|
OrderSide::Bid,
|
||||||
AssetPair::default(),
|
AssetPair::default(),
|
||||||
Token::B,
|
Token::B,
|
||||||
3,
|
3,
|
||||||
|
|
|
@ -118,19 +118,19 @@ impl TokenAccountInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Direction of the exchange between two tokens in a pair
|
/// side of the exchange between two tokens in a pair
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||||
pub enum Direction {
|
pub enum OrderSide {
|
||||||
/// Trade first token type (primary) in the pair 'To' the second
|
/// Offer the Base asset and Accept the Quote asset
|
||||||
To,
|
Ask, // to
|
||||||
/// Trade first token type in the pair 'From' the second (secondary)
|
/// Offer the Quote asset and Accept the Base asset
|
||||||
From,
|
Bid, // from
|
||||||
}
|
}
|
||||||
impl fmt::Display for Direction {
|
impl fmt::Display for OrderSide {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Direction::To => write!(f, "T")?,
|
OrderSide::Ask => write!(f, "A")?,
|
||||||
Direction::From => write!(f, "F")?,
|
OrderSide::Bid => write!(f, "B")?,
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -141,11 +141,11 @@ impl fmt::Display for Direction {
|
||||||
pub struct OrderInfo {
|
pub struct OrderInfo {
|
||||||
/// Owner of the trade order
|
/// Owner of the trade order
|
||||||
pub owner: Pubkey,
|
pub owner: Pubkey,
|
||||||
/// Direction of the exchange
|
/// side of the order in the market (bid/ask)
|
||||||
pub direction: Direction,
|
pub side: OrderSide,
|
||||||
/// Token pair indicating two tokens to exchange, first is primary
|
/// Token pair indicating two tokens to exchange, first is primary
|
||||||
pub pair: AssetPair,
|
pub pair: AssetPair,
|
||||||
/// Number of tokens to exchange; primary or secondary depending on direction. Once
|
/// Number of tokens to exchange; primary or secondary depending on side. Once
|
||||||
/// this number goes to zero this trade order will be converted into a regular token account
|
/// this number goes to zero this trade order will be converted into a regular token account
|
||||||
pub tokens: u64,
|
pub tokens: u64,
|
||||||
/// Scaled price of the secondary token given the primary is equal to the scale value
|
/// Scaled price of the secondary token given the primary is equal to the scale value
|
||||||
|
@ -160,7 +160,7 @@ impl Default for OrderInfo {
|
||||||
Self {
|
Self {
|
||||||
owner: Pubkey::default(),
|
owner: Pubkey::default(),
|
||||||
pair: AssetPair::default(),
|
pair: AssetPair::default(),
|
||||||
direction: Direction::To,
|
side: OrderSide::Ask,
|
||||||
tokens: 0,
|
tokens: 0,
|
||||||
price: 0,
|
price: 0,
|
||||||
tokens_settled: 0,
|
tokens_settled: 0,
|
||||||
|
@ -172,8 +172,8 @@ impl OrderInfo {
|
||||||
self.pair = pair;
|
self.pair = pair;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn direction(mut self, direction: Direction) -> Self {
|
pub fn side(mut self, side: OrderSide) -> Self {
|
||||||
self.direction = direction;
|
self.side = side;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
pub fn tokens(mut self, tokens: u64) -> Self {
|
pub fn tokens(mut self, tokens: u64) -> Self {
|
||||||
|
@ -186,9 +186,9 @@ impl OrderInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_trade(direction: Direction, tokens: u64, price: u64) -> Result<(), ExchangeError> {
|
pub fn check_trade(side: OrderSide, tokens: u64, price: u64) -> Result<(), ExchangeError> {
|
||||||
match direction {
|
match side {
|
||||||
Direction::To => {
|
OrderSide::Ask => {
|
||||||
if tokens * price / SCALER == 0 {
|
if tokens * price / SCALER == 0 {
|
||||||
Err(ExchangeError::InvalidTrade(format!(
|
Err(ExchangeError::InvalidTrade(format!(
|
||||||
"To trade of {} for {}/{} results in 0 tradeable tokens",
|
"To trade of {} for {}/{} results in 0 tradeable tokens",
|
||||||
|
@ -196,7 +196,7 @@ pub fn check_trade(direction: Direction, tokens: u64, price: u64) -> Result<(),
|
||||||
)))?
|
)))?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Direction::From => {
|
OrderSide::Bid => {
|
||||||
if tokens * SCALER / price == 0 {
|
if tokens * SCALER / price == 0 {
|
||||||
Err(ExchangeError::InvalidTrade(format!(
|
Err(ExchangeError::InvalidTrade(format!(
|
||||||
"From trade of {} for {}?{} results in 0 tradeable tokens",
|
"From trade of {} for {}?{} results in 0 tradeable tokens",
|
||||||
|
|
Loading…
Reference in New Issue