From 6796b08909fc4b30b035f0a72ab2def629eb2a77 Mon Sep 17 00:00:00 2001 From: Greg Fitzgerald Date: Mon, 2 Dec 2019 15:42:05 -0700 Subject: [PATCH] Migrate to thiserror (#7177) * Migrate to thiserror * Discourage the use of other modules' Result alias `io::Result` set a bad precedent. Don't import other `Result` aliases. --- Cargo.lock | 26 +++++++++++++++++ ledger/Cargo.toml | 1 + ledger/src/bank_forks.rs | 22 +++++--------- ledger/src/block_error.rs | 9 +++++- ledger/src/blocktree.rs | 8 ++---- ledger/src/blocktree_db.rs | 31 ++++---------------- ledger/src/blocktree_processor.rs | 20 +++++++------ ledger/src/rooted_slot_iterator.rs | 1 + ledger/src/shred.rs | 22 +++++++------- ledger/src/snapshot_utils.rs | 32 +++++++-------------- programs/budget/Cargo.toml | 1 + programs/budget/src/budget_instruction.rs | 17 ++--------- programs/ownable/Cargo.toml | 1 + programs/ownable/src/ownable_instruction.rs | 17 ++--------- programs/stake/Cargo.toml | 1 + programs/stake/src/stake_instruction.rs | 25 ++++++++-------- programs/vest/Cargo.toml | 1 + programs/vest/src/vest_instruction.rs | 6 +++- programs/vote/Cargo.toml | 1 + programs/vote/src/vote_instruction.rs | 26 ++++++----------- 20 files changed, 122 insertions(+), 146 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e7f1fbe0..8d0d829ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3184,6 +3184,7 @@ dependencies = [ "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "solana-runtime 0.22.0", "solana-sdk 0.22.0", + "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3577,6 +3578,7 @@ dependencies = [ "sys-info 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3776,6 +3778,7 @@ dependencies = [ "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", "solana-runtime 0.22.0", "solana-sdk 0.22.0", + "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3913,6 +3916,7 @@ dependencies = [ "solana-metrics 0.22.0", "solana-sdk 0.22.0", "solana-vote-program 0.22.0", + "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4009,6 +4013,7 @@ dependencies = [ "solana-config-program 0.22.0", "solana-runtime 0.22.0", "solana-sdk 0.22.0", + "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4024,6 +4029,7 @@ dependencies = [ "solana-logger 0.22.0", "solana-metrics 0.22.0", "solana-sdk 0.22.0", + "thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -4681,6 +4687,24 @@ dependencies = [ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "thiserror" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thiserror-impl 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread-id" version = "2.0.0" @@ -5760,6 +5784,8 @@ dependencies = [ "checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thiserror 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "cc6b305ec0e323c7b6cfff6098a22516e0063d0bb7c3d88660a890217dca099a" +"checksum thiserror-impl 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45ba8d810d9c48fc456b7ad54574e8bfb7c7918a57ad7a6e6a0985d7959e8597" "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" "checksum thread-id 3.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7fbf4c9d56b320106cd64fd024dadfa0be7cb4706725fc44a7d7ce952d820c1" "checksum thread-scoped 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcbb6aa301e5d3b0b5ef639c9a9c7e2f1c944f177b460c04dc24c69b1fa2bd99" diff --git a/ledger/Cargo.toml b/ledger/Cargo.toml index 1462f55e6..af7c14207 100644 --- a/ledger/Cargo.toml +++ b/ledger/Cargo.toml @@ -44,6 +44,7 @@ solana-stake-program = { path = "../programs/stake", version = "0.22.0" } solana-vote-program = { path = "../programs/vote", version = "0.22.0" } sys-info = "0.5.8" tar = "0.4.26" +thiserror = "1.0" tempfile = "3.1.0" [dependencies.rocksdb] diff --git a/ledger/src/bank_forks.rs b/ledger/src/bank_forks.rs index 4dc132db2..9a7a3c61f 100644 --- a/ledger/src/bank_forks.rs +++ b/ledger/src/bank_forks.rs @@ -14,6 +14,7 @@ use std::{ sync::Arc, time::Instant, }; +use thiserror::Error; #[derive(Clone, Debug, Eq, PartialEq)] pub struct SnapshotConfig { @@ -27,24 +28,15 @@ pub struct SnapshotConfig { pub snapshot_path: PathBuf, } -#[derive(Debug)] +#[derive(Error, Debug)] pub enum BankForksError { - SnapshotError(SnapshotError), - SnapshotPackageSendError(SnapshotPackageSendError), -} -pub type Result = std::result::Result; + #[error("snapshot error")] + SnapshotError(#[from] SnapshotError), -impl std::convert::From for BankForksError { - fn from(e: SnapshotError) -> BankForksError { - BankForksError::SnapshotError(e) - } -} - -impl std::convert::From for BankForksError { - fn from(e: SnapshotPackageSendError) -> BankForksError { - BankForksError::SnapshotPackageSendError(e) - } + #[error("snapshot package send error")] + SnapshotPackageSendError(#[from] SnapshotPackageSendError), } +type Result = std::result::Result; pub struct BankForks { pub banks: HashMap>, diff --git a/ledger/src/block_error.rs b/ledger/src/block_error.rs index a60aafabb..91e5243c2 100644 --- a/ledger/src/block_error.rs +++ b/ledger/src/block_error.rs @@ -1,18 +1,25 @@ -#[derive(Debug, PartialEq)] +use thiserror::Error; + +#[derive(Error, Debug, PartialEq)] pub enum BlockError { /// Block entries hashes must all be valid + #[error("invalid entry hash")] InvalidEntryHash, /// Blocks must end in a tick that has been marked as the last tick. + #[error("invalid last tick")] InvalidLastTick, /// Blocks can not have extra ticks or missing ticks + #[error("invalid tick count")] InvalidTickCount, /// All ticks must contain the same number of hashes within a block + #[error("invalid tick hash count")] InvalidTickHashCount, /// Blocks must end in a tick entry, trailing transaction entries are not allowed to guarantee /// that each block has the same number of hashes + #[error("trailing entry")] TrailingEntry, } diff --git a/ledger/src/blocktree.rs b/ledger/src/blocktree.rs index e08c8d551..c9ca6093a 100644 --- a/ledger/src/blocktree.rs +++ b/ledger/src/blocktree.rs @@ -1,9 +1,11 @@ //! The `blocktree` module provides functions for parallel verification of the //! Proof of History ledger as well as iterative read, append write, and random //! access read to a persistent file-based ledger. +pub use crate::{blocktree_db::BlocktreeError, blocktree_meta::SlotMeta}; use crate::{ blocktree_db::{ - columns as cf, Column, Database, IteratorDirection, IteratorMode, LedgerColumn, WriteBatch, + columns as cf, Column, Database, IteratorDirection, IteratorMode, LedgerColumn, Result, + WriteBatch, }, blocktree_meta::*, entry::{create_ticks, Entry}, @@ -11,10 +13,6 @@ use crate::{ leader_schedule_cache::LeaderScheduleCache, shred::{Shred, Shredder}, }; -pub use crate::{ - blocktree_db::{BlocktreeError, Result}, - blocktree_meta::SlotMeta, -}; use bincode::deserialize; use chrono::{offset::TimeZone, Duration as ChronoDuration, Utc}; use log::*; diff --git a/ledger/src/blocktree_db.rs b/ledger/src/blocktree_db.rs index 67bac239d..8e0578065 100644 --- a/ledger/src/blocktree_db.rs +++ b/ledger/src/blocktree_db.rs @@ -12,6 +12,7 @@ use serde::Serialize; use solana_client::rpc_request::RpcTransactionStatus; use solana_sdk::{clock::Slot, signature::Signature}; use std::{collections::HashMap, fs, marker::PhantomData, path::Path, sync::Arc}; +use thiserror::Error; // A good value for this is the number of cores on the machine const TOTAL_THREADS: i32 = 8; @@ -35,18 +36,16 @@ const CODE_SHRED_CF: &str = "code_shred"; /// Column family for Transaction Status const TRANSACTION_STATUS_CF: &str = "transaction_status"; -#[derive(Debug)] +#[derive(Error, Debug)] pub enum BlocktreeError { ShredForIndexExists, InvalidShredData(Box), - RocksDb(rocksdb::Error), + RocksDb(#[from] rocksdb::Error), SlotNotRooted, - IO(std::io::Error), - Serialize(std::boxed::Box), + IO(#[from] std::io::Error), + Serialize(#[from] Box), } -pub type Result = std::result::Result; - -impl std::error::Error for BlocktreeError {} +pub(crate) type Result = std::result::Result; impl std::fmt::Display for BlocktreeError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -54,24 +53,6 @@ impl std::fmt::Display for BlocktreeError { } } -impl std::convert::From for BlocktreeError { - fn from(e: std::io::Error) -> BlocktreeError { - BlocktreeError::IO(e) - } -} - -impl std::convert::From> for BlocktreeError { - fn from(e: std::boxed::Box) -> BlocktreeError { - BlocktreeError::Serialize(e) - } -} - -impl std::convert::From for BlocktreeError { - fn from(e: rocksdb::Error) -> BlocktreeError { - BlocktreeError::RocksDb(e) - } -} - pub enum IteratorMode { Start, End, diff --git a/ledger/src/blocktree_processor.rs b/ledger/src/blocktree_processor.rs index de6c42786..1a496c61c 100644 --- a/ledger/src/blocktree_processor.rs +++ b/ledger/src/blocktree_processor.rs @@ -31,6 +31,7 @@ use std::{ sync::Arc, time::{Duration, Instant}, }; +use thiserror::Error; thread_local!(static PAR_THREAD_POOL: RefCell = RefCell::new(rayon::ThreadPoolBuilder::new() .num_threads(get_thread_count()) @@ -224,18 +225,19 @@ pub struct BankForksInfo { pub bank_slot: u64, } -#[derive(Debug, PartialEq)] +#[derive(Error, Debug, PartialEq)] pub enum BlocktreeProcessorError { + #[error("failed to load entries")] FailedToLoadEntries, - FailedToLoadMeta, - InvalidBlock(BlockError), - InvalidTransaction, -} -impl From for BlocktreeProcessorError { - fn from(block_error: BlockError) -> Self { - BlocktreeProcessorError::InvalidBlock(block_error) - } + #[error("failed to load meta")] + FailedToLoadMeta, + + #[error("invalid block")] + InvalidBlock(#[from] BlockError), + + #[error("invalid transaction")] + InvalidTransaction, } /// Callback for accessing bank state while processing the blocktree diff --git a/ledger/src/rooted_slot_iterator.rs b/ledger/src/rooted_slot_iterator.rs index 3feb01c8e..5747f2cfb 100644 --- a/ledger/src/rooted_slot_iterator.rs +++ b/ledger/src/rooted_slot_iterator.rs @@ -1,3 +1,4 @@ +use crate::blocktree_db::Result; use crate::{blocktree::*, blocktree_meta::SlotMeta}; use log::*; use solana_sdk::clock::Slot; diff --git a/ledger/src/shred.rs b/ledger/src/shred.rs index 26cbe8898..fead6eafa 100644 --- a/ledger/src/shred.rs +++ b/ledger/src/shred.rs @@ -21,6 +21,7 @@ use solana_sdk::{ }; use std::mem::size_of; use std::{sync::Arc, time::Instant}; +use thiserror::Error; /// The following constants are computed by hand, and hardcoded. /// `test_shred_constants` ensures that the values are correct. @@ -52,22 +53,23 @@ pub const SHRED_TICK_REFERENCE_MASK: u8 = 0b0011_1111; const LAST_SHRED_IN_SLOT: u8 = 0b1000_0000; pub const DATA_COMPLETE_SHRED: u8 = 0b0100_0000; -#[derive(Debug)] +#[derive(Error, Debug)] pub enum ShredError { + #[error("invalid shred type")] InvalidShredType, - InvalidFecRate(f32), // FEC rate must be more than 0.0 and less than 1.0 - SlotTooLow { slot: Slot, parent_slot: Slot }, // "Current slot must be > Parent slot, but the difference must not be > u16::MAX - Serialize(std::boxed::Box), + + #[error("invalid FEC rate; must be 0.0 < {0} < 1.0")] + InvalidFecRate(f32), + + #[error("slot too low; current slot {slot} must be above parent slot {parent_slot}, but the difference must be below u16::MAX")] + SlotTooLow { slot: Slot, parent_slot: Slot }, + + #[error("serialization error")] + Serialize(#[from] Box), } pub type Result = std::result::Result; -impl std::convert::From> for ShredError { - fn from(e: std::boxed::Box) -> ShredError { - ShredError::Serialize(e) - } -} - #[derive(Serialize, Clone, Deserialize, PartialEq, Debug)] pub struct ShredType(pub u8); impl Default for ShredType { diff --git a/ledger/src/snapshot_utils.rs b/ledger/src/snapshot_utils.rs index fa09d108d..4b5d89626 100644 --- a/ledger/src/snapshot_utils.rs +++ b/ledger/src/snapshot_utils.rs @@ -14,6 +14,7 @@ use std::{ path::{Path, PathBuf}, }; use tar::Archive; +use thiserror::Error; pub const SNAPSHOT_STATUS_CACHE_FILE_NAME: &str = "status_cache"; pub const TAR_SNAPSHOTS_DIR: &str = "snapshots"; @@ -25,32 +26,19 @@ pub struct SlotSnapshotPaths { pub snapshot_file_path: PathBuf, } -#[derive(Debug)] +#[derive(Error, Debug)] pub enum SnapshotError { - IO(std::io::Error), - Serialize(std::boxed::Box), - FsExtra(fs_extra::error::Error), + #[error("I/O error")] + IO(#[from] std::io::Error), + + #[error("serialization error")] + Serialize(#[from] Box), + + #[error("file system error")] + FsExtra(#[from] fs_extra::error::Error), } pub type Result = std::result::Result; -impl std::convert::From for SnapshotError { - fn from(e: std::io::Error) -> SnapshotError { - SnapshotError::IO(e) - } -} - -impl std::convert::From> for SnapshotError { - fn from(e: std::boxed::Box) -> SnapshotError { - SnapshotError::Serialize(e) - } -} - -impl std::convert::From for SnapshotError { - fn from(e: fs_extra::error::Error) -> SnapshotError { - SnapshotError::FsExtra(e) - } -} - impl PartialOrd for SlotSnapshotPaths { fn partial_cmp(&self, other: &Self) -> Option { Some(self.slot.cmp(&other.slot)) diff --git a/programs/budget/Cargo.toml b/programs/budget/Cargo.toml index ca3b65966..6d0ba80ca 100644 --- a/programs/budget/Cargo.toml +++ b/programs/budget/Cargo.toml @@ -17,6 +17,7 @@ num-traits = "0.2" serde = "1.0.103" serde_derive = "1.0.103" solana-sdk = { path = "../../sdk", version = "0.22.0" } +thiserror = "1.0" [dev-dependencies] solana-runtime = { path = "../../runtime", version = "0.22.0" } diff --git a/programs/budget/src/budget_instruction.rs b/programs/budget/src/budget_instruction.rs index 87705595b..b4736536e 100644 --- a/programs/budget/src/budget_instruction.rs +++ b/programs/budget/src/budget_instruction.rs @@ -10,9 +10,11 @@ use solana_sdk::{ pubkey::Pubkey, system_instruction, }; +use thiserror::Error; -#[derive(Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)] +#[derive(Error, Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)] pub enum BudgetError { + #[error("destination missing")] DestinationMissing, } @@ -22,19 +24,6 @@ impl DecodeError for BudgetError { } } -impl std::fmt::Display for BudgetError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( - f, - "{}", - match self { - BudgetError::DestinationMissing => "destination missing", - } - ) - } -} -impl std::error::Error for BudgetError {} - /// An instruction to progress the smart contract. #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub enum BudgetInstruction { diff --git a/programs/ownable/Cargo.toml b/programs/ownable/Cargo.toml index a561c13d4..c9e10bb7e 100644 --- a/programs/ownable/Cargo.toml +++ b/programs/ownable/Cargo.toml @@ -15,6 +15,7 @@ serde_derive = "1.0.103" solana-sdk = { path = "../../sdk", version = "0.22.0" } num-derive = "0.3" num-traits = "0.2" +thiserror = "1.0" [dev-dependencies] solana-runtime = { path = "../../runtime", version = "0.22.0" } diff --git a/programs/ownable/src/ownable_instruction.rs b/programs/ownable/src/ownable_instruction.rs index 71de18877..c567ea73c 100644 --- a/programs/ownable/src/ownable_instruction.rs +++ b/programs/ownable/src/ownable_instruction.rs @@ -5,9 +5,11 @@ use solana_sdk::{ pubkey::Pubkey, system_instruction, }; +use thiserror::Error; -#[derive(Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)] +#[derive(Error, Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)] pub enum OwnableError { + #[error("incorrect error")] IncorrectOwner, } @@ -17,19 +19,6 @@ impl DecodeError for OwnableError { } } -impl std::fmt::Display for OwnableError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( - f, - "{}", - match self { - OwnableError::IncorrectOwner => "incorrect owner", - } - ) - } -} -impl std::error::Error for OwnableError {} - fn initialize_account(account_pubkey: &Pubkey, owner_pubkey: &Pubkey) -> Instruction { let keys = vec![AccountMeta::new(*account_pubkey, false)]; Instruction::new(crate::id(), &owner_pubkey, keys) diff --git a/programs/stake/Cargo.toml b/programs/stake/Cargo.toml index 9e82e4c51..dc42ab289 100644 --- a/programs/stake/Cargo.toml +++ b/programs/stake/Cargo.toml @@ -21,6 +21,7 @@ solana-metrics = { path = "../../metrics", version = "0.22.0" } solana-sdk = { path = "../../sdk", version = "0.22.0" } solana-vote-program = { path = "../vote", version = "0.22.0" } solana-config-program = { path = "../config", version = "0.22.0" } +thiserror = "1.0" [lib] crate-type = ["lib", "cdylib"] diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index ffc10eae7..45fd05f91 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -15,33 +15,32 @@ use solana_sdk::{ self, clock::Clock, rent::Rent, rewards::Rewards, stake_history::StakeHistory, Sysvar, }, }; +use thiserror::Error; /// Reasons the stake might have had an error -#[derive(Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)] +#[derive(Error, Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)] pub enum StakeError { + #[error("not enough credits to redeem")] NoCreditsToRedeem, + + #[error("lockup has not yet expired")] LockupInForce, + + #[error("stake already deactivated")] AlreadyDeactivated, + + #[error("one re-delegation permitted per epoch")] TooSoonToRedelegate, + + #[error("split amount is more than is staked")] InsufficientStake, } + impl DecodeError for StakeError { fn type_of() -> &'static str { "StakeError" } } -impl std::fmt::Display for StakeError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - StakeError::NoCreditsToRedeem => write!(f, "not enough credits to redeem"), - StakeError::LockupInForce => write!(f, "lockup has not yet expired"), - StakeError::AlreadyDeactivated => write!(f, "stake already deactivated"), - StakeError::TooSoonToRedelegate => write!(f, "one re-delegation permitted per epoch"), - StakeError::InsufficientStake => write!(f, "split amount is more than is staked"), - } - } -} -impl std::error::Error for StakeError {} #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub enum StakeInstruction { diff --git a/programs/vest/Cargo.toml b/programs/vest/Cargo.toml index 216f9b27e..2a3dd669e 100644 --- a/programs/vest/Cargo.toml +++ b/programs/vest/Cargo.toml @@ -18,6 +18,7 @@ serde = "1.0.103" serde_derive = "1.0.103" solana-sdk = { path = "../../sdk", version = "0.22.0" } solana-config-program = { path = "../config", version = "0.22.0" } +thiserror = "1.0" [dev-dependencies] solana-runtime = { path = "../../runtime", version = "0.22.0" } diff --git a/programs/vest/src/vest_instruction.rs b/programs/vest/src/vest_instruction.rs index 42b7ff48e..632381760 100644 --- a/programs/vest/src/vest_instruction.rs +++ b/programs/vest/src/vest_instruction.rs @@ -9,10 +9,14 @@ use solana_sdk::{ pubkey::Pubkey, system_instruction, }; +use thiserror::Error; -#[derive(Debug, Clone, PartialEq, FromPrimitive)] +#[derive(Error, Debug, Clone, PartialEq, FromPrimitive)] pub enum VestError { + #[error("destination missing")] DestinationMissing, + + #[error("unauthorized")] Unauthorized, } diff --git a/programs/vote/Cargo.toml b/programs/vote/Cargo.toml index 9b2e8151a..de0e4d032 100644 --- a/programs/vote/Cargo.toml +++ b/programs/vote/Cargo.toml @@ -18,6 +18,7 @@ serde_derive = "1.0.103" solana-logger = { path = "../../logger", version = "0.22.0" } solana-metrics = { path = "../../metrics", version = "0.22.0" } solana-sdk = { path = "../../sdk", version = "0.22.0" } +thiserror = "1.0" [lib] crate-type = ["lib", "cdylib"] diff --git a/programs/vote/src/vote_instruction.rs b/programs/vote/src/vote_instruction.rs index 1975e9ddc..70f4d3902 100644 --- a/programs/vote/src/vote_instruction.rs +++ b/programs/vote/src/vote_instruction.rs @@ -17,13 +17,21 @@ use solana_sdk::{ system_instruction, sysvar::{self, clock::Clock, slot_hashes::SlotHashes, Sysvar}, }; +use thiserror::Error; /// Reasons the stake might have had an error -#[derive(Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)] +#[derive(Error, Debug, Clone, PartialEq, FromPrimitive, ToPrimitive)] pub enum VoteError { + #[error("vote already recorded or not in slot hashes history")] VoteTooOld, + + #[error("vote slots do not match bank history")] SlotsMismatch, + + #[error("vote hash does not match bank hash")] SlotHashMismatch, + + #[error("vote has no slots, invalid")] EmptySlots, } impl DecodeError for VoteError { @@ -32,22 +40,6 @@ impl DecodeError for VoteError { } } -impl std::fmt::Display for VoteError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!( - f, - "{}", - match self { - VoteError::VoteTooOld => "vote already recorded or not in slot hashes history", - VoteError::SlotsMismatch => "vote slots do not match bank history", - VoteError::SlotHashMismatch => "vote hash does not match bank hash", - VoteError::EmptySlots => "vote has no slots, invalid", - } - ) - } -} -impl std::error::Error for VoteError {} - #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] pub enum VoteInstruction { /// Initialize the VoteState for this `vote account`