From 71f77a8e0a0477514322927488ebf206643d200c Mon Sep 17 00:00:00 2001 From: Jack May Date: Fri, 14 Feb 2020 14:52:14 -0800 Subject: [PATCH] Remove Exchange program's use of GenericError (#8290) automerge --- Cargo.lock | 3 ++ programs/exchange/Cargo.toml | 3 ++ programs/exchange/src/exchange_processor.rs | 52 +++++++++++++++------ 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0bc2ff980..51bf0c891 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3915,12 +3915,15 @@ version = "0.24.0" dependencies = [ "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)", + "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_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", "solana-logger 0.24.0", "solana-metrics 0.24.0", "solana-runtime 0.24.0", "solana-sdk 0.24.0", + "thiserror 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/programs/exchange/Cargo.toml b/programs/exchange/Cargo.toml index e8c6d940b..866fa888b 100644 --- a/programs/exchange/Cargo.toml +++ b/programs/exchange/Cargo.toml @@ -11,11 +11,14 @@ edition = "2018" [dependencies] bincode = "1.2.1" log = "0.4.8" +num-derive = { version = "0.3" } +num-traits = { version = "0.2" } serde = "1.0.104" serde_derive = "1.0.103" solana-logger = { path = "../../logger", version = "0.24.0" } solana-metrics = { path = "../../metrics", version = "0.24.0" } solana-sdk = { path = "../../sdk", version = "0.24.0" } +thiserror = "1.0" [dev-dependencies] solana-runtime = { path = "../../runtime", version = "0.24.0" } diff --git a/programs/exchange/src/exchange_processor.rs b/programs/exchange/src/exchange_processor.rs index cc08bd565..38b9fc6fb 100644 --- a/programs/exchange/src/exchange_processor.rs +++ b/programs/exchange/src/exchange_processor.rs @@ -4,12 +4,36 @@ use crate::exchange_instruction::*; use crate::exchange_state::*; use crate::faucet; use log::*; +use num_derive::{FromPrimitive, ToPrimitive}; +use serde_derive::Serialize; use solana_metrics::inc_new_counter_info; -use solana_sdk::account::KeyedAccount; -use solana_sdk::instruction::InstructionError; -use solana_sdk::program_utils::limited_deserialize; -use solana_sdk::pubkey::Pubkey; +use solana_sdk::{ + account::KeyedAccount, instruction::InstructionError, program_utils::limited_deserialize, + program_utils::DecodeError, pubkey::Pubkey, +}; 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 DecodeError for ExchangeError { + fn type_of() -> &'static str { + "ExchangeError" + } +} pub struct ExchangeProcessor {} @@ -56,7 +80,7 @@ impl ExchangeProcessor { Ok(_) => Ok(()), Err(e) => { error!("Serialize failed: {:?}", e); - Err(InstructionError::GenericError) + Err(ExchangeError::SerializeFailed.into()) } } } @@ -204,12 +228,12 @@ impl ExchangeProcessor { ExchangeState::Account(mut from_account) => { if &from_account.owner != keyed_accounts[OWNER_INDEX].unsigned_key() { error!("Signer does not own from account"); - return Err(InstructionError::GenericError); + return Err(ExchangeError::SignerDoesNotOwnAccount.into()); } if from_account.tokens[token] < tokens { error!("From account balance too low"); - return Err(InstructionError::GenericError); + return Err(ExchangeError::FromAccountBalanceTooLow.into()); } from_account.tokens[token] -= tokens; @@ -225,7 +249,7 @@ impl ExchangeProcessor { ExchangeState::Trade(mut from_trade) => { if &from_trade.owner != keyed_accounts[OWNER_INDEX].unsigned_key() { error!("Signer does not own from account"); - return Err(InstructionError::GenericError); + return Err(ExchangeError::SignerDoesNotOwnAccount.into()); } let from_token = match from_trade.side { @@ -234,12 +258,12 @@ impl ExchangeProcessor { }; if token != from_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 { error!("From trade balance too low"); - return Err(InstructionError::GenericError); + return Err(ExchangeError::FromTradeBalanceTooLow.into()); } from_trade.tokens_settled -= tokens; @@ -285,7 +309,7 @@ impl ExchangeProcessor { if &account.owner != keyed_accounts[OWNER_INDEX].unsigned_key() { error!("Signer does not own account"); - return Err(InstructionError::GenericError); + return Err(ExchangeError::SignerDoesNotOwnAccount.into()); } let from_token = match info.side { OrderSide::Ask => info.pair.Base, @@ -293,7 +317,7 @@ impl ExchangeProcessor { }; if account.tokens[from_token] < info.tokens { 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) { @@ -334,8 +358,8 @@ impl ExchangeProcessor { let order = Self::deserialize_order(&keyed_accounts[ORDER_INDEX].try_account_ref()?.data)?; if &order.owner != keyed_accounts[OWNER_INDEX].unsigned_key() { - error!("Signer does not own trade"); - return Err(InstructionError::GenericError); + error!("Signer does not own order"); + return Err(ExchangeError::SignerDoesNotOwnOrder.into()); } let token = match order.side {