parent
644a7f9a44
commit
71f77a8e0a
|
@ -3915,12 +3915,15 @@ version = "0.24.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"solana-logger 0.24.0",
|
"solana-logger 0.24.0",
|
||||||
"solana-metrics 0.24.0",
|
"solana-metrics 0.24.0",
|
||||||
"solana-runtime 0.24.0",
|
"solana-runtime 0.24.0",
|
||||||
"solana-sdk 0.24.0",
|
"solana-sdk 0.24.0",
|
||||||
|
"thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -11,11 +11,14 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bincode = "1.2.1"
|
bincode = "1.2.1"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
|
num-derive = { version = "0.3" }
|
||||||
|
num-traits = { version = "0.2" }
|
||||||
serde = "1.0.104"
|
serde = "1.0.104"
|
||||||
serde_derive = "1.0.103"
|
serde_derive = "1.0.103"
|
||||||
solana-logger = { path = "../../logger", version = "0.24.0" }
|
solana-logger = { path = "../../logger", version = "0.24.0" }
|
||||||
solana-metrics = { path = "../../metrics", version = "0.24.0" }
|
solana-metrics = { path = "../../metrics", version = "0.24.0" }
|
||||||
solana-sdk = { path = "../../sdk", version = "0.24.0" }
|
solana-sdk = { path = "../../sdk", version = "0.24.0" }
|
||||||
|
thiserror = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
solana-runtime = { path = "../../runtime", version = "0.24.0" }
|
solana-runtime = { path = "../../runtime", version = "0.24.0" }
|
||||||
|
|
|
@ -4,12 +4,36 @@ use crate::exchange_instruction::*;
|
||||||
use crate::exchange_state::*;
|
use crate::exchange_state::*;
|
||||||
use crate::faucet;
|
use crate::faucet;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use num_derive::{FromPrimitive, ToPrimitive};
|
||||||
|
use serde_derive::Serialize;
|
||||||
use solana_metrics::inc_new_counter_info;
|
use solana_metrics::inc_new_counter_info;
|
||||||
use solana_sdk::account::KeyedAccount;
|
use solana_sdk::{
|
||||||
use solana_sdk::instruction::InstructionError;
|
account::KeyedAccount, instruction::InstructionError, program_utils::limited_deserialize,
|
||||||
use solana_sdk::program_utils::limited_deserialize;
|
program_utils::DecodeError, pubkey::Pubkey,
|
||||||
use solana_sdk::pubkey::Pubkey;
|
};
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug, Serialize, Clone, PartialEq, FromPrimitive, ToPrimitive)]
|
||||||
|
pub enum ExchangeError {
|
||||||
|
#[error("Signer does not own account")]
|
||||||
|
SignerDoesNotOwnAccount,
|
||||||
|
#[error("Signer does not own order")]
|
||||||
|
SignerDoesNotOwnOrder,
|
||||||
|
#[error("The From account balance is too low")]
|
||||||
|
FromAccountBalanceTooLow,
|
||||||
|
#[error("Attmept operation on mismatched tokens")]
|
||||||
|
TokenMismatch,
|
||||||
|
#[error("From trade balance is too low")]
|
||||||
|
FromTradeBalanceTooLow,
|
||||||
|
#[error("Serialization failed")]
|
||||||
|
SerializeFailed,
|
||||||
|
}
|
||||||
|
impl<T> DecodeError<T> for ExchangeError {
|
||||||
|
fn type_of() -> &'static str {
|
||||||
|
"ExchangeError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ExchangeProcessor {}
|
pub struct ExchangeProcessor {}
|
||||||
|
|
||||||
|
@ -56,7 +80,7 @@ impl ExchangeProcessor {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Serialize failed: {:?}", e);
|
error!("Serialize failed: {:?}", e);
|
||||||
Err(InstructionError::GenericError)
|
Err(ExchangeError::SerializeFailed.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,12 +228,12 @@ impl ExchangeProcessor {
|
||||||
ExchangeState::Account(mut from_account) => {
|
ExchangeState::Account(mut from_account) => {
|
||||||
if &from_account.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
|
if &from_account.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
|
||||||
error!("Signer does not own from account");
|
error!("Signer does not own from account");
|
||||||
return Err(InstructionError::GenericError);
|
return Err(ExchangeError::SignerDoesNotOwnAccount.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if from_account.tokens[token] < tokens {
|
if from_account.tokens[token] < tokens {
|
||||||
error!("From account balance too low");
|
error!("From account balance too low");
|
||||||
return Err(InstructionError::GenericError);
|
return Err(ExchangeError::FromAccountBalanceTooLow.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
from_account.tokens[token] -= tokens;
|
from_account.tokens[token] -= tokens;
|
||||||
|
@ -225,7 +249,7 @@ impl ExchangeProcessor {
|
||||||
ExchangeState::Trade(mut from_trade) => {
|
ExchangeState::Trade(mut from_trade) => {
|
||||||
if &from_trade.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
|
if &from_trade.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
|
||||||
error!("Signer does not own from account");
|
error!("Signer does not own from account");
|
||||||
return Err(InstructionError::GenericError);
|
return Err(ExchangeError::SignerDoesNotOwnAccount.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let from_token = match from_trade.side {
|
let from_token = match from_trade.side {
|
||||||
|
@ -234,12 +258,12 @@ impl ExchangeProcessor {
|
||||||
};
|
};
|
||||||
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");
|
||||||
return Err(InstructionError::GenericError);
|
return Err(ExchangeError::TokenMismatch.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if from_trade.tokens_settled < tokens {
|
if from_trade.tokens_settled < tokens {
|
||||||
error!("From trade balance too low");
|
error!("From trade balance too low");
|
||||||
return Err(InstructionError::GenericError);
|
return Err(ExchangeError::FromTradeBalanceTooLow.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
from_trade.tokens_settled -= tokens;
|
from_trade.tokens_settled -= tokens;
|
||||||
|
@ -285,7 +309,7 @@ impl ExchangeProcessor {
|
||||||
|
|
||||||
if &account.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
|
if &account.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
|
||||||
error!("Signer does not own account");
|
error!("Signer does not own account");
|
||||||
return Err(InstructionError::GenericError);
|
return Err(ExchangeError::SignerDoesNotOwnAccount.into());
|
||||||
}
|
}
|
||||||
let from_token = match info.side {
|
let from_token = match info.side {
|
||||||
OrderSide::Ask => info.pair.Base,
|
OrderSide::Ask => info.pair.Base,
|
||||||
|
@ -293,7 +317,7 @@ impl ExchangeProcessor {
|
||||||
};
|
};
|
||||||
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");
|
||||||
return Err(InstructionError::GenericError);
|
return Err(ExchangeError::FromAccountBalanceTooLow.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = check_trade(info.side, info.tokens, info.price) {
|
if let Err(e) = check_trade(info.side, info.tokens, info.price) {
|
||||||
|
@ -334,8 +358,8 @@ impl ExchangeProcessor {
|
||||||
let order = Self::deserialize_order(&keyed_accounts[ORDER_INDEX].try_account_ref()?.data)?;
|
let order = Self::deserialize_order(&keyed_accounts[ORDER_INDEX].try_account_ref()?.data)?;
|
||||||
|
|
||||||
if &order.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
|
if &order.owner != keyed_accounts[OWNER_INDEX].unsigned_key() {
|
||||||
error!("Signer does not own trade");
|
error!("Signer does not own order");
|
||||||
return Err(InstructionError::GenericError);
|
return Err(ExchangeError::SignerDoesNotOwnOrder.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let token = match order.side {
|
let token = match order.side {
|
||||||
|
|
Loading…
Reference in New Issue