synor/crates/synor-ibc/src/error.rs
Gulshan Yadav 6037695afb feat(ibc): add Phase 14 Milestone 1 - Cross-Chain IBC Interoperability
Implements full Inter-Blockchain Communication (IBC) protocol:

synor-ibc crate (new):
- Light client management (create, update, verify headers)
- Connection handshake (4-way: Init, Try, Ack, Confirm)
- Channel handshake (4-way: Init, Try, Ack, Confirm)
- Packet handling (send, receive, acknowledge, timeout)
- Merkle commitment proofs for state verification
- ICS-20 fungible token transfer support
- Atomic swap engine with HTLC (hashlock + timelock)

IBC Bridge Contract (contracts/ibc-bridge):
- Token locking/unlocking for cross-chain transfers
- Relayer whitelist management
- Channel registration and sequence tracking
- HTLC atomic swap (create, claim, refund)
- Event emission for indexing
- 52KB optimized WASM binary

Test coverage: 40 tests passing
2026-01-19 16:51:59 +05:30

163 lines
4.2 KiB
Rust

//! IBC error types
use thiserror::Error;
/// Result type for IBC operations
pub type IbcResult<T> = Result<T, IbcError>;
/// IBC error types
#[derive(Debug, Error)]
pub enum IbcError {
// Client errors
#[error("Client not found: {0}")]
ClientNotFound(String),
#[error("Client already exists: {0}")]
ClientAlreadyExists(String),
#[error("Invalid client state: {0}")]
InvalidClientState(String),
#[error("Client frozen: {0}")]
ClientFrozen(String),
#[error("Client expired: {0}")]
ClientExpired(String),
// Connection errors
#[error("Connection not found: {0}")]
ConnectionNotFound(String),
#[error("Connection already exists: {0}")]
ConnectionAlreadyExists(String),
#[error("Invalid connection state: expected {expected}, got {actual}")]
InvalidConnectionState { expected: String, actual: String },
#[error("Connection version mismatch: {0}")]
ConnectionVersionMismatch(String),
// Channel errors
#[error("Channel not found: port={port}, channel={channel}")]
ChannelNotFound { port: String, channel: String },
#[error("Channel already exists: port={port}, channel={channel}")]
ChannelAlreadyExists { port: String, channel: String },
#[error("Invalid channel state: expected {expected}, got {actual}")]
InvalidChannelState { expected: String, actual: String },
#[error("Port not bound: {0}")]
PortNotBound(String),
#[error("Port already bound: {0}")]
PortAlreadyBound(String),
// Packet errors
#[error("Packet timeout: height={height}, timestamp={timestamp}")]
PacketTimeout { height: u64, timestamp: u64 },
#[error("Packet already received: sequence={0}")]
PacketAlreadyReceived(u64),
#[error("Packet not found: sequence={0}")]
PacketNotFound(u64),
#[error("Invalid packet sequence: expected {expected}, got {actual}")]
InvalidPacketSequence { expected: u64, actual: u64 },
#[error("Packet data too large: {size} bytes (max {max})")]
PacketDataTooLarge { size: usize, max: usize },
#[error("Invalid packet data: {0}")]
InvalidPacketData(String),
#[error("Invalid acknowledgement: {0}")]
InvalidAcknowledgement(String),
// Swap errors
#[error("Swap not found: {0}")]
SwapNotFound(String),
#[error("Invalid swap state: expected {expected}, got {actual}")]
InvalidSwapState { expected: String, actual: String },
#[error("Swap timeout expired: {0}")]
SwapTimeoutExpired(String),
#[error("Invalid secret: {0}")]
InvalidSecret(String),
// Proof errors
#[error("Proof verification failed: {0}")]
ProofVerificationFailed(String),
#[error("Invalid proof: {0}")]
InvalidProof(String),
#[error("Invalid proof height: expected {expected}, got {actual}")]
InvalidProofHeight { expected: u64, actual: u64 },
#[error("Missing proof: {0}")]
MissingProof(String),
// Commitment errors
#[error("Commitment not found: {0}")]
CommitmentNotFound(String),
#[error("Invalid commitment: {0}")]
InvalidCommitment(String),
// Handshake errors
#[error("Handshake error: {0}")]
HandshakeError(String),
#[error("Invalid counterparty: {0}")]
InvalidCounterparty(String),
// Serialization errors
#[error("Serialization error: {0}")]
SerializationError(String),
#[error("Deserialization error: {0}")]
DeserializationError(String),
// General errors
#[error("Invalid identifier: {0}")]
InvalidIdentifier(String),
#[error("Unauthorized: {0}")]
Unauthorized(String),
#[error("Internal error: {0}")]
Internal(String),
}
impl From<serde_json::Error> for IbcError {
fn from(err: serde_json::Error) -> Self {
IbcError::SerializationError(err.to_string())
}
}
impl From<std::io::Error> for IbcError {
fn from(err: std::io::Error) -> Self {
IbcError::Internal(err.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display() {
let err = IbcError::ClientNotFound("client-1".to_string());
assert!(err.to_string().contains("client-1"));
let err = IbcError::PacketTimeout {
height: 100,
timestamp: 1000,
};
assert!(err.to_string().contains("100"));
}
}