diff --git a/common/blockchain/Cargo.toml b/common/blockchain/Cargo.toml index 722adc9a..87764a38 100644 --- a/common/blockchain/Cargo.toml +++ b/common/blockchain/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] borsh.workspace = true derive_more.workspace = true +strum.workspace = true lib = { workspace = true, features = ["borsh"] } diff --git a/common/blockchain/src/block.rs b/common/blockchain/src/block.rs index b826c613..45f8b8f6 100644 --- a/common/blockchain/src/block.rs +++ b/common/blockchain/src/block.rs @@ -45,7 +45,7 @@ pub struct Block { } /// Error while generating new block. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, strum::IntoStaticStr)] pub enum GenerateError { /// Host height went backwards. BadHostHeight, diff --git a/common/blockchain/src/manager.rs b/common/blockchain/src/manager.rs index 3d26cb04..6cd6d2e0 100644 --- a/common/blockchain/src/manager.rs +++ b/common/blockchain/src/manager.rs @@ -55,7 +55,9 @@ struct PendingBlock { pub struct BadGenesis; /// Error while generating a new block. -#[derive(Clone, Debug, PartialEq, Eq, derive_more::From)] +#[derive( + Clone, Debug, PartialEq, Eq, derive_more::From, strum::IntoStaticStr, +)] pub enum GenerateError { /// Last block hasn’t been signed by enough validators yet. HasPendingBlock, diff --git a/solana/solana-ibc/programs/solana-ibc/Cargo.toml b/solana/solana-ibc/programs/solana-ibc/Cargo.toml index 5508b968..73886b13 100644 --- a/solana/solana-ibc/programs/solana-ibc/Cargo.toml +++ b/solana/solana-ibc/programs/solana-ibc/Cargo.toml @@ -19,6 +19,7 @@ mocks = ["ibc/mocks", "ibc/std"] anchor-lang.workspace = true base64.workspace = true bytemuck.workspace = true +derive_more.workspace = true ibc-proto.workspace = true ibc.workspace = true serde.workspace = true diff --git a/solana/solana-ibc/programs/solana-ibc/src/error.rs b/solana/solana-ibc/programs/solana-ibc/src/error.rs new file mode 100644 index 00000000..b4c439f9 --- /dev/null +++ b/solana/solana-ibc/programs/solana-ibc/src/error.rs @@ -0,0 +1,37 @@ +/// Error returned when handling a request. +// Note: When changing variants in the enum, try to preserve indexes of each +// variant. The position is translated into error code returned by Anchor and +// keeping them consistent makes things easier. +#[derive(strum::EnumDiscriminants, strum::IntoStaticStr)] +#[strum_discriminants(repr(u32))] +#[allow(clippy::enum_variant_names)] +pub(crate) enum Error { + /// Error handling an IBC request. + RouterError(ibc::core::RouterError), +} + +impl Error { + pub fn name(&self) -> String { <&'static str>::from(self).into() } +} + +impl core::fmt::Display for Error { + fn fmt(&self, fmtr: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::RouterError(err) => err.fmt(fmtr), + } + } +} + +impl From for u32 { + fn from(err: Error) -> u32 { + let code = ErrorDiscriminants::from(err) as u32; + anchor_lang::error::ERROR_CODE_OFFSET + code + } +} + +impl From<&Error> for u32 { + fn from(err: &Error) -> u32 { + let code = ErrorDiscriminants::from(err) as u32; + anchor_lang::error::ERROR_CODE_OFFSET + code + } +} diff --git a/solana/solana-ibc/programs/solana-ibc/src/lib.rs b/solana/solana-ibc/programs/solana-ibc/src/lib.rs index c73d4364..058d1976 100644 --- a/solana/solana-ibc/programs/solana-ibc/src/lib.rs +++ b/solana/solana-ibc/programs/solana-ibc/src/lib.rs @@ -10,6 +10,7 @@ use ibc::core::router::{Module, ModuleId, Router}; const SOLANA_IBC_STORAGE_SEED: &[u8] = b"solana_ibc_storage"; const TRIE_SEED: &[u8] = b"trie"; const PACKET_SEED: &[u8] = b"packet"; + const CONNECTION_ID_PREFIX: &str = "connection-"; const CHANNEL_ID_PREFIX: &str = "channel-"; use ibc::core::MsgEnvelope; @@ -21,6 +22,7 @@ declare_id!("EnfDJsAK7BGgetnmKzBx86CsgC5kfSPcsktFCQ4YLC81"); mod client_state; mod consensus_state; mod ed25519; +mod error; mod execution_context; mod storage; #[cfg(test)] @@ -55,11 +57,9 @@ pub mod solana_ibc { { let mut router = store.clone(); - if let Err(e) = - ibc::core::dispatch(&mut store, &mut router, message.clone()) - { - return err!(Error::RouterError(&e)); - } + ibc::core::dispatch(&mut store, &mut router, message.clone()) + .map_err(error::Error::RouterError) + .map_err(|err| error!((&err)))?; } if let MsgEnvelope::Packet(packet) = message { // store the packet if not exists @@ -89,7 +89,7 @@ pub struct Deliver<'info> { sender: Signer<'info>, /// The account holding private IBC storage. - #[account(init_if_needed, payer = sender, seeds = [SOLANA_IBC_STORAGE_SEED],bump, space = 10000)] + #[account(init_if_needed, payer = sender, seeds = [SOLANA_IBC_STORAGE_SEED], bump, space = 10000)] storage: Account<'info, storage::PrivateStorage>, /// The account holding provable IBC storage, i.e. the trie. @@ -106,32 +106,6 @@ pub struct Deliver<'info> { system_program: Program<'info, System>, } -/// Error returned when handling a request. -#[derive(Clone, strum::AsRefStr, strum::EnumDiscriminants)] -#[strum_discriminants(repr(u32))] -pub enum Error<'a> { - RouterError(&'a ibc::core::RouterError), -} - -impl Error<'_> { - pub fn name(&self) -> String { self.as_ref().into() } -} - -impl core::fmt::Display for Error<'_> { - fn fmt(&self, fmtr: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::RouterError(err) => write!(fmtr, "{err}"), - } - } -} - -impl From> for u32 { - fn from(err: Error<'_>) -> u32 { - let code = ErrorDiscriminants::from(err) as u32; - anchor_lang::error::ERROR_CODE_OFFSET + code - } -} - #[event] pub struct EmitIBCEvent { pub ibc_event: Vec,