use super::packet::Sequence;
use super::timeout::TimeoutHeight;
use crate::core::ics02_client::error as client_error;
use crate::core::ics03_connection::error as connection_error;
use crate::core::ics04_channel::channel::State;
use crate::core::ics24_host::error::ValidationError;
use crate::core::ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId};
use crate::proofs::ProofError;
use crate::signer::SignerError;
use crate::timestamp::Timestamp;
use crate::Height;
use flex_error::{define_error, TraceError};
use itertools::Itertools;
use tendermint_proto::Error as TendermintError;
define_error! {
#[derive(Debug, PartialEq, Eq)]
Error {
Ics03Connection
[ connection_error::Error ]
| _ | { "ics03 connection error" },
UnknownState
{ state: i32 }
| e | { format_args!("channel state unknown: {}", e.state) },
UnknownFlushStatus
{ state: i32 }
| e | { format_args!("flush status unknown: {}", e.state) },
UnknownFlushStatusType
{ type_id: String }
| e | { format_args!("flush status unknown: {}", e.type_id) },
Identifier
[ ValidationError ]
| _ | { "identifier error" },
UnknownOrderType
{ type_id: String }
| e | { format_args!("channel order type unknown: {}", e.type_id) },
InvalidConnectionHopsLength
{ expected: usize, actual: usize }
| e | {
format_args!(
"invalid connection hops length: expected {0}; actual {1}",
e.expected, e.actual)
},
InvalidPacketCounterparty
{ port_id: PortId, channel_id: ChannelId }
| e | {
format_args!(
"packet destination port {} and channel {} doesn't match the counterparty's port/channel",
e.port_id, e.channel_id)
},
InvalidVersion
[ TraceError<TendermintError> ]
| _ | { "invalid version" },
InvalidFlushStatus
{ flush_status: i32 }
| e | { format_args!("invalid flush_status value: {}", e.flush_status) },
Signer
[ SignerError ]
| _ | { "invalid signer address" },
InvalidProof
[ ProofError ]
| _ | { "invalid proof" },
MissingHeight
| _ | { "invalid proof: missing height" },
MissingNextRecvSeq
{ port_id: PortId, channel_id: ChannelId }
| e | {
format_args!("Missing sequence number for receiving packets on port {0} and channel {1}",
e.port_id,
e.channel_id)
},
ZeroPacketSequence
| _ | { "packet sequence cannot be 0" },
ZeroPacketData
| _ | { "packet data bytes cannot be empty" },
InvalidTimeoutHeight
| _ | { "invalid timeout height for the packet" },
InvalidTimeoutTimestamp
[ crate::timestamp::ParseTimestampError ]
| _ | { "invalid timeout timestamp" },
InvalidPacket
| _ | { "invalid packet" },
MissingPacket
| _ | { "there is no packet in this message" },
MissingChannelId
| _ | { "missing channel id" },
MissingCounterparty
| _ | { "missing counterparty" },
NoCommonVersion
| _ | { "no common version" },
MissingChannel
| _ | { "missing channel end" },
MissingUpgradeTimeout
| _ | { "missing upgrade timeout, either a height or a timestamp must be set" },
MissingUpgrade
| _ | { "missing upgrade" },
MissingUpgradeFields
| _ | { "missing upgrade fields" },
MissingUpgradeErrorReceipt
| _ | { "missing upgrade error receipt" },
MissingProposedUpgradeChannel
| _ | { "missing proposed upgrade channel" },
MissingProofHeight
| _ | { "missing proof height" },
InvalidProofHeight
| _ | { "invalid proof height" },
InvalidVersionLengthConnection
| _ | { "single version must be negotiated on connection before opening channel" },
ChannelFeatureNotSuportedByConnection
| _ | { "the channel ordering is not supported by connection" },
ChannelNotFound
{ port_id: PortId, channel_id: ChannelId }
| e | {
format_args!(
"the channel end ({0}, {1}) does not exist",
e.port_id, e.channel_id)
},
ChannelMismatch
{ channel_id: ChannelId }
| e | {
format_args!(
"a different channel exists (was initialized) already for the same channel identifier {0}",
e.channel_id)
},
ConnectionNotOpen
{ connection_id: ConnectionId }
| e | {
format_args!(
"the associated connection {0} is not OPEN",
e.connection_id)
},
UndefinedConnectionCounterparty
{ connection_id: ConnectionId }
| e | {
format_args!(
"Undefined counterparty connection for {0}",
e.connection_id)
},
PacketVerificationFailed
{ sequence: Sequence }
[ client_error::Error ]
| e | {
format_args!(
"Verification fails for the packet with the sequence number {0}",
e.sequence)
},
VerifyChannelFailed
[ client_error::Error ]
| _ | {
"Error verifying channel state"
},
InvalidAcknowledgement
| _ | { "Acknowledgment cannot be empty" },
AcknowledgementExists
{ sequence: Sequence }
| e | {
format_args!(
"Packet acknowledgement exists for the packet with the sequence {0}",
e.sequence)
},
MissingNextSendSeq
{ port_id: PortId, channel_id: ChannelId }
| e | {
format_args!("Missing sequence number for sending packets on port {0} and channel {1}",
e.port_id,
e.channel_id)
},
InvalidStringAsSequence
{ value: String }
[ TraceError<core::num::ParseIntError> ]
| e | {
format_args!(
"String {0} cannot be converted to packet sequence",
e.value)
},
InvalidPacketSequence
{
given_sequence: Sequence,
next_sequence: Sequence
}
| e | {
format_args!(
"Invalid packet sequence {0} ≠ next send sequence {1}",
e.given_sequence, e.next_sequence)
},
InvalidPacketData
{
data: String,
}
| e | {
format_args!("Invalid packet data, not a valid hex-encoded string: {}", e.data)
},
InvalidPacketAck
{
ack: String,
}
| e | {
format_args!("Invalid packet ack, not a valid hex-encoded string: {}", e.ack)
},
LowPacketHeight
{
chain_height: Height,
timeout_height: TimeoutHeight
}
| e | {
format_args!(
"Receiving chain block height {0} >= packet timeout height {1}",
e.chain_height, e.timeout_height)
},
PacketTimeoutHeightNotReached
{
timeout_height: TimeoutHeight,
chain_height: Height,
}
| e | {
format_args!(
"Packet timeout height {0} > chain height {1}",
e.timeout_height, e.chain_height)
},
PacketTimeoutTimestampNotReached
{
timeout_timestamp: Timestamp,
chain_timestamp: Timestamp,
}
| e | {
format_args!(
"Packet timeout timestamp {0} > chain timestamp {1}",
e.timeout_timestamp, e.chain_timestamp)
},
LowPacketTimestamp
| _ | { "Receiving chain block timestamp >= packet timeout timestamp" },
InvalidPacketTimestamp
[ crate::timestamp::ParseTimestampError ]
| _ | { "Invalid packet timeout timestamp value" },
ErrorInvalidConsensusState
| _ | { "Invalid timestamp in consensus state; timestamp must be a positive value" },
FrozenClient
{ client_id: ClientId }
| e | {
format_args!(
"Client with id {0} is frozen",
e.client_id)
},
InvalidCounterpartyChannelId
[ ValidationError ]
| _ | { "Invalid channel id in counterparty" },
InvalidChannelState
{ channel_id: ChannelId, state: State }
| e | {
format_args!(
"Channel {0} should not be state {1}",
e.channel_id, e.state)
},
ChannelClosed
{ channel_id: ChannelId }
| e | {
format_args!(
"Channel {0} is Closed",
e.channel_id)
},
ChanOpenAckProofVerification
| _ | { "Handshake proof verification fails at ChannelOpenAck" },
PacketCommitmentNotFound
{ sequence: Sequence }
| e | {
format_args!(
"Commitment for the packet {0} not found",
e.sequence)
},
IncorrectPacketCommitment
{ sequence: Sequence }
| e | {
format_args!(
"The stored commitment of the packet {0} is incorrect",
e.sequence)
},
PacketReceiptNotFound
{ sequence: Sequence }
| e | {
format_args!(
"Receipt for the packet {0} not found",
e.sequence)
},
PacketAcknowledgementNotFound
{ sequence: Sequence }
| e | {
format_args!(
"Acknowledgment for the packet {0} not found",
e.sequence)
},
MissingNextAckSeq
{ port_id: PortId, channel_id: ChannelId }
| e | {
format_args!("Missing sequence number for ack packets on port {0} and channel {1}",
e.port_id,
e.channel_id)
},
ProcessedTimeNotFound
{
client_id: ClientId,
height: Height,
}
| e | {
format_args!(
"Processed time for the client {0} at height {1} not found",
e.client_id, e.height)
},
ProcessedHeightNotFound
{
client_id: ClientId,
height: Height,
}
| e | {
format_args!(
"Processed height for the client {0} at height {1} not found",
e.client_id, e.height)
},
RouteNotFound
| _ | { "route not found" },
ImplementationSpecific
| _ | { "implementation specific error" },
AppModule
{ description: String }
| e | {
format_args!(
"application module error: {0}",
e.description)
},
AbciConversionFailed
{ abci_event: String }
| e | { format_args!("Failed to convert abci event to IbcEvent: {}", e.abci_event)},
ParseConnectionHopsVector
{ failures: Vec<(String, ValidationError)> }
| e | {
let failures = e.failures
.iter()
.map(|(s, e)| format!("\"{}\": {}", s, e))
.join(", ");
format!("error parsing a vector of ConnectionId: {}", failures)
},
MalformedEventAttributeKey
| _ | { format_args!("event attribute key is not valid UTF-8") },
MalformedEventAttributeValue
{ key: String }
| e | { format_args!("event attribute value for key {} is not valid UTF-8", e.key) },
}
}
impl Error {
pub fn chan_open_confirm_proof_verification(e: Error) -> Error {
e.add_trace(&"Handshake proof verification fails at ChannelOpenConfirm")
}
}