diff --git a/Cargo.toml b/Cargo.toml index a2ac8e33a..35836b333 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,22 @@ resolver = "2" members = [ "crates/ibc", + "crates/ibc-data-types", + "crates/ibc-primitives", + "crates/ibc-core", + "crates/ibc-core/ics02-client", + "crates/ibc-core/ics02-client/types", + "crates/ibc-core/ics03-connection", + "crates/ibc-core/ics03-connection/types", + "crates/ibc-core/ics04-channel", + "crates/ibc-core/ics04-channel/types", + "crates/ibc-core/ics23-commitment/types", + "crates/ibc-core/ics24-host/types", + "crates/ibc-core/context", + "crates/ibc-core/extra", + "crates/ibc-core/context/types", + "crates/ibc-core/ics26-routing", + "crates/ibc-core/ics26-routing/types", "crates/ibc-apps", "crates/ibc-apps/ics20-transfer", "crates/ibc-apps/ics20-transfer/types", @@ -35,7 +51,7 @@ parking_lot = { version = "0.12.1", default-features = false } primitive-types = { version = "0.12.2", default-features = false, features = ["serde_no_std"] } prost = { version = "0.12", default-features = false } rstest = "0.18.2" -schemars = { version = "0.8.15"} +schemars = { version = "0.8.15" } sha2 = { version = "0.10.8", default-features = false } serde = { version = "1.0", default-features = false } serde_derive = { version = "1.0", default-features = false } @@ -45,14 +61,34 @@ test-log = { version = "0.2.13", features = ["trace"] } time = { version = ">=0.3.0, <0.3.31", default-features = false } tracing = { version = "0.1.40", default-features = false } tracing-subscriber = { version = "0.3.17", features = ["fmt", "env-filter", "json"] } -typed-builder = { version = "0.18.0"} +typed-builder = { version = "0.18.0" } # ibc dependencies -ibc = { version = "0.47.0", path = "./crates/ibc", default-features = false } -ibc-testkit = { version = "0.47.0", path = "./crates/ibc-testkit", default-features = false} -ibc-app-transfer = { version = "0.47.0", path = "./crates/ibc-apps/ics20-transfer", default-features = false } -ibc-app-transfer-types = { version = "0.47.0", path = "./crates/ibc-apps/ics20-transfer/types", default-features = false } -ibc-derive = { version = "0.3.0", path = "./crates/ibc-derive" } +ibc = { version = "0.47.0", path = "./crates/ibc", default-features = false } +ibc-apps = { version = "0.47.0", path = "./crates/ibc-apps", default-features = false } +ibc-core = { version = "0.47.0", path = "./crates//ibc-core", default-features = false } +ibc-primitives = { version = "0.47.0", path = "./crates/ibc-primitives", default-features = false } +ibc-testkit = { version = "0.47.0", path = "./crates/ibc-testkit" } +ibc-derive = { version = "0.3.0", path = "./crates/ibc-derive" } + +ibc-core-client = { version = "0.47.0", path = "./crates/ibc-core/ics02-client", default-features = false } +ibc-core-connection = { version = "0.47.0", path = "./crates/ibc-core/ics03-connection", default-features = false } +ibc-core-channel = { version = "0.47.0", path = "./crates/ibc-core/ics04-channel", default-features = false } +ibc-core-router = { version = "0.47.0", path = "./crates/ibc-core/ics26-routing", default-features = false } +ibc-core-context = { version = "0.47.0", path = "./crates/ibc-core/context", default-features = false } +ibc-core-extra = { version = "0.47.0", path = "./crates/ibc-core/extra", default-features = false } +ibc-app-transfer = { version = "0.47.0", path = "./crates/ibc-apps/ics20-transfer", default-features = false } + +ibc-core-client-context = { version = "0.47.0", path = "./crates/ibc-core/ics02-client/context", default-features = false } +ibc-core-client-types = { version = "0.47.0", path = "./crates/ibc-core/ics02-client/types", default-features = false } +ibc-core-channel-types = { version = "0.47.0", path = "./crates/ibc-core/ics04-channel/types", default-features = false } +ibc-core-connection-types = { version = "0.47.0", path = "./crates/ibc-core/ics03-connection/types" } +ibc-core-commitment-types = { version = "0.47.0", path = "./crates/ibc-core/ics23-commitment/types", default-features = false } +ibc-core-host-types = { version = "0.47.0", path = "./crates/ibc-core/ics24-host/types", default-features = false } +ibc-core-router-types = { version = "0.47.0", path = "./crates/ibc-core/ics26-routing/types", default-features = false } +ibc-core-context-types = { version = "0.47.0", path = "./crates/ibc-core/context/types", default-features = false } +ibc-app-transfer-types = { version = "0.47.0", path = "./crates/ibc-apps/ics20-transfer/types", default-features = false } + ibc-proto = { version = "0.38.0", default-features = false } ics23 = { version = "0.11", default-features = false } diff --git a/crates/ibc-apps/ics20-transfer/Cargo.toml b/crates/ibc-apps/ics20-transfer/Cargo.toml index 821e3381b..5a1bfc84f 100644 --- a/crates/ibc-apps/ics20-transfer/Cargo.toml +++ b/crates/ibc-apps/ics20-transfer/Cargo.toml @@ -22,7 +22,7 @@ serde_json = { workspace = true, optional = true } sha2 = { workspace = true } # ibc dependencies -ibc = { workspace = true } +ibc-core = { workspace = true } ibc-app-transfer-types = { workspace = true } [dev-dependencies] @@ -32,26 +32,26 @@ subtle-encoding = { workspace = true } default = ["std"] std = [ "ibc-app-transfer-types/std", - "ibc/std", + "ibc-core/std", "serde_json/std", "sha2/std", ] serde = [ "ibc-app-transfer-types/serde", - "ibc/serde", + "ibc-core/serde", "serde_json" ] schema = [ "ibc-app-transfer-types/schema", - "ibc/schema", + "ibc-core/schema", "serde", "std", ] borsh = [ "ibc-app-transfer-types/borsh", - "ibc/borsh", + "ibc-core/borsh", ] parity-scale-codec = [ "ibc-app-transfer-types/parity-scale-codec", - "ibc/parity-scale-codec", + "ibc-core/parity-scale-codec", ] diff --git a/crates/ibc-apps/ics20-transfer/src/context.rs b/crates/ibc-apps/ics20-transfer/src/context.rs index 80899b12b..c2718f97a 100644 --- a/crates/ibc-apps/ics20-transfer/src/context.rs +++ b/crates/ibc-apps/ics20-transfer/src/context.rs @@ -1,10 +1,10 @@ //! Defines the main context traits and IBC module callbacks -use ibc::core::ics24_host::identifier::{ChannelId, PortId}; -use ibc::prelude::*; -use ibc::Signer; use ibc_app_transfer_types::error::TokenTransferError; use ibc_app_transfer_types::{PrefixedCoin, PrefixedDenom, VERSION}; +use ibc_core::host::identifiers::{ChannelId, PortId}; +use ibc_core::primitives::prelude::*; +use ibc_core::primitives::Signer; use sha2::{Digest, Sha256}; /// Methods required in token transfer validation, to be implemented by the host diff --git a/crates/ibc-apps/ics20-transfer/src/handler/mod.rs b/crates/ibc-apps/ics20-transfer/src/handler/mod.rs index 730017f6d..967df3918 100644 --- a/crates/ibc-apps/ics20-transfer/src/handler/mod.rs +++ b/crates/ibc-apps/ics20-transfer/src/handler/mod.rs @@ -2,11 +2,10 @@ pub mod on_recv_packet; pub mod send_transfer; -use ibc::core::ics04_channel::packet::Packet; -use ibc::prelude::*; use ibc_app_transfer_types::error::TokenTransferError; use ibc_app_transfer_types::is_sender_chain_source; use ibc_app_transfer_types::packet::PacketData; +use ibc_core::channel::types::packet::Packet; use crate::context::{TokenTransferExecutionContext, TokenTransferValidationContext}; diff --git a/crates/ibc-apps/ics20-transfer/src/handler/on_recv_packet.rs b/crates/ibc-apps/ics20-transfer/src/handler/on_recv_packet.rs index d150d8399..2baa187f6 100644 --- a/crates/ibc-apps/ics20-transfer/src/handler/on_recv_packet.rs +++ b/crates/ibc-apps/ics20-transfer/src/handler/on_recv_packet.rs @@ -1,10 +1,10 @@ -use ibc::core::ics04_channel::packet::Packet; -use ibc::core::router::ModuleExtras; -use ibc::prelude::*; use ibc_app_transfer_types::error::TokenTransferError; use ibc_app_transfer_types::events::DenomTraceEvent; use ibc_app_transfer_types::packet::PacketData; use ibc_app_transfer_types::{is_receiver_chain_source, TracePrefix}; +use ibc_core::channel::types::packet::Packet; +use ibc_core::primitives::prelude::*; +use ibc_core::router::types::module::ModuleExtras; use crate::context::TokenTransferExecutionContext; diff --git a/crates/ibc-apps/ics20-transfer/src/handler/send_transfer.rs b/crates/ibc-apps/ics20-transfer/src/handler/send_transfer.rs index 9fe2662b5..fbbe0c4ca 100644 --- a/crates/ibc-apps/ics20-transfer/src/handler/send_transfer.rs +++ b/crates/ibc-apps/ics20-transfer/src/handler/send_transfer.rs @@ -1,13 +1,14 @@ -use ibc::core::events::{MessageEvent, ModuleEvent}; -use ibc::core::ics04_channel::context::{SendPacketExecutionContext, SendPacketValidationContext}; -use ibc::core::ics04_channel::handler::send_packet::{send_packet_execute, send_packet_validate}; -use ibc::core::ics04_channel::packet::Packet; -use ibc::core::ics24_host::path::{ChannelEndPath, SeqSendPath}; -use ibc::prelude::*; use ibc_app_transfer_types::error::TokenTransferError; use ibc_app_transfer_types::events::TransferEvent; use ibc_app_transfer_types::msgs::transfer::MsgTransfer; use ibc_app_transfer_types::{is_sender_chain_source, MODULE_ID_STR}; +use ibc_core::channel::context::{SendPacketExecutionContext, SendPacketValidationContext}; +use ibc_core::channel::handler::{send_packet_execute, send_packet_validate}; +use ibc_core::channel::types::packet::Packet; +use ibc_core::context::types::events::MessageEvent; +use ibc_core::host::path::{ChannelEndPath, SeqSendPath}; +use ibc_core::primitives::prelude::*; +use ibc_core::router::types::event::ModuleEvent; use crate::context::{TokenTransferExecutionContext, TokenTransferValidationContext}; diff --git a/crates/ibc-apps/ics20-transfer/src/module.rs b/crates/ibc-apps/ics20-transfer/src/module.rs index 1c86d139e..ba97a162d 100644 --- a/crates/ibc-apps/ics20-transfer/src/module.rs +++ b/crates/ibc-apps/ics20-transfer/src/module.rs @@ -1,16 +1,16 @@ -use ibc::core::ics04_channel::acknowledgement::{Acknowledgement, AcknowledgementStatus}; -use ibc::core::ics04_channel::channel::{Counterparty, Order}; -use ibc::core::ics04_channel::packet::Packet; -use ibc::core::ics04_channel::Version; -use ibc::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; -use ibc::core::router::ModuleExtras; -use ibc::core::ContextError; -use ibc::prelude::*; -use ibc::Signer; use ibc_app_transfer_types::error::TokenTransferError; use ibc_app_transfer_types::events::{AckEvent, AckStatusEvent, RecvEvent, TimeoutEvent}; use ibc_app_transfer_types::packet::PacketData; use ibc_app_transfer_types::{ack_success_b64, VERSION}; +use ibc_core::channel::types::acknowledgement::{Acknowledgement, AcknowledgementStatus}; +use ibc_core::channel::types::channel::{Counterparty, Order}; +use ibc_core::channel::types::packet::Packet; +use ibc_core::channel::types::Version; +use ibc_core::context::types::error::ContextError; +use ibc_core::host::identifiers::{ChannelId, ConnectionId, PortId}; +use ibc_core::primitives::prelude::*; +use ibc_core::primitives::Signer; +use ibc_core::router::types::module::ModuleExtras; use crate::context::{TokenTransferExecutionContext, TokenTransferValidationContext}; use crate::handler::on_recv_packet::process_recv_packet_execute; diff --git a/crates/ibc-apps/ics20-transfer/types/Cargo.toml b/crates/ibc-apps/ics20-transfer/types/Cargo.toml index 495a77de5..d7083b90a 100644 --- a/crates/ibc-apps/ics20-transfer/types/Cargo.toml +++ b/crates/ibc-apps/ics20-transfer/types/Cargo.toml @@ -28,7 +28,7 @@ serde_json = { workspace = true, optional = true} uint = { version = "0.9", default-features = false } # ibc dependencies -ibc = { workspace = true } +ibc-core = { workspace = true } ibc-proto = { workspace = true } ## parity dependencies @@ -49,7 +49,7 @@ std = [ "uint/std", "primitive-types/std", ] -borsh = ["dep:borsh", "ibc/borsh", "ibc-proto/borsh"] -serde = ["dep:serde", "serde_json", "ibc/serde", "ibc-proto/serde"] -schema = ["dep:schemars", "ibc/schema", "ibc-proto/json-schema", "serde", "std"] -parity-scale-codec = ["dep:parity-scale-codec", "dep:scale-info", "ibc/parity-scale-codec", "ibc-proto/parity-scale-codec"] \ No newline at end of file +borsh = ["dep:borsh", "ibc-core/borsh", "ibc-proto/borsh"] +serde = ["dep:serde", "serde_json", "ibc-core/serde", "ibc-proto/serde"] +schema = ["dep:schemars", "ibc-core/schema", "ibc-proto/json-schema", "serde", "std"] +parity-scale-codec = ["dep:parity-scale-codec", "dep:scale-info", "ibc-core/parity-scale-codec", "ibc-proto/parity-scale-codec"] \ No newline at end of file diff --git a/crates/ibc-apps/ics20-transfer/types/src/amount.rs b/crates/ibc-apps/ics20-transfer/types/src/amount.rs index cc793200b..5c3802d2d 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/amount.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/amount.rs @@ -3,7 +3,7 @@ use core::ops::Deref; use core::str::FromStr; use derive_more::{Display, From, Into}; -use ibc::prelude::*; +use ibc_core::primitives::prelude::*; use primitive_types::U256; use super::error::TokenTransferError; diff --git a/crates/ibc-apps/ics20-transfer/types/src/coin.rs b/crates/ibc-apps/ics20-transfer/types/src/coin.rs index 70f3d832b..65a147218 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/coin.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/coin.rs @@ -2,7 +2,7 @@ use core::fmt::{Display, Error as FmtError, Formatter}; use core::str::FromStr; -use ibc::prelude::*; +use ibc_core::primitives::prelude::*; use ibc_proto::cosmos::base::v1beta1::Coin as ProtoCoin; use super::amount::Amount; diff --git a/crates/ibc-apps/ics20-transfer/types/src/denom.rs b/crates/ibc-apps/ics20-transfer/types/src/denom.rs index 42847ceba..c93dcf2df 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/denom.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/denom.rs @@ -3,8 +3,8 @@ use core::fmt::{Display, Error as FmtError, Formatter}; use core::str::FromStr; use derive_more::{Display, From}; -use ibc::core::ics24_host::identifier::{ChannelId, PortId}; -use ibc::prelude::*; +use ibc_core::host::identifiers::{ChannelId, PortId}; +use ibc_core::primitives::prelude::*; use ibc_proto::ibc::applications::transfer::v1::DenomTrace as RawDenomTrace; use super::error::TokenTransferError; diff --git a/crates/ibc-apps/ics20-transfer/types/src/error.rs b/crates/ibc-apps/ics20-transfer/types/src/error.rs index 8372f8aa5..64bc33444 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/error.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/error.rs @@ -3,11 +3,12 @@ use core::convert::Infallible; use core::str::Utf8Error; use displaydoc::Display; -use ibc::core::ics04_channel::acknowledgement::StatusValue; -use ibc::core::ics04_channel::channel::Order; -use ibc::core::ics24_host::identifier::{ChannelId, IdentifierError, PortId}; -use ibc::core::ContextError; -use ibc::prelude::*; +use ibc_core::channel::types::acknowledgement::StatusValue; +use ibc_core::channel::types::channel::Order; +use ibc_core::context::types::error::ContextError; +use ibc_core::host::error::IdentifierError; +use ibc_core::host::identifiers::{ChannelId, PortId}; +use ibc_core::primitives::prelude::*; use uint::FromDecStrErr; #[derive(Display, Debug)] diff --git a/crates/ibc-apps/ics20-transfer/types/src/events.rs b/crates/ibc-apps/ics20-transfer/types/src/events.rs index bee96cf72..565e14430 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/events.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/events.rs @@ -1,8 +1,8 @@ //! Defines all token transfer event types -use ibc::core::events::ModuleEvent; -use ibc::core::ics04_channel::acknowledgement::AcknowledgementStatus; -use ibc::prelude::*; -use ibc::Signer; +use ibc_core::channel::types::acknowledgement::AcknowledgementStatus; +use ibc_core::primitives::prelude::*; +use ibc_core::primitives::Signer; +use ibc_core::router::types::event::ModuleEvent; use super::Memo; use crate::{Amount, PrefixedDenom, MODULE_ID_STR}; @@ -22,7 +22,7 @@ pub enum Event { Transfer(TransferEvent), } -/// Event emitted in the `onRecvPacket` module callback to indicate that the +/// Event emitted by the `onRecvPacket` module callback to indicate the that the /// `RecvPacket` message was processed pub struct RecvEvent { pub sender: Signer, @@ -58,7 +58,7 @@ impl From for ModuleEvent { } } -/// Event emitted by the `onAcknowledgePacket` module callback +/// Event emitted in the `onAcknowledgePacket` module callback pub struct AckEvent { pub sender: Signer, pub receiver: Signer, @@ -93,7 +93,7 @@ impl From for ModuleEvent { } } -/// Event emitted by the `onAcknowledgePacket` module callback to indicate +/// Event emitted in the `onAcknowledgePacket` module callback to indicate /// whether the acknowledgement is a success or a failure pub struct AckStatusEvent { pub acknowledgement: AcknowledgementStatus, @@ -114,7 +114,7 @@ impl From for ModuleEvent { } } -/// Event emitted by the `onTimeoutPacket` module callback +/// Event emitted in the `onTimeoutPacket` module callback pub struct TimeoutEvent { pub refund_receiver: Signer, pub refund_denom: PrefixedDenom, @@ -143,7 +143,7 @@ impl From for ModuleEvent { } } -/// Event emitted by the `onRecvPacket` module callback when new tokens are minted +/// Event emitted in the `onRecvPacket` module callback when new tokens are minted pub struct DenomTraceEvent { pub trace_hash: Option, pub denom: PrefixedDenom, diff --git a/crates/ibc-apps/ics20-transfer/types/src/lib.rs b/crates/ibc-apps/ics20-transfer/types/src/lib.rs index 723a146d3..c4044c6e5 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/lib.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/lib.rs @@ -61,7 +61,7 @@ pub const VERSION: &str = "ics20-1"; /// equivalent to `base64::encode(0x01)`. pub const ACK_SUCCESS_B64: &str = "AQ=="; -use ibc::core::ics04_channel::acknowledgement::StatusValue; +use ibc_core::channel::types::acknowledgement::StatusValue; /// Returns a successful acknowledgement status for the token transfer application. pub fn ack_success_b64() -> StatusValue { diff --git a/crates/ibc-apps/ics20-transfer/types/src/memo.rs b/crates/ibc-apps/ics20-transfer/types/src/memo.rs index de7368fa6..9a3caea74 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/memo.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/memo.rs @@ -7,7 +7,7 @@ use core::fmt::{ }; use core::str::FromStr; -use ibc::prelude::*; +use ibc_core::primitives::prelude::*; /// Represents the token transfer memo #[cfg_attr( diff --git a/crates/ibc-apps/ics20-transfer/types/src/msgs/transfer.rs b/crates/ibc-apps/ics20-transfer/types/src/msgs/transfer.rs index eb061d9a2..ff4fe77d7 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/msgs/transfer.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/msgs/transfer.rs @@ -1,10 +1,11 @@ //! Defines the token transfer message type -use ibc::core::ics04_channel::error::PacketError; -use ibc::core::ics04_channel::timeout::TimeoutHeight; -use ibc::core::ics24_host::identifier::{ChannelId, PortId}; -use ibc::core::timestamp::Timestamp; -use ibc::core::{ContextError, Msg}; -use ibc::prelude::*; + +use ibc_core::channel::types::error::PacketError; +use ibc_core::channel::types::timeout::TimeoutHeight; +use ibc_core::context::types::error::ContextError; +use ibc_core::host::identifiers::{ChannelId, PortId}; +use ibc_core::primitives::prelude::*; +use ibc_core::primitives::{Msg, Timestamp}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::applications::transfer::v1::MsgTransfer as RawMsgTransfer; use ibc_proto::Protobuf; diff --git a/crates/ibc-apps/ics20-transfer/types/src/packet.rs b/crates/ibc-apps/ics20-transfer/types/src/packet.rs index bb556af34..d9d1ace76 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/packet.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/packet.rs @@ -3,8 +3,8 @@ use core::convert::TryFrom; use core::str::FromStr; -use ibc::prelude::*; -use ibc::Signer; +use ibc_core::primitives::prelude::*; +use ibc_core::primitives::Signer; use ibc_proto::ibc::applications::transfer::v2::FungibleTokenPacketData as RawPacketData; use super::error::TokenTransferError; diff --git a/crates/ibc-apps/ics20-transfer/types/src/serializers.rs b/crates/ibc-apps/ics20-transfer/types/src/serializers.rs index 57f6e20d3..65c4d2ba6 100644 --- a/crates/ibc-apps/ics20-transfer/types/src/serializers.rs +++ b/crates/ibc-apps/ics20-transfer/types/src/serializers.rs @@ -1,7 +1,7 @@ use core::fmt::Display; use core::str::FromStr; -use ibc::prelude::*; +use ibc_core::primitives::prelude::*; use serde::{de, Deserialize, Deserializer, Serializer}; // Note: This method serializes to a String instead of a str diff --git a/crates/ibc-core/Cargo.toml b/crates/ibc-core/Cargo.toml new file mode 100644 index 000000000..2f7a98cca --- /dev/null +++ b/crates/ibc-core/Cargo.toml @@ -0,0 +1,52 @@ +[package] +name = "ibc-core" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + `ibc-core` provides a comprehensive set of libraries for IBC core (TAO) layers, + facilitating seamless integration of IBC business logic into any blockchain system. +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +ibc-core-client = { workspace = true } +ibc-core-connection = { workspace = true } +ibc-core-channel = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-router = { workspace = true } +ibc-core-context = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-primitives = { workspace = true } +# ibc-core-utils = { workspace = true } + +[features] +default = ["std"] +std = [ + "ibc-core-client/std", + "ibc-core-connection/std", + "ibc-core-channel/std", + "ibc-core-commitment-types/std", + "ibc-core-router/std", + "ibc-core-context/std", + "ibc-core-host-types/std", +] +serde = [ + "ibc-core-client/serde", + "ibc-core-connection/serde", + "ibc-core-channel/serde", + "ibc-core-commitment-types/serde", + "ibc-core-router/serde", + "ibc-core-context/serde", + "ibc-core-host-types/serde", +] +borsh = [] +schema = [] +parity-scale-codec = [] \ No newline at end of file diff --git a/crates/ibc-core/README.md b/crates/ibc-core/README.md new file mode 100644 index 000000000..aeb49d1b5 --- /dev/null +++ b/crates/ibc-core/README.md @@ -0,0 +1,43 @@ +# `ibc-core` + +This crate is top-level library re-exports implemented Inter-Blockchain +Communication (IBC) core transport and authentication layers in Rust serves as a +centralized hub, simplifying the process of importing and integrating various +IBC core components into your blockchain. IBC is a distributed protocol that +enables communication between distinct sovereign blockchains and IBC +applications is the part of the protocol that abstracts away the core transport +and authentication layers and focuses solely on business logics. + +The structure within the `ibc-core` crate is designed to provide flexibility for +external users. It allows you to utilize the own `ibc-core` crate +comprehensively or selectively import specific libraries, whether you need a +certain IBC application (e.g. `ibc-core-client` crate) or only their associated +data structures (e.g. `ibc-core-client-types`). This versatility empowers +hosts, including chain integrators, relayers, or any IBC tooling projects, to +build their solutions on top of the layers that best suit their requirements. + +## Libraries + +Currently, the `ibc-core` crate contains the implementation of the following IBC +core libraries: + +## Contributing + +IBC is specified in English in the [cosmos/ibc repo][ibc]. Any +protocol changes or clarifications should be contributed there. + +If you're interested in contributing, please comment on an issue or open a new +one! + +See also [CONTRIBUTING.md](./../../CONTRIBUTING.md). + +## Resources + +- [IBC Website][ibc-homepage] +- [IBC Specification][ibc] +- [IBC Go implementation][ibc-go] + +[//]: # (general links) +[ibc]: https://github.com/cosmos/ibc +[ibc-go]: https://github.com/cosmos/ibc-go +[ibc-homepage]: https://cosmos.network/ibc diff --git a/crates/ibc-core/context/Cargo.toml b/crates/ibc-core/context/Cargo.toml new file mode 100644 index 000000000..33876c91e --- /dev/null +++ b/crates/ibc-core/context/Cargo.toml @@ -0,0 +1,62 @@ +[package] +name = "ibc-core-context" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc-primitives = { workspace = true } +ibc-core-client-types = { workspace = true } +ibc-core-client-context = { workspace = true } +ibc-core-connection-types = { workspace = true } +ibc-core-channel-types = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-router = { workspace = true } +ibc-core-context-types = { workspace = true } + +[dev-dependencies] +rstest = { workspace = true } + +[features] +default = ["std"] +std = [ + "ibc-primitives/std", + "ibc-core-client-types/std", + "ibc-core-client-context/std", + "ibc-core-connection-types/std", + "ibc-core-channel-types/std", + "ibc-core-commitment-types/std", + "ibc-core-host-types/std", + "ibc-core-router/std", + "ibc-core-context-types/std", +] +serde = [ + "ibc-primitives/serde", + "ibc-core-client-types/serde", + "ibc-core-client-context/serde", + "ibc-core-connection-types/serde", + "ibc-core-channel-types/serde", + "ibc-core-commitment-types/serde", + "ibc-core-host-types/serde", + "ibc-core-router/serde", + "ibc-core-context-types/serde", +] \ No newline at end of file diff --git a/crates/ibc-core/context/src/block_delay.rs b/crates/ibc-core/context/src/block_delay.rs new file mode 100644 index 000000000..9d9cf3fa4 --- /dev/null +++ b/crates/ibc-core/context/src/block_delay.rs @@ -0,0 +1,45 @@ +use core::time::Duration; + +pub fn calculate_block_delay( + delay_period_time: &Duration, + max_expected_time_per_block: &Duration, +) -> u64 { + let delay_period_time = delay_period_time.as_secs(); + let max_expected_time_per_block = max_expected_time_per_block.as_secs(); + if max_expected_time_per_block == 0 { + return 0; + } + if delay_period_time % max_expected_time_per_block == 0 { + return delay_period_time / max_expected_time_per_block; + } + (delay_period_time / max_expected_time_per_block) + 1 +} + +#[cfg(test)] +mod tests { + + use rstest::rstest; + + use super::*; + + #[rstest] + #[case::remainder_zero(10, 2, 5)] + #[case::remainder_not_zero(10, 3, 4)] + #[case::max_expected_zero(10, 0, 0)] + #[case::delay_period_zero(0, 2, 0)] + #[case::both_zero(0, 0, 0)] + #[case::delay_less_than_max(10, 11, 1)] + fn test_calculate_block_delay_zero( + #[case] delay_period_time: u64, + #[case] max_expected_time_per_block: u64, + #[case] expected: u64, + ) { + assert_eq!( + calculate_block_delay( + &Duration::from_secs(delay_period_time), + &Duration::from_secs(max_expected_time_per_block) + ), + expected + ); + } +} diff --git a/crates/ibc/src/core/context.rs b/crates/ibc-core/context/src/context.rs similarity index 76% rename from crates/ibc/src/core/context.rs rename to crates/ibc-core/context/src/context.rs index 288717f4b..d661a32a1 100644 --- a/crates/ibc/src/core/context.rs +++ b/crates/ibc-core/context/src/context.rs @@ -1,97 +1,33 @@ -use alloc::string::String; use core::time::Duration; -use derive_more::From; -use displaydoc::Display; -use ibc_proto::google::protobuf::Any; - -use super::ics02_client::client_state::ClientState; -use super::ics02_client::consensus_state::ConsensusState; -use super::ics02_client::{ClientExecutionContext, ClientValidationContext}; -use super::ics24_host::identifier::PortId; -use crate::core::events::IbcEvent; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::ConnectionEnd; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics03_connection::version::{ +use ibc_core_channel_types::channel::ChannelEnd; +use ibc_core_channel_types::commitment::{AcknowledgementCommitment, PacketCommitment}; +use ibc_core_channel_types::packet::Receipt; +use ibc_core_client_context::client_state::ClientState; +use ibc_core_client_context::consensus_state::ConsensusState; +use ibc_core_client_context::{ClientExecutionContext, ClientValidationContext}; +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentPrefix; +use ibc_core_connection_types::version::{ get_compatible_versions, pick_version, Version as ConnectionVersion, }; -use crate::core::ics04_channel::channel::ChannelEnd; -use crate::core::ics04_channel::commitment::{AcknowledgementCommitment, PacketCommitment}; -use crate::core::ics04_channel::context::calculate_block_delay; -use crate::core::ics04_channel::error::{ChannelError, PacketError}; -use crate::core::ics04_channel::packet::{Receipt, Sequence}; -use crate::core::ics23_commitment::commitment::CommitmentPrefix; -use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; -use crate::core::ics24_host::path::{ +use ibc_core_connection_types::ConnectionEnd; +use ibc_core_context_types::error::ContextError; +use ibc_core_context_types::events::IbcEvent; +use ibc_core_context_types::proto::Any; +use ibc_core_host_types::identifiers::{ClientId, ConnectionId, Sequence}; +use ibc_core_host_types::path::{ AckPath, ChannelEndPath, ClientConnectionPath, ClientConsensusStatePath, CommitmentPath, ConnectionPath, ReceiptPath, SeqAckPath, SeqRecvPath, SeqSendPath, }; -use crate::core::timestamp::Timestamp; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; - -/// Top-level error -#[derive(Debug, Display, From)] -pub enum ContextError { - /// ICS02 Client error: {0} - ClientError(ClientError), - /// ICS03 Connection error: {0} - ConnectionError(ConnectionError), - /// ICS04 Channel error: {0} - ChannelError(ChannelError), - /// ICS04 Packet error: {0} - PacketError(PacketError), -} - -#[cfg(feature = "std")] -impl std::error::Error for ContextError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match &self { - Self::ClientError(e) => Some(e), - Self::ConnectionError(e) => Some(e), - Self::ChannelError(e) => Some(e), - Self::PacketError(e) => Some(e), - } - } -} - -/// Error returned from entrypoint functions [`dispatch`][super::dispatch], [`validate`][super::validate] and -/// [`execute`][super::execute]. -#[derive(Debug, Display)] -pub enum RouterError { - /// context error: `{0}` - ContextError(ContextError), - /// unknown type URL `{url}` - UnknownMessageTypeUrl { url: String }, - /// the message is malformed and cannot be decoded error: `{reason}` - MalformedMessageBytes { reason: String }, - /// port `{port_id}` is unknown - UnknownPort { port_id: PortId }, - /// module not found - ModuleNotFound, -} +use ibc_primitives::prelude::*; +use ibc_primitives::{Signer, Timestamp}; -impl From for RouterError { - fn from(error: ContextError) -> Self { - Self::ContextError(error) - } -} - -#[cfg(feature = "std")] -impl std::error::Error for RouterError { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - match &self { - Self::ContextError(e) => Some(e), - _ => None, - } - } -} +use crate::block_delay::calculate_block_delay; /// Context to be implemented by the host that provides all "read-only" methods. /// -/// Trait used for the top-level [`validate`](crate::core::validate) +/// Trait used for the top-level `validate` entrypoint in the `ibc-core` crate. pub trait ValidationContext { type V: ClientValidationContext; type E: ClientExecutionContext; @@ -147,7 +83,7 @@ pub trait ValidationContext { /// requirements](https://github.com/cosmos/ibc/tree/main/spec/core/ics-024-host-requirements#client-state-validation) /// /// Additionally, implementations specific to individual chains can be found - /// in the [hosts](crate::hosts) module. + /// in the `ibc-core-extra` crate. fn validate_self_client( &self, client_state_of_host_on_counterparty: Any, @@ -228,7 +164,7 @@ pub trait ValidationContext { /// Context to be implemented by the host that provides all "write-only" methods. /// -/// Trait used for the top-level [`execute`](crate::core::execute) and [`dispatch`](crate::core::dispatch) +/// Trait used for the top-level `execute` and `dispatch` entrypoints in the `ibc-core` crate. pub trait ExecutionContext: ValidationContext { /// Retrieve the context that implements all clients' `ExecutionContext`. fn get_client_execution_context(&mut self) -> &mut Self::E; diff --git a/crates/ibc-core/context/src/lib.rs b/crates/ibc-core/context/src/lib.rs new file mode 100644 index 000000000..d028936e0 --- /dev/null +++ b/crates/ibc-core/context/src/lib.rs @@ -0,0 +1,21 @@ +#![no_std] +#![forbid(unsafe_code)] +#![cfg_attr(not(test), deny(clippy::unwrap_used))] +#![cfg_attr(not(test), deny(clippy::disallowed_methods, clippy::disallowed_types))] +#![deny( + warnings, + trivial_numeric_casts, + unused_import_braces, + unused_qualifications, + rust_2018_idioms +)] + +pub(crate) mod block_delay; + +mod context; +pub use context::*; + +pub mod types { + #[doc(inline)] + pub use ibc_core_context_types::*; +} diff --git a/crates/ibc-core/context/types/Cargo.toml b/crates/ibc-core/context/types/Cargo.toml new file mode 100644 index 000000000..998ad74a0 --- /dev/null +++ b/crates/ibc-core/context/types/Cargo.toml @@ -0,0 +1,72 @@ +[package] +name = "ibc-core-context-types" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc", "data structures"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +serde = { workspace = true, optional = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc-primitives = { workspace = true } +ibc-core-client-types = { workspace = true } +ibc-core-connection-types = { workspace = true } +ibc-core-channel-types = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-router-types = { workspace = true } +ibc-proto = { workspace = true } + +# cosmos dependencies +tendermint = { workspace = true } + +[dev-dependencies] +ibc-testkit = { workspace = true } + +[features] +default = ["std"] +std = [ + "displaydoc/std", + "prost/std", + "subtle-encoding/std", + "ibc-primitives/std", + "ibc-core-client-types/std", + "ibc-core-connection-types/std", + "ibc-core-channel-types/std", + "ibc-core-commitment-types/std", + "ibc-core-host-types/std", + "ibc-core-router-types/std", + "ibc-proto/std", + "tendermint/std", + "ibc-testkit/std", +] +borsh = ["ibc-proto/borsh"] +serde = [ + "dep:serde", + "ibc-proto/serde", + "ibc-primitives/serde", + "ibc-core-client-types/serde", + "ibc-core-connection-types/serde", + "ibc-core-channel-types/serde", + "ibc-core-commitment-types/serde", + "ibc-core-host-types/serde", + "ibc-core-router-types/serde", +] +schema = ["ibc-proto/json-schema", "std"] +parity-scale-codec = ["ibc-proto/parity-scale-codec"] diff --git a/crates/ibc-core/context/types/src/error.rs b/crates/ibc-core/context/types/src/error.rs new file mode 100644 index 000000000..8c4e17b45 --- /dev/null +++ b/crates/ibc-core/context/types/src/error.rs @@ -0,0 +1,46 @@ +use derive_more::From; +use displaydoc::Display; +use ibc_core_channel_types::error::{ChannelError, PacketError}; +use ibc_core_client_types::error::ClientError; +use ibc_core_connection_types::error::ConnectionError; +use ibc_core_router_types::error::RouterError; +use ibc_primitives::prelude::*; + +/// Top-level error +#[derive(Debug, Display, From)] +pub enum ContextError { + /// ICS02 Client error: {0} + ClientError(ClientError), + /// ICS03 Connection error: {0} + ConnectionError(ConnectionError), + /// ICS04 Channel error: {0} + ChannelError(ChannelError), + /// ICS04 Packet error: {0} + PacketError(PacketError), + /// ICS26 Routing error: {0} + RouterError(RouterError), +} + +impl From for ClientError { + fn from(context_error: ContextError) -> Self { + match context_error { + ContextError::ClientError(e) => e, + _ => ClientError::Other { + description: context_error.to_string(), + }, + } + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ContextError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::ClientError(e) => Some(e), + Self::ConnectionError(e) => Some(e), + Self::ChannelError(e) => Some(e), + Self::PacketError(e) => Some(e), + Self::RouterError(e) => Some(e), + } + } +} diff --git a/crates/ibc/src/core/events.rs b/crates/ibc-core/context/types/src/events.rs similarity index 77% rename from crates/ibc/src/core/events.rs rename to crates/ibc-core/context/types/src/events.rs index b4a2b5292..efc4390ca 100644 --- a/crates/ibc/src/core/events.rs +++ b/crates/ibc-core/context/types/src/events.rs @@ -3,16 +3,16 @@ use core::convert::{TryFrom, TryInto}; use displaydoc::Display; +use ibc_core_channel_types::{error as channel_error, events as ChannelEvents}; +use ibc_core_client_types::error as client_error; +use ibc_core_client_types::events::{self as ClientEvents}; +use ibc_core_connection_types::{error as connection_error, events as ConnectionEvents}; +use ibc_core_host_types::error::IdentifierError; +use ibc_core_router_types::event::ModuleEvent; +use ibc_primitives::prelude::*; +use ibc_primitives::ParseTimestampError; use tendermint::abci; -use super::ics24_host::identifier::IdentifierError; -use crate::core::ics02_client::error as client_error; -use crate::core::ics02_client::events::{self as ClientEvents}; -use crate::core::ics03_connection::{error as connection_error, events as ConnectionEvents}; -use crate::core::ics04_channel::{error as channel_error, events as ChannelEvents}; -use crate::core::timestamp::ParseTimestampError; -use crate::prelude::*; - /// All error variants related to IBC events #[derive(Debug, Display)] pub enum Error { @@ -122,7 +122,7 @@ impl TryFrom for abci::Event { IbcEvent::AcknowledgePacket(event) => event.try_into().map_err(Error::Channel)?, IbcEvent::TimeoutPacket(event) => event.try_into().map_err(Error::Channel)?, IbcEvent::ChannelClosed(event) => event.into(), - IbcEvent::Module(event) => event.try_into()?, + IbcEvent::Module(event) => event.into(), IbcEvent::Message(event) => abci::Event { kind: MESSAGE_EVENT.to_string(), attributes: vec![("module", event.module_attribute(), true).into()], @@ -160,79 +160,6 @@ impl IbcEvent { } } -/// The event type emitted by IBC applications -#[cfg_attr( - feature = "parity-scale-codec", - derive( - parity_scale_codec::Encode, - parity_scale_codec::Decode, - scale_info::TypeInfo - ) -)] -#[cfg_attr( - feature = "borsh", - derive(borsh::BorshSerialize, borsh::BorshDeserialize) -)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleEvent { - pub kind: String, - pub attributes: Vec, -} - -impl TryFrom for abci::Event { - type Error = Error; - - fn try_from(event: ModuleEvent) -> Result { - let attributes = event.attributes.into_iter().map(Into::into).collect(); - Ok(abci::Event { - kind: event.kind, - attributes, - }) - } -} - -impl From for IbcEvent { - fn from(e: ModuleEvent) -> Self { - IbcEvent::Module(e) - } -} - -/// A single key/value pair in a [`ModuleEvent`] -#[cfg_attr( - feature = "parity-scale-codec", - derive( - parity_scale_codec::Encode, - parity_scale_codec::Decode, - scale_info::TypeInfo - ) -)] -#[cfg_attr( - feature = "borsh", - derive(borsh::BorshSerialize, borsh::BorshDeserialize) -)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ModuleEventAttribute { - pub key: String, - pub value: String, -} - -impl From<(K, V)> for ModuleEventAttribute { - fn from((k, v): (K, V)) -> Self { - Self { - key: k.to_string(), - value: v.to_string(), - } - } -} - -impl From for abci::EventAttribute { - fn from(attr: ModuleEventAttribute) -> Self { - (attr.key, attr.value).into() - } -} - /// An event type that is emitted by the Cosmos SDK. /// /// We need to emit it as well, as currently [hermes] relies on it. @@ -279,17 +206,22 @@ impl From for IbcEvent { } } +impl From for IbcEvent { + fn from(e: ModuleEvent) -> Self { + IbcEvent::Module(e) + } +} + #[cfg(test)] pub mod tests { - use alloc::vec; + use ibc_core_channel_types::channel::Order; + use ibc_core_channel_types::events::SendPacket; + use ibc_core_channel_types::packet::Packet; + use ibc_core_host_types::identifiers::ConnectionId; use ibc_testkit::utils::core::channel::dummy_raw_packet; use super::*; - use crate::core::ics04_channel::channel::Order; - use crate::core::ics04_channel::events::SendPacket; - use crate::core::ics04_channel::packet::Packet; - use crate::core::ics24_host::identifier::ConnectionId; #[test] /// Ensures that we don't panic when packet data is not valid UTF-8. diff --git a/crates/ibc-core/context/types/src/lib.rs b/crates/ibc-core/context/types/src/lib.rs new file mode 100644 index 000000000..93ab14d59 --- /dev/null +++ b/crates/ibc-core/context/types/src/lib.rs @@ -0,0 +1,22 @@ +#![no_std] +#![forbid(unsafe_code)] +#![cfg_attr(not(test), deny(clippy::unwrap_used))] +#![cfg_attr(not(test), deny(clippy::disallowed_methods, clippy::disallowed_types,))] +#![deny( + warnings, + trivial_numeric_casts, + unused_import_braces, + unused_qualifications, + rust_2018_idioms +)] + +#[cfg(feature = "std")] +extern crate std; + +pub mod error; +pub mod events; +pub mod msgs; + +pub mod proto { + pub use ibc_proto::google::protobuf::Any; +} diff --git a/crates/ibc-core/context/types/src/msgs.rs b/crates/ibc-core/context/types/src/msgs.rs new file mode 100644 index 000000000..849bcaaf6 --- /dev/null +++ b/crates/ibc-core/context/types/src/msgs.rs @@ -0,0 +1,206 @@ +use ibc_core_channel_types::msgs::{ + ChannelMsg, MsgAcknowledgement, MsgChannelCloseConfirm, MsgChannelCloseInit, MsgChannelOpenAck, + MsgChannelOpenConfirm, MsgChannelOpenInit, MsgChannelOpenTry, MsgRecvPacket, MsgTimeout, + MsgTimeoutOnClose, PacketMsg, ACKNOWLEDGEMENT_TYPE_URL, CHAN_CLOSE_CONFIRM_TYPE_URL, + CHAN_CLOSE_INIT_TYPE_URL, CHAN_OPEN_ACK_TYPE_URL, CHAN_OPEN_CONFIRM_TYPE_URL, + CHAN_OPEN_INIT_TYPE_URL, CHAN_OPEN_TRY_TYPE_URL, RECV_PACKET_TYPE_URL, + TIMEOUT_ON_CLOSE_TYPE_URL, TIMEOUT_TYPE_URL, +}; +use ibc_core_client_types::msgs::{ + ClientMsg, MsgCreateClient, MsgSubmitMisbehaviour, MsgUpdateClient, MsgUpgradeClient, + CREATE_CLIENT_TYPE_URL, SUBMIT_MISBEHAVIOUR_TYPE_URL, UPDATE_CLIENT_TYPE_URL, + UPGRADE_CLIENT_TYPE_URL, +}; +use ibc_core_connection_types::msgs::{ + ConnectionMsg, MsgConnectionOpenAck, MsgConnectionOpenConfirm, MsgConnectionOpenInit, + MsgConnectionOpenTry, CONN_OPEN_ACK_TYPE_URL, CONN_OPEN_CONFIRM_TYPE_URL, + CONN_OPEN_INIT_TYPE_URL, CONN_OPEN_TRY_TYPE_URL, +}; +use ibc_core_router_types::error::RouterError; +use ibc_primitives::prelude::*; +use ibc_proto::google::protobuf::Any; +use ibc_proto::Protobuf; + +/// Enumeration of all messages that the local ICS26 module is capable of routing. +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[derive(Clone, Debug, PartialEq, Eq, derive_more::From)] +pub enum MsgEnvelope { + Client(ClientMsg), + Connection(ConnectionMsg), + Channel(ChannelMsg), + Packet(PacketMsg), +} + +impl TryFrom for MsgEnvelope { + type Error = RouterError; + + fn try_from(any_msg: Any) -> Result { + match any_msg.type_url.as_str() { + // ICS2 messages + CREATE_CLIENT_TYPE_URL => { + // Pop out the message and then wrap it in the corresponding type. + let domain_msg = MsgCreateClient::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Client(ClientMsg::CreateClient(domain_msg))) + } + UPDATE_CLIENT_TYPE_URL => { + let domain_msg = MsgUpdateClient::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Client(ClientMsg::UpdateClient(domain_msg))) + } + UPGRADE_CLIENT_TYPE_URL => { + let domain_msg = MsgUpgradeClient::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Client(ClientMsg::UpgradeClient(domain_msg))) + } + SUBMIT_MISBEHAVIOUR_TYPE_URL => { + let domain_msg = + MsgSubmitMisbehaviour::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Client(ClientMsg::Misbehaviour(domain_msg))) + } + + // ICS03 + CONN_OPEN_INIT_TYPE_URL => { + let domain_msg = + MsgConnectionOpenInit::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Connection(ConnectionMsg::OpenInit(domain_msg))) + } + CONN_OPEN_TRY_TYPE_URL => { + let domain_msg = MsgConnectionOpenTry::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Connection(ConnectionMsg::OpenTry(domain_msg))) + } + CONN_OPEN_ACK_TYPE_URL => { + let domain_msg = MsgConnectionOpenAck::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Connection(ConnectionMsg::OpenAck(domain_msg))) + } + CONN_OPEN_CONFIRM_TYPE_URL => { + let domain_msg = + MsgConnectionOpenConfirm::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Connection(ConnectionMsg::OpenConfirm( + domain_msg, + ))) + } + + // ICS04 channel messages + CHAN_OPEN_INIT_TYPE_URL => { + let domain_msg = MsgChannelOpenInit::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Channel(ChannelMsg::OpenInit(domain_msg))) + } + CHAN_OPEN_TRY_TYPE_URL => { + let domain_msg = MsgChannelOpenTry::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Channel(ChannelMsg::OpenTry(domain_msg))) + } + CHAN_OPEN_ACK_TYPE_URL => { + let domain_msg = MsgChannelOpenAck::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Channel(ChannelMsg::OpenAck(domain_msg))) + } + CHAN_OPEN_CONFIRM_TYPE_URL => { + let domain_msg = + MsgChannelOpenConfirm::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Channel(ChannelMsg::OpenConfirm(domain_msg))) + } + CHAN_CLOSE_INIT_TYPE_URL => { + let domain_msg = MsgChannelCloseInit::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Channel(ChannelMsg::CloseInit(domain_msg))) + } + CHAN_CLOSE_CONFIRM_TYPE_URL => { + let domain_msg = + MsgChannelCloseConfirm::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Channel(ChannelMsg::CloseConfirm(domain_msg))) + } + // ICS04 packet messages + RECV_PACKET_TYPE_URL => { + let domain_msg = MsgRecvPacket::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Packet(PacketMsg::Recv(domain_msg))) + } + ACKNOWLEDGEMENT_TYPE_URL => { + let domain_msg = MsgAcknowledgement::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Packet(PacketMsg::Ack(domain_msg))) + } + TIMEOUT_TYPE_URL => { + let domain_msg = MsgTimeout::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Packet(PacketMsg::Timeout(domain_msg))) + } + TIMEOUT_ON_CLOSE_TYPE_URL => { + let domain_msg = MsgTimeoutOnClose::decode_vec(&any_msg.value).map_err(|e| { + RouterError::MalformedMessageBytes { + reason: e.to_string(), + } + })?; + Ok(MsgEnvelope::Packet(PacketMsg::TimeoutOnClose(domain_msg))) + } + _ => Err(RouterError::UnknownMessageTypeUrl { + url: any_msg.type_url, + }), + } + } +} diff --git a/crates/ibc-core/extra/Cargo.toml b/crates/ibc-core/extra/Cargo.toml new file mode 100644 index 000000000..6c6e52baa --- /dev/null +++ b/crates/ibc-core/extra/Cargo.toml @@ -0,0 +1,46 @@ +[package] +name = "ibc-core-extra" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc = { workspace = true } +ibc-core-client-types = { workspace = true } +ibc-core-client-context = { workspace = true } +ibc-core-connection-types = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-context-types = { workspace = true } +ibc-primitives = { workspace = true } +ibc-proto = { workspace = true } + +# cosmos dependencies +tendermint = { workspace = true } + +[dev-dependencies] +ibc-testkit = { workspace = true } +[features] +default = ["std"] +std = [ +] +serde = [ +] \ No newline at end of file diff --git a/crates/ibc/src/hosts/mod.rs b/crates/ibc-core/extra/src/lib.rs similarity index 100% rename from crates/ibc/src/hosts/mod.rs rename to crates/ibc-core/extra/src/lib.rs diff --git a/crates/ibc/src/hosts/tendermint/mod.rs b/crates/ibc-core/extra/src/tendermint/mod.rs similarity index 100% rename from crates/ibc/src/hosts/tendermint/mod.rs rename to crates/ibc-core/extra/src/tendermint/mod.rs diff --git a/crates/ibc/src/hosts/tendermint/upgrade_proposal/context.rs b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/context.rs similarity index 88% rename from crates/ibc/src/hosts/tendermint/upgrade_proposal/context.rs rename to crates/ibc-core/extra/src/tendermint/upgrade_proposal/context.rs index 29428a2be..eaa9313a8 100644 --- a/crates/ibc/src/hosts/tendermint/upgrade_proposal/context.rs +++ b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/context.rs @@ -5,12 +5,13 @@ //! [Basecoin-rs](https://github.com/informalsystems/basecoin-rs) repository. //! If it proves to be generic enough, we may move it to the ICS02 section. +use ibc_core_client_context::client_state::ClientState; +use ibc_core_client_context::consensus_state::ConsensusState; +use ibc_core_client_context::{ClientExecutionContext, ClientValidationContext}; +use ibc_core_client_types::error::UpgradeClientError; +use ibc_core_host_types::path::UpgradeClientPath; + use super::Plan; -use crate::core::ics02_client::client_state::ClientState; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::UpgradeClientError; -use crate::core::ics02_client::{ClientExecutionContext, ClientValidationContext}; -use crate::core::ics24_host::path::UpgradeClientPath; /// Helper context to validate client upgrades, providing methods to retrieve /// an upgrade plan and related upgraded client and consensus states. diff --git a/crates/ibc/src/hosts/tendermint/upgrade_proposal/events.rs b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/events.rs similarity index 98% rename from crates/ibc/src/hosts/tendermint/upgrade_proposal/events.rs rename to crates/ibc-core/extra/src/tendermint/upgrade_proposal/events.rs index 0cb380d18..b4e3550c9 100644 --- a/crates/ibc/src/hosts/tendermint/upgrade_proposal/events.rs +++ b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/events.rs @@ -1,10 +1,7 @@ //! Definitions of events emitted when an upgrade client is proposed or executed. -use alloc::borrow::ToOwned; -use alloc::string::{String, ToString}; -use alloc::vec; - use derive_more::From; +use ibc_primitives::prelude::*; use tendermint::abci; const UPGRADE_CHAIN_EVENT: &str = "upgrade_chain"; diff --git a/crates/ibc/src/hosts/tendermint/upgrade_proposal/handler.rs b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/handler.rs similarity index 82% rename from crates/ibc/src/hosts/tendermint/upgrade_proposal/handler.rs rename to crates/ibc-core/extra/src/tendermint/upgrade_proposal/handler.rs index 0680854ca..7f0de895a 100644 --- a/crates/ibc/src/hosts/tendermint/upgrade_proposal/handler.rs +++ b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/handler.rs @@ -1,11 +1,10 @@ -use alloc::string::ToString; - +use ibc::clients::ics07_tendermint::client_state::ClientState as TmClientState; +use ibc_core_client_types::error::UpgradeClientError; +use ibc_core_host_types::path::UpgradeClientPath; +use ibc_primitives::prelude::*; use tendermint::abci::Event as TmEvent; -use crate::clients::ics07_tendermint::client_state::ClientState as TmClientState; -use crate::core::ics02_client::error::UpgradeClientError; -use crate::core::ics24_host::path::UpgradeClientPath; -use crate::hosts::tendermint::upgrade_proposal::{ +use crate::tendermint::upgrade_proposal::{ UpgradeClientProposal, UpgradeExecutionContext, UpgradeProposal, }; diff --git a/crates/ibc/src/hosts/tendermint/upgrade_proposal/mod.rs b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/mod.rs similarity index 100% rename from crates/ibc/src/hosts/tendermint/upgrade_proposal/mod.rs rename to crates/ibc-core/extra/src/tendermint/upgrade_proposal/mod.rs diff --git a/crates/ibc/src/hosts/tendermint/upgrade_proposal/plan.rs b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/plan.rs similarity index 94% rename from crates/ibc/src/hosts/tendermint/upgrade_proposal/plan.rs rename to crates/ibc-core/extra/src/tendermint/upgrade_proposal/plan.rs index 075e0b692..d1a25adcc 100644 --- a/crates/ibc/src/hosts/tendermint/upgrade_proposal/plan.rs +++ b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/plan.rs @@ -1,15 +1,12 @@ //! Definition of domain `Plan` type. -use alloc::format; -use alloc::string::{String, ToString}; - +use ibc_core_client_types::error::UpgradeClientError; +use ibc_primitives::prelude::*; use ibc_proto::cosmos::upgrade::v1beta1::Plan as RawPlan; use ibc_proto::google::protobuf::Any; use ibc_proto::Protobuf; -use crate::core::ics02_client::error::UpgradeClientError; - -pub(crate) const TYPE_URL: &str = "/cosmos.upgrade.v1beta1.Plan"; +pub const TYPE_URL: &str = "/cosmos.upgrade.v1beta1.Plan"; /// Specifies information about a planned upgrade and at which height it should /// be performed. diff --git a/crates/ibc/src/hosts/tendermint/upgrade_proposal/proposal.rs b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/proposal.rs similarity index 96% rename from crates/ibc/src/hosts/tendermint/upgrade_proposal/proposal.rs rename to crates/ibc-core/extra/src/tendermint/upgrade_proposal/proposal.rs index 46deaeda2..5f24c9523 100644 --- a/crates/ibc/src/hosts/tendermint/upgrade_proposal/proposal.rs +++ b/crates/ibc-core/extra/src/tendermint/upgrade_proposal/proposal.rs @@ -1,13 +1,12 @@ //! Definition of domain `UpgradeProposal` type for handling upgrade client proposal -use alloc::string::{String, ToString}; - +use ibc_core_client_types::error::UpgradeClientError; +use ibc_primitives::prelude::*; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::UpgradeProposal as RawUpgradeProposal; use ibc_proto::Protobuf; use super::Plan; -use crate::core::ics02_client::error::UpgradeClientError; /// Defines a governance proposal of type `Content` that enables the initiation /// of an IBC breaking upgrade and specifies the new client state that should be diff --git a/crates/ibc/src/hosts/tendermint/validate_self_client.rs b/crates/ibc-core/extra/src/tendermint/validate_self_client.rs similarity index 91% rename from crates/ibc/src/hosts/tendermint/validate_self_client.rs rename to crates/ibc-core/extra/src/tendermint/validate_self_client.rs index 6b7762114..4ec53f2ee 100644 --- a/crates/ibc/src/hosts/tendermint/validate_self_client.rs +++ b/crates/ibc-core/extra/src/tendermint/validate_self_client.rs @@ -1,19 +1,17 @@ -use alloc::format; -use alloc::string::{String, ToString}; use core::time::Duration; +use ibc::clients::ics07_tendermint::client_state::ClientState as TmClientState; +use ibc_core_client_context::client_state::ClientStateCommon; +use ibc_core_client_types::error::ClientError; +use ibc_core_client_types::Height; +use ibc_core_commitment_types::specs::ProofSpecs; +use ibc_core_connection_types::error::ConnectionError; +use ibc_core_context_types::error::ContextError; +use ibc_core_host_types::identifiers::ChainId; +use ibc_primitives::prelude::*; use ibc_proto::google::protobuf::Any; use tendermint::trust_threshold::TrustThresholdFraction as TendermintTrustThresholdFraction; -use crate::clients::ics07_tendermint::client_state::ClientState as TmClientState; -use crate::core::ics02_client::client_state::ClientStateCommon; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics23_commitment::specs::ProofSpecs; -use crate::core::ics24_host::identifier::ChainId; -use crate::core::ContextError; -use crate::Height; - /// Provides an implementation of `ValidationContext::validate_self_client` for /// Tendermint-based hosts. pub trait ValidateSelfClientContext { diff --git a/crates/ibc-core/ics02-client/Cargo.toml b/crates/ibc-core/ics02-client/Cargo.toml new file mode 100644 index 000000000..7b201a651 --- /dev/null +++ b/crates/ibc-core/ics02-client/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "ibc-core-client" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +prost = { workspace = true } + +# ibc dependencies +ibc-core-client-types = { workspace = true } +ibc-core-client-context = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-context = { workspace = true } +ibc-derive = { workspace = true } + +[features] +default = ["std"] +std = [ + "ibc-core-client-types/std", +] +serde = [ + "ibc-core-client-types/serde", +] \ No newline at end of file diff --git a/crates/ibc-core/ics02-client/context/Cargo.toml b/crates/ibc-core/ics02-client/context/Cargo.toml new file mode 100644 index 000000000..0293bc3e8 --- /dev/null +++ b/crates/ibc-core/ics02-client/context/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "ibc-core-client-context" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc-derive = { workspace = true } +ibc-primitives = { workspace = true } +ibc-core-client-types = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-context-types = { workspace = true } +ibc-proto = {workspace = true } + +# cosmos dependencies +tendermint = { workspace = true } + +[dev-dependencies] +ibc-testkit = { workspace = true } + +[features] +default = ["std"] +std = [ +] +serde = [ +] \ No newline at end of file diff --git a/crates/ibc/src/core/ics02_client/client_state.rs b/crates/ibc-core/ics02-client/context/src/client_state.rs similarity index 80% rename from crates/ibc/src/core/ics02_client/client_state.rs rename to crates/ibc-core/ics02-client/context/src/client_state.rs index 05ee1e37b..fc9b9fee5 100644 --- a/crates/ibc/src/core/ics02_client/client_state.rs +++ b/crates/ibc-core/ics02-client/context/src/client_state.rs @@ -1,66 +1,16 @@ //! Defines `ClientState`, the core type to be implemented by light clients -use core::fmt::{Debug, Display, Formatter}; use core::marker::{Send, Sync}; -use ibc_proto::google::protobuf::Any; - -use crate::core::ics02_client::client_type::ClientType; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics02_client::ClientExecutionContext; -use crate::core::ics23_commitment::commitment::{ +use ibc_core_client_types::error::ClientError; +use ibc_core_client_types::primitives::prelude::*; +use ibc_core_client_types::proto::Any; +use ibc_core_client_types::{Height, Status, UpdateKind}; +use ibc_core_commitment_types::commitment::{ CommitmentPrefix, CommitmentProofBytes, CommitmentRoot, }; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::ics24_host::path::Path; -use crate::prelude::*; -use crate::Height; - -/// `UpdateKind` represents the 2 ways that a client can be updated -/// in IBC: either through a `MsgUpdateClient`, or a `MsgSubmitMisbehaviour`. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum UpdateKind { - /// this is the typical scenario where a new header is submitted to the client - /// to update the client. Note that light clients are free to define the type - /// of the object used to update them (e.g. could be a list of headers). - UpdateClient, - /// this is the scenario where misbehaviour is submitted to the client - /// (e.g 2 headers with the same height in Tendermint) - SubmitMisbehaviour, -} - -/// Represents the status of a client -#[derive(Debug, PartialEq, Eq)] -pub enum Status { - /// The client is active and allowed to be used - Active, - /// The client is frozen and not allowed to be used - Frozen, - /// The client is expired and not allowed to be used - Expired, - /// Unauthorized indicates that the client type is not registered as an allowed client type. - Unauthorized, -} - -impl Status { - pub fn is_active(&self) -> bool { - *self == Status::Active - } - - pub fn is_frozen(&self) -> bool { - *self == Status::Frozen - } - - pub fn is_expired(&self) -> bool { - *self == Status::Expired - } -} - -impl Display for Status { - fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { - write!(f, "{self:?}") - } -} +use ibc_core_host_types::identifiers::{ClientId, ClientType}; +use ibc_core_host_types::path::Path; /// `ClientState` methods needed in both validation and execution. /// @@ -242,7 +192,7 @@ where /// `ClientExecutionContext` (e.g. `MyType` would not be supported). pub use ibc_derive::ClientState; -use super::ClientValidationContext; +use crate::context::{ClientExecutionContext, ClientValidationContext}; /// Primary client trait. Defines all the methods that clients must implement. /// diff --git a/crates/ibc/src/core/ics02_client/consensus_state.rs b/crates/ibc-core/ics02-client/context/src/consensus_state.rs similarity index 86% rename from crates/ibc/src/core/ics02_client/consensus_state.rs rename to crates/ibc-core/ics02-client/context/src/consensus_state.rs index ea5e05e37..b020b4747 100644 --- a/crates/ibc/src/core/ics02_client/consensus_state.rs +++ b/crates/ibc-core/ics02-client/context/src/consensus_state.rs @@ -2,14 +2,13 @@ use core::marker::{Send, Sync}; +use ibc_core_client_types::primitives::prelude::*; +use ibc_core_client_types::primitives::Timestamp; +use ibc_core_commitment_types::commitment::CommitmentRoot; /// Derive macro that implements [`ConsensusState`] for enums containing /// variants that implement [`ConsensusState`] pub use ibc_derive::ConsensusState; -use crate::core::ics23_commitment::commitment::CommitmentRoot; -use crate::core::timestamp::Timestamp; -use crate::prelude::*; - /// Defines methods that all `ConsensusState`s should provide. /// /// One can think of a "consensus state" as a pruned header, to be stored on chain. In other words, diff --git a/crates/ibc/src/core/ics02_client/context.rs b/crates/ibc-core/ics02-client/context/src/context.rs similarity index 90% rename from crates/ibc/src/core/ics02_client/context.rs rename to crates/ibc-core/ics02-client/context/src/context.rs index 093cdf610..99f1711ce 100644 --- a/crates/ibc/src/core/ics02_client/context.rs +++ b/crates/ibc-core/ics02-client/context/src/context.rs @@ -1,14 +1,15 @@ +use ibc_core_client_types::primitives::Timestamp; +use ibc_core_client_types::Height; +use ibc_core_context_types::error::ContextError; +use ibc_core_host_types::identifiers::ClientId; +use ibc_core_host_types::path::{ClientConsensusStatePath, ClientStatePath}; + use super::client_state::ClientState; use super::consensus_state::ConsensusState; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::ics24_host::path::{ClientConsensusStatePath, ClientStatePath}; -use crate::core::timestamp::Timestamp; -use crate::core::ContextError; -use crate::Height; /// Defines the methods available to clients for validating client state /// transitions. The generic `V` parameter in -/// [crate::core::ics02_client::client_state::ClientStateValidation] must +/// [crate::client_state::ClientStateValidation] must /// inherit from this trait. pub trait ClientValidationContext { /// Returns the time when the client state for the given [`ClientId`] was updated with a header for the given [`Height`] @@ -28,7 +29,7 @@ pub trait ClientValidationContext { /// Defines the methods that all client `ExecutionContext`s (precisely the /// generic parameter of -/// [`crate::core::ics02_client::client_state::ClientStateExecution`] ) must +/// [`crate::client_state::ClientStateExecution`] ) must /// implement. /// /// Specifically, clients have the responsibility to store their client state diff --git a/crates/ibc-core/ics02-client/context/src/lib.rs b/crates/ibc-core/ics02-client/context/src/lib.rs new file mode 100644 index 000000000..4dd20dda2 --- /dev/null +++ b/crates/ibc-core/ics02-client/context/src/lib.rs @@ -0,0 +1,5 @@ +pub mod client_state; +pub mod consensus_state; + +mod context; +pub use context::*; diff --git a/crates/ibc/src/core/ics02_client/handler/create_client.rs b/crates/ibc-core/ics02-client/src/handler/create_client.rs similarity index 75% rename from crates/ibc/src/core/ics02_client/handler/create_client.rs rename to crates/ibc-core/ics02-client/src/handler/create_client.rs index 342fefb16..d73a76864 100644 --- a/crates/ibc/src/core/ics02_client/handler/create_client.rs +++ b/crates/ibc-core/ics02-client/src/handler/create_client.rs @@ -1,16 +1,16 @@ //! Protocol logic specific to processing ICS2 messages of type `MsgCreateClient`. -use crate::core::context::ContextError; -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateExecution}; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics02_client::events::CreateClient; -use crate::core::ics02_client::msgs::create_client::MsgCreateClient; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::{ExecutionContext, ValidationContext}; -use crate::prelude::*; - -pub(crate) fn validate(ctx: &Ctx, msg: MsgCreateClient) -> Result<(), ContextError> +use ibc_core_client_context::client_state::{ClientStateCommon, ClientStateExecution}; +use ibc_core_client_types::error::ClientError; +use ibc_core_client_types::events::CreateClient; +use ibc_core_client_types::msgs::MsgCreateClient; +use ibc_core_client_types::primitives::prelude::*; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::identifiers::ClientId; + +pub fn validate(ctx: &Ctx, msg: MsgCreateClient) -> Result<(), ContextError> where Ctx: ValidationContext, { @@ -46,7 +46,7 @@ where Ok(()) } -pub(crate) fn execute(ctx: &mut Ctx, msg: MsgCreateClient) -> Result<(), ContextError> +pub fn execute(ctx: &mut Ctx, msg: MsgCreateClient) -> Result<(), ContextError> where Ctx: ExecutionContext, { diff --git a/crates/ibc/src/core/ics02_client/handler.rs b/crates/ibc-core/ics02-client/src/handler/mod.rs similarity index 100% rename from crates/ibc/src/core/ics02_client/handler.rs rename to crates/ibc-core/ics02-client/src/handler/mod.rs diff --git a/crates/ibc/src/core/ics02_client/handler/update_client.rs b/crates/ibc-core/ics02-client/src/handler/update_client.rs similarity index 83% rename from crates/ibc/src/core/ics02_client/handler/update_client.rs rename to crates/ibc-core/ics02-client/src/handler/update_client.rs index f4ce3013d..14dcaffd5 100644 --- a/crates/ibc/src/core/ics02_client/handler/update_client.rs +++ b/crates/ibc-core/ics02-client/src/handler/update_client.rs @@ -1,19 +1,19 @@ //! Protocol logic specific to processing ICS2 messages of type `MsgUpdateAnyClient`. -use prost::Message; - -use crate::core::context::ContextError; -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ - ClientStateCommon, ClientStateExecution, ClientStateValidation, UpdateKind, +use ibc_core_client_context::client_state::{ + ClientStateCommon, ClientStateExecution, ClientStateValidation, }; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics02_client::events::{ClientMisbehaviour, UpdateClient}; -use crate::core::ics02_client::msgs::MsgUpdateOrMisbehaviour; -use crate::core::{ExecutionContext, ValidationContext}; -use crate::prelude::*; +use ibc_core_client_types::error::ClientError; +use ibc_core_client_types::events::{ClientMisbehaviour, UpdateClient}; +use ibc_core_client_types::msgs::MsgUpdateOrMisbehaviour; +use ibc_core_client_types::primitives::prelude::*; +use ibc_core_client_types::UpdateKind; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use prost::Message; -pub(crate) fn validate(ctx: &Ctx, msg: MsgUpdateOrMisbehaviour) -> Result<(), ContextError> +pub fn validate(ctx: &Ctx, msg: MsgUpdateOrMisbehaviour) -> Result<(), ContextError> where Ctx: ValidationContext, { @@ -47,7 +47,7 @@ where Ok(()) } -pub(crate) fn execute(ctx: &mut Ctx, msg: MsgUpdateOrMisbehaviour) -> Result<(), ContextError> +pub fn execute(ctx: &mut Ctx, msg: MsgUpdateOrMisbehaviour) -> Result<(), ContextError> where Ctx: ExecutionContext, { diff --git a/crates/ibc/src/core/ics02_client/handler/upgrade_client.rs b/crates/ibc-core/ics02-client/src/handler/upgrade_client.rs similarity index 67% rename from crates/ibc/src/core/ics02_client/handler/upgrade_client.rs rename to crates/ibc-core/ics02-client/src/handler/upgrade_client.rs index de5ebfbbd..facc4c4a9 100644 --- a/crates/ibc/src/core/ics02_client/handler/upgrade_client.rs +++ b/crates/ibc-core/ics02-client/src/handler/upgrade_client.rs @@ -1,19 +1,19 @@ //! Protocol logic specific to processing ICS2 messages of type `MsgUpgradeAnyClient`. //! -use crate::core::context::ContextError; -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ +use ibc_core_client_context::client_state::{ ClientStateCommon, ClientStateExecution, ClientStateValidation, }; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics02_client::events::UpgradeClient; -use crate::core::ics02_client::msgs::upgrade_client::MsgUpgradeClient; -use crate::core::ics24_host::path::ClientConsensusStatePath; -use crate::core::{ExecutionContext, ValidationContext}; -use crate::prelude::*; +use ibc_core_client_context::consensus_state::ConsensusState; +use ibc_core_client_types::error::ClientError; +use ibc_core_client_types::events::UpgradeClient; +use ibc_core_client_types::msgs::MsgUpgradeClient; +use ibc_core_client_types::primitives::prelude::*; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::path::ClientConsensusStatePath; -pub(crate) fn validate(ctx: &Ctx, msg: MsgUpgradeClient) -> Result<(), ContextError> +pub fn validate(ctx: &Ctx, msg: MsgUpgradeClient) -> Result<(), ContextError> where Ctx: ValidationContext, { @@ -35,12 +35,15 @@ where } // Read the latest consensus state from the host chain store. - let old_client_cons_state_path = - ClientConsensusStatePath::new(&client_id, &old_client_state.latest_height()); + let old_client_cons_state_path = ClientConsensusStatePath::new( + client_id.clone(), + old_client_state.latest_height().revision_number(), + old_client_state.latest_height().revision_height(), + ); let old_consensus_state = ctx .consensus_state(&old_client_cons_state_path) .map_err(|_| ClientError::ConsensusStateNotFound { - client_id: client_id.clone(), + client_id, height: old_client_state.latest_height(), })?; @@ -56,7 +59,7 @@ where Ok(()) } -pub(crate) fn execute(ctx: &mut Ctx, msg: MsgUpgradeClient) -> Result<(), ContextError> +pub fn execute(ctx: &mut Ctx, msg: MsgUpgradeClient) -> Result<(), ContextError> where Ctx: ExecutionContext, { diff --git a/crates/ibc-core/ics02-client/src/lib.rs b/crates/ibc-core/ics02-client/src/lib.rs new file mode 100644 index 000000000..9e1b94137 --- /dev/null +++ b/crates/ibc-core/ics02-client/src/lib.rs @@ -0,0 +1,25 @@ +//! ICS 02: Client implementation for verifying remote IBC-enabled chains. +//! Exports data structures and implementations of IBC core client component. +#![no_std] +#![forbid(unsafe_code)] +#![cfg_attr(not(test), deny(clippy::unwrap_used))] +#![cfg_attr(not(test), deny(clippy::disallowed_methods, clippy::disallowed_types,))] +#![deny( + warnings, + trivial_numeric_casts, + unused_import_braces, + unused_qualifications, + rust_2018_idioms +)] + +pub mod handler; + +pub mod context { + #[doc(inline)] + pub use ibc_core_client_context::*; +} + +pub mod types { + #[doc(inline)] + pub use ibc_core_client_types::*; +} diff --git a/crates/ibc-core/ics02-client/types/Cargo.toml b/crates/ibc-core/ics02-client/types/Cargo.toml new file mode 100644 index 000000000..87ff69136 --- /dev/null +++ b/crates/ibc-core/ics02-client/types/Cargo.toml @@ -0,0 +1,73 @@ +[package] +name = "ibc-core-client-types" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +borsh = { workspace = true, optional = true } +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +schemars = { workspace = true, optional = true } +serde = { workspace = true, optional = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-derive = { workspace = true } +ibc-primitives = { workspace = true } +ibc-proto = { workspace = true } + +# cosmos dependencies +tendermint = { workspace = true } + +# parity dependencies +parity-scale-codec = { workspace = true, optional = true } +scale-info = { workspace = true, optional = true } + +[dev-dependencies] +ibc-testkit = { workspace = true } + +[features] +default = ["std"] +std = [ + "ibc-core-commitment-types/std", + "ibc-core-host-types/std", + "ibc-primitives/std", + "ibc-proto/std", + "tendermint/std", +] +serde = [ + "ibc-core-host-types/serde", + "ibc-proto/serde", + "dep:serde", +] +borsh = [ + "dep:borsh", + "ibc-core-host-types/borsh", + "ibc-primitives/borsh", +] +schema = [ + "dep:schemars", + "serde", + "std" +] +parity-scale-codec = [ + "dep:parity-scale-codec", + "dep:scale-info", + "ibc-core-host-types/parity-scale-codec", +] diff --git a/crates/ibc/src/core/ics02_client/error.rs b/crates/ibc-core/ics02-client/types/src/error.rs similarity index 90% rename from crates/ibc/src/core/ics02_client/error.rs rename to crates/ibc-core/ics02-client/types/src/error.rs index f9b79f194..ab40103f1 100644 --- a/crates/ibc/src/core/ics02_client/error.rs +++ b/crates/ibc-core/ics02-client/types/src/error.rs @@ -1,15 +1,15 @@ //! Defines the client error type use displaydoc::Display; +// use ibc::core::ContextError; +use ibc_core_commitment_types::error::CommitmentError; +use ibc_core_host_types::error::IdentifierError; +use ibc_core_host_types::identifiers::{ClientId, ClientType}; +use ibc_primitives::prelude::*; +use ibc_primitives::Timestamp; -use super::client_state::Status; -use crate::core::ics02_client::client_type::ClientType; -use crate::core::ics23_commitment::error::CommitmentError; -use crate::core::ics24_host::identifier::{ClientId, IdentifierError}; -use crate::core::timestamp::Timestamp; -use crate::core::ContextError; -use crate::prelude::*; -use crate::Height; +use super::status::Status; +use crate::height::Height; /// Encodes all the possible client errors #[derive(Debug, Display)] @@ -84,7 +84,7 @@ pub enum ClientError { /// invalid commitment proof bytes error: `{0}` InvalidCommitmentProof(CommitmentError), /// invalid packet timeout timestamp value error: `{0}` - InvalidPacketTimestamp(crate::core::timestamp::ParseTimestampError), + InvalidPacketTimestamp(ibc_primitives::ParseTimestampError), /// mismatch between client and arguments types ClientArgsTypeMismatch { client_type: ClientType }, /// received header height (`{header_height}`) is lower than (or equal to) client latest height (`{latest_height}`) @@ -110,17 +110,6 @@ pub enum ClientError { Other { description: String }, } -impl From for ClientError { - fn from(context_error: ContextError) -> Self { - match context_error { - ContextError::ClientError(e) => e, - _ => ClientError::Other { - description: context_error.to_string(), - }, - } - } -} - impl From<&'static str> for ClientError { fn from(s: &'static str) -> Self { Self::Other { diff --git a/crates/ibc/src/core/ics02_client/events.rs b/crates/ibc-core/ics02-client/types/src/events.rs similarity index 98% rename from crates/ibc/src/core/ics02_client/events.rs rename to crates/ibc-core/ics02-client/types/src/events.rs index e55bb9017..bb6d6ad7e 100644 --- a/crates/ibc/src/core/ics02_client/events.rs +++ b/crates/ibc-core/ics02-client/types/src/events.rs @@ -1,12 +1,11 @@ //! Types for the IBC events emitted from Tendermint Websocket by the client module. use derive_more::From; +use ibc_core_host_types::identifiers::{ClientId, ClientType}; +use ibc_primitives::prelude::*; use subtle_encoding::hex; use tendermint::abci; -use crate::core::ics02_client::client_type::ClientType; -use crate::core::ics02_client::height::Height; -use crate::core::ics24_host::identifier::ClientId; -use crate::prelude::*; +use crate::height::Height; /// Client event types const CREATE_CLIENT_EVENT: &str = "create_client"; diff --git a/crates/ibc/src/core/ics02_client/height.rs b/crates/ibc-core/ics02-client/types/src/height.rs similarity index 98% rename from crates/ibc/src/core/ics02_client/height.rs rename to crates/ibc-core/ics02-client/types/src/height.rs index fbdf42def..889c47c81 100644 --- a/crates/ibc/src/core/ics02_client/height.rs +++ b/crates/ibc-core/ics02-client/types/src/height.rs @@ -5,11 +5,11 @@ use core::num::ParseIntError; use core::str::FromStr; use displaydoc::Display; +use ibc_primitives::prelude::*; use ibc_proto::ibc::core::client::v1::Height as RawHeight; use ibc_proto::Protobuf; -use crate::core::ics02_client::error::ClientError; -use crate::prelude::*; +use crate::error::ClientError; /// The core IBC height type, which represents the height of a chain, /// which typically is the number of blocks since genesis diff --git a/crates/ibc-core/ics02-client/types/src/lib.rs b/crates/ibc-core/ics02-client/types/src/lib.rs new file mode 100644 index 000000000..f6fe044ce --- /dev/null +++ b/crates/ibc-core/ics02-client/types/src/lib.rs @@ -0,0 +1,36 @@ +//! Implementation of the IBC [fungible token transfer](https://github.com/cosmos/ibc/blob/main/spec/app/ics-020-fungible-token-transfer/README.md) (ICS-20) data structures. + +#![no_std] +#![forbid(unsafe_code)] +#![cfg_attr(not(test), deny(clippy::unwrap_used))] +#![cfg_attr(not(test), deny(clippy::disallowed_methods, clippy::disallowed_types,))] +#![deny( + warnings, + trivial_numeric_casts, + unused_import_braces, + unused_qualifications, + rust_2018_idioms +)] + +#[cfg(feature = "std")] +extern crate std; + +pub mod error; +pub mod events; +mod height; +pub mod msgs; +mod status; + +pub use height::*; +pub use status::*; + +/// Re-exports pertinent ibc proto types from the `ibc-proto-rs` crate for added convenience +pub mod proto { + pub use ibc_proto::google::protobuf::Any; + pub use ibc_proto::ibc::core::client::*; + pub use ibc_proto::Protobuf; +} + +pub mod primitives { + pub use ibc_primitives::*; +} diff --git a/crates/ibc/src/core/ics02_client/msgs/create_client.rs b/crates/ibc-core/ics02-client/types/src/msgs/create_client.rs similarity index 88% rename from crates/ibc/src/core/ics02_client/msgs/create_client.rs rename to crates/ibc-core/ics02-client/types/src/msgs/create_client.rs index 9e1e6af13..7c3347980 100644 --- a/crates/ibc/src/core/ics02_client/msgs/create_client.rs +++ b/crates/ibc-core/ics02-client/types/src/msgs/create_client.rs @@ -1,15 +1,14 @@ //! Definition of domain type message `MsgCreateClient`. +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::MsgCreateClient as RawMsgCreateClient; use ibc_proto::Protobuf; -use crate::core::ics02_client::error::ClientError; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; +use crate::error::ClientError; -pub(crate) const TYPE_URL: &str = "/ibc.core.client.v1.MsgCreateClient"; +pub const CREATE_CLIENT_TYPE_URL: &str = "/ibc.core.client.v1.MsgCreateClient"; /// A type of message that triggers the creation of a new on-chain (IBC) client. #[cfg_attr( @@ -38,7 +37,7 @@ impl Msg for MsgCreateClient { type Raw = RawMsgCreateClient; fn type_url(&self) -> String { - TYPE_URL.to_string() + CREATE_CLIENT_TYPE_URL.to_string() } } @@ -77,9 +76,8 @@ mod tests { use ibc_proto::ibc::core::client::v1::MsgCreateClient as RawMsgCreateClient; use ibc_testkit::utils::core::client::dummy_raw_msg_create_client; - use test_log::test; - use crate::core::ics02_client::msgs::create_client::MsgCreateClient; + use crate::msgs::create_client::MsgCreateClient; #[test] fn msg_create_client_serialization() { diff --git a/crates/ibc/src/core/ics02_client/msgs/misbehaviour.rs b/crates/ibc-core/ics02-client/types/src/msgs/misbehaviour.rs similarity index 86% rename from crates/ibc/src/core/ics02_client/msgs/misbehaviour.rs rename to crates/ibc-core/ics02-client/types/src/msgs/misbehaviour.rs index 925bd69f9..d33651821 100644 --- a/crates/ibc/src/core/ics02_client/msgs/misbehaviour.rs +++ b/crates/ibc-core/ics02-client/types/src/msgs/misbehaviour.rs @@ -1,16 +1,15 @@ //! Definition of domain type message `MsgSubmitMisbehaviour`. +use ibc_core_host_types::identifiers::ClientId; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::google::protobuf::Any as ProtoAny; use ibc_proto::ibc::core::client::v1::MsgSubmitMisbehaviour as RawMsgSubmitMisbehaviour; use ibc_proto::Protobuf; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; +use crate::error::ClientError; -pub(crate) const TYPE_URL: &str = "/ibc.core.client.v1.MsgSubmitMisbehaviour"; +pub const SUBMIT_MISBEHAVIOUR_TYPE_URL: &str = "/ibc.core.client.v1.MsgSubmitMisbehaviour"; /// A type of message that submits client misbehaviour proof. #[cfg_attr( @@ -32,7 +31,7 @@ impl Msg for MsgSubmitMisbehaviour { type Raw = RawMsgSubmitMisbehaviour; fn type_url(&self) -> String { - TYPE_URL.to_string() + SUBMIT_MISBEHAVIOUR_TYPE_URL.to_string() } } diff --git a/crates/ibc/src/core/ics02_client/msgs.rs b/crates/ibc-core/ics02-client/types/src/msgs/mod.rs similarity index 65% rename from crates/ibc/src/core/ics02_client/msgs.rs rename to crates/ibc-core/ics02-client/types/src/msgs/mod.rs index 22140248f..33330a77d 100644 --- a/crates/ibc/src/core/ics02_client/msgs.rs +++ b/crates/ibc-core/ics02-client/types/src/msgs/mod.rs @@ -1,18 +1,18 @@ //! Defines the client message types that are sent to the chain by the relayer. +use ibc_core_host_types::identifiers::ClientId; +use ibc_primitives::prelude::*; +use ibc_primitives::Signer; use ibc_proto::google::protobuf::Any; -use crate::core::ics02_client::msgs::create_client::MsgCreateClient; -use crate::core::ics02_client::msgs::misbehaviour::MsgSubmitMisbehaviour; -use crate::core::ics02_client::msgs::update_client::MsgUpdateClient; -use crate::core::ics02_client::msgs::upgrade_client::MsgUpgradeClient; -use crate::core::ics24_host::identifier::ClientId; -use crate::prelude::*; -use crate::signer::Signer; +mod create_client; +mod misbehaviour; +mod update_client; +mod upgrade_client; -pub mod create_client; -pub mod misbehaviour; -pub mod update_client; -pub mod upgrade_client; +pub use create_client::*; +pub use misbehaviour::*; +pub use update_client::*; +pub use upgrade_client::*; /// Encodes all the different client messages #[allow(dead_code)] @@ -29,27 +29,27 @@ pub enum ClientMsg { UpgradeClient(MsgUpgradeClient), } -pub(crate) enum MsgUpdateOrMisbehaviour { +pub enum MsgUpdateOrMisbehaviour { UpdateClient(MsgUpdateClient), Misbehaviour(MsgSubmitMisbehaviour), } impl MsgUpdateOrMisbehaviour { - pub(crate) fn client_id(&self) -> &ClientId { + pub fn client_id(&self) -> &ClientId { match self { MsgUpdateOrMisbehaviour::UpdateClient(msg) => &msg.client_id, MsgUpdateOrMisbehaviour::Misbehaviour(msg) => &msg.client_id, } } - pub(crate) fn client_message(self) -> Any { + pub fn client_message(self) -> Any { match self { MsgUpdateOrMisbehaviour::UpdateClient(msg) => msg.client_message, MsgUpdateOrMisbehaviour::Misbehaviour(msg) => msg.misbehaviour, } } - pub(crate) fn signer(&self) -> &Signer { + pub fn signer(&self) -> &Signer { match self { MsgUpdateOrMisbehaviour::UpdateClient(msg) => &msg.signer, MsgUpdateOrMisbehaviour::Misbehaviour(msg) => &msg.signer, diff --git a/crates/ibc/src/core/ics02_client/msgs/update_client.rs b/crates/ibc-core/ics02-client/types/src/msgs/update_client.rs similarity index 86% rename from crates/ibc/src/core/ics02_client/msgs/update_client.rs rename to crates/ibc-core/ics02-client/types/src/msgs/update_client.rs index 9c19e77d2..60c70cfc2 100644 --- a/crates/ibc/src/core/ics02_client/msgs/update_client.rs +++ b/crates/ibc-core/ics02-client/types/src/msgs/update_client.rs @@ -1,16 +1,15 @@ //! Definition of domain type message `MsgUpdateClient`. +use ibc_core_host_types::identifiers::ClientId; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::MsgUpdateClient as RawMsgUpdateClient; use ibc_proto::Protobuf; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; +use crate::error::ClientError; -pub(crate) const TYPE_URL: &str = "/ibc.core.client.v1.MsgUpdateClient"; +pub const UPDATE_CLIENT_TYPE_URL: &str = "/ibc.core.client.v1.MsgUpdateClient"; /// Represents the message that triggers the update of an on-chain (IBC) client /// either with new headers, or evidence of misbehaviour. @@ -32,7 +31,7 @@ impl Msg for MsgUpdateClient { type Raw = RawMsgUpdateClient; fn type_url(&self) -> String { - TYPE_URL.to_string() + UPDATE_CLIENT_TYPE_URL.to_string() } } @@ -69,10 +68,9 @@ impl From for RawMsgUpdateClient { mod tests { use ibc_proto::ibc::core::client::v1::MsgUpdateClient as RawMsgUpdateClient; use ibc_testkit::utils::core::client::dummy_raw_msg_update_client; - use test_log::test; use super::*; - use crate::core::ics02_client::msgs::MsgUpdateClient; + use crate::msgs::MsgUpdateClient; #[test] fn msg_update_client_serialization() { diff --git a/crates/ibc/src/core/ics02_client/msgs/upgrade_client.rs b/crates/ibc-core/ics02-client/types/src/msgs/upgrade_client.rs similarity index 88% rename from crates/ibc/src/core/ics02_client/msgs/upgrade_client.rs rename to crates/ibc-core/ics02-client/types/src/msgs/upgrade_client.rs index baf363b38..2175a3cb4 100644 --- a/crates/ibc/src/core/ics02_client/msgs/upgrade_client.rs +++ b/crates/ibc-core/ics02-client/types/src/msgs/upgrade_client.rs @@ -2,19 +2,18 @@ use core::str::FromStr; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_commitment_types::error::CommitmentError; +use ibc_core_host_types::identifiers::ClientId; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::client::v1::MsgUpgradeClient as RawMsgUpgradeClient; use ibc_proto::Protobuf; -use crate::core::ics02_client::error::{ClientError, UpgradeClientError}; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::ics23_commitment::error::CommitmentError; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; +use crate::error::{ClientError, UpgradeClientError}; -pub(crate) const TYPE_URL: &str = "/ibc.core.client.v1.MsgUpgradeClient"; +pub const UPGRADE_CLIENT_TYPE_URL: &str = "/ibc.core.client.v1.MsgUpgradeClient"; /// A type of message that triggers the upgrade of an on-chain (IBC) client. #[cfg_attr( @@ -43,7 +42,7 @@ impl Msg for MsgUpgradeClient { type Raw = RawMsgUpgradeClient; fn type_url(&self) -> String { - TYPE_URL.to_string() + UPGRADE_CLIENT_TYPE_URL.to_string() } } @@ -102,7 +101,7 @@ mod tests { use ibc_proto::ibc::core::client::v1::MsgUpgradeClient as RawMsgUpgradeClient; use ibc_testkit::utils::core::client::dummy_raw_msg_upgrade_client; - use crate::core::ics02_client::msgs::upgrade_client::MsgUpgradeClient; + use crate::msgs::upgrade_client::MsgUpgradeClient; #[test] fn msg_upgrade_client_serialization() { diff --git a/crates/ibc-core/ics02-client/types/src/status.rs b/crates/ibc-core/ics02-client/types/src/status.rs new file mode 100644 index 000000000..b15ed61e7 --- /dev/null +++ b/crates/ibc-core/ics02-client/types/src/status.rs @@ -0,0 +1,47 @@ +use core::fmt::{Debug, Display, Formatter}; + +/// `UpdateKind` represents the 2 ways that a client can be updated +/// in IBC: either through a `MsgUpdateClient`, or a `MsgSubmitMisbehaviour`. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum UpdateKind { + /// this is the typical scenario where a new header is submitted to the client + /// to update the client. Note that light clients are free to define the type + /// of the object used to update them (e.g. could be a list of headers). + UpdateClient, + /// this is the scenario where misbehaviour is submitted to the client + /// (e.g 2 headers with the same height in Tendermint) + SubmitMisbehaviour, +} + +/// Represents the status of a client +#[derive(Debug, PartialEq, Eq)] +pub enum Status { + /// The client is active and allowed to be used + Active, + /// The client is frozen and not allowed to be used + Frozen, + /// The client is expired and not allowed to be used + Expired, + /// Unauthorized indicates that the client type is not registered as an allowed client type. + Unauthorized, +} + +impl Status { + pub fn is_active(&self) -> bool { + *self == Status::Active + } + + pub fn is_frozen(&self) -> bool { + *self == Status::Frozen + } + + pub fn is_expired(&self) -> bool { + *self == Status::Expired + } +} + +impl Display for Status { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + write!(f, "{self:?}") + } +} diff --git a/crates/ibc-core/ics03-connection/Cargo.toml b/crates/ibc-core/ics03-connection/Cargo.toml new file mode 100644 index 000000000..f77d5693b --- /dev/null +++ b/crates/ibc-core/ics03-connection/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "ibc-core-connection" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +prost = { workspace = true } + +# ibc dependencies +ibc-core-connection-types = { workspace = true } +ibc-core-client = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-context = { workspace = true } +ibc-proto = { workspace = true } + +[features] +default = ["std"] +std = [ + "ibc-core-connection-types/std", +] +serde = [ + "ibc-core-connection-types/serde", +] \ No newline at end of file diff --git a/crates/ibc/src/core/ics03_connection/delay.rs b/crates/ibc-core/ics03-connection/src/delay.rs similarity index 87% rename from crates/ibc/src/core/ics03_connection/delay.rs rename to crates/ibc-core/ics03-connection/src/delay.rs index 9b3865fac..68c49897d 100644 --- a/crates/ibc/src/core/ics03_connection/delay.rs +++ b/crates/ibc-core/ics03-connection/src/delay.rs @@ -1,8 +1,9 @@ -use super::connection::ConnectionEnd; -use super::error::ConnectionError; -use crate::core::ics02_client::height::Height; -use crate::core::ics02_client::ClientValidationContext; -use crate::core::{ContextError, ValidationContext}; +use ibc_core_client::context::ClientValidationContext; +use ibc_core_client::types::Height; +use ibc_core_connection_types::error::ConnectionError; +use ibc_core_connection_types::ConnectionEnd; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::ValidationContext; pub fn verify_conn_delay_passed( ctx: &Ctx, diff --git a/crates/ibc/src/core/ics03_connection/handler/conn_open_ack.rs b/crates/ibc-core/ics03-connection/src/handler/conn_open_ack.rs similarity index 79% rename from crates/ibc/src/core/ics03_connection/handler/conn_open_ack.rs rename to crates/ibc-core/ics03-connection/src/handler/conn_open_ack.rs index cdc137d66..b7f52f428 100644 --- a/crates/ibc/src/core/ics03_connection/handler/conn_open_ack.rs +++ b/crates/ibc-core/ics03-connection/src/handler/conn_open_ack.rs @@ -1,25 +1,22 @@ //! Protocol logic specific to processing ICS3 messages of type `MsgConnectionOpenAck`. +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection_types::error::ConnectionError; +use ibc_core_connection_types::events::OpenAck; +use ibc_core_connection_types::msgs::MsgConnectionOpenAck; +use ibc_core_connection_types::primitives::prelude::*; +use ibc_core_connection_types::{ConnectionEnd, Counterparty, State}; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::identifiers::ClientId; +use ibc_core_host_types::path::{ClientConsensusStatePath, ClientStatePath, ConnectionPath, Path}; use ibc_proto::Protobuf; use prost::Message; -use crate::core::context::ContextError; -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::{ConnectionEnd, Counterparty, State}; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics03_connection::events::OpenAck; -use crate::core::ics03_connection::msgs::conn_open_ack::MsgConnectionOpenAck; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::ics24_host::path::{ - ClientConsensusStatePath, ClientStatePath, ConnectionPath, Path, -}; -use crate::core::{ExecutionContext, ValidationContext}; -use crate::prelude::*; - -pub(crate) fn validate(ctx_a: &Ctx, msg: MsgConnectionOpenAck) -> Result<(), ContextError> +pub fn validate(ctx_a: &Ctx, msg: MsgConnectionOpenAck) -> Result<(), ContextError> where Ctx: ValidationContext, { @@ -68,8 +65,12 @@ where } client_state_of_b_on_a.validate_proof_height(msg.proofs_height_on_b)?; - let client_cons_state_path_on_a = - ClientConsensusStatePath::new(vars.client_id_on_a(), &msg.proofs_height_on_b); + let client_cons_state_path_on_a = ClientConsensusStatePath::new( + vars.client_id_on_a().clone(), + msg.proofs_height_on_b.revision_number(), + msg.proofs_height_on_b.revision_height(), + ); + let consensus_state_of_b_on_a = ctx_a.consensus_state(&client_cons_state_path_on_a)?; let prefix_on_a = ctx_a.commitment_prefix(); @@ -115,8 +116,11 @@ where let expected_consensus_state_of_a_on_b = ctx_a.host_consensus_state(&msg.consensus_height_of_a_on_b)?; - let client_cons_state_path_on_b = - ClientConsensusStatePath::new(vars.client_id_on_b(), &msg.consensus_height_of_a_on_b); + let client_cons_state_path_on_b = ClientConsensusStatePath::new( + vars.client_id_on_b().clone(), + msg.consensus_height_of_a_on_b.revision_number(), + msg.consensus_height_of_a_on_b.revision_height(), + ); client_state_of_b_on_a .verify_membership( @@ -135,7 +139,7 @@ where Ok(()) } -pub(crate) fn execute(ctx_a: &mut Ctx, msg: MsgConnectionOpenAck) -> Result<(), ContextError> +pub fn execute(ctx_a: &mut Ctx, msg: MsgConnectionOpenAck) -> Result<(), ContextError> where Ctx: ExecutionContext, { diff --git a/crates/ibc/src/core/ics03_connection/handler/conn_open_confirm.rs b/crates/ibc-core/ics03-connection/src/handler/conn_open_confirm.rs similarity index 77% rename from crates/ibc/src/core/ics03_connection/handler/conn_open_confirm.rs rename to crates/ibc-core/ics03-connection/src/handler/conn_open_confirm.rs index 83392ff6d..3ae64dda1 100644 --- a/crates/ibc/src/core/ics03_connection/handler/conn_open_confirm.rs +++ b/crates/ibc-core/ics03-connection/src/handler/conn_open_confirm.rs @@ -1,22 +1,21 @@ //! Protocol logic specific to processing ICS3 messages of type `MsgConnectionOpenConfirm`. +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection_types::error::ConnectionError; +use ibc_core_connection_types::events::OpenConfirm; +use ibc_core_connection_types::msgs::MsgConnectionOpenConfirm; +use ibc_core_connection_types::primitives::prelude::*; +use ibc_core_connection_types::{ConnectionEnd, Counterparty, State}; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::identifiers::{ClientId, ConnectionId}; +use ibc_core_host_types::path::{ClientConsensusStatePath, ConnectionPath, Path}; use ibc_proto::Protobuf; -use crate::core::context::ContextError; -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::{ConnectionEnd, Counterparty, State}; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics03_connection::events::OpenConfirm; -use crate::core::ics03_connection::msgs::conn_open_confirm::MsgConnectionOpenConfirm; -use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; -use crate::core::ics24_host::path::{ClientConsensusStatePath, ConnectionPath, Path}; -use crate::core::{ExecutionContext, ValidationContext}; -use crate::prelude::*; - -pub(crate) fn validate(ctx_b: &Ctx, msg: &MsgConnectionOpenConfirm) -> Result<(), ContextError> +pub fn validate(ctx_b: &Ctx, msg: &MsgConnectionOpenConfirm) -> Result<(), ContextError> where Ctx: ValidationContext, { @@ -55,8 +54,11 @@ where } client_state_of_a_on_b.validate_proof_height(msg.proof_height_on_a)?; - let client_cons_state_path_on_b = - ClientConsensusStatePath::new(client_id_on_b, &msg.proof_height_on_a); + let client_cons_state_path_on_b = ClientConsensusStatePath::new( + client_id_on_b.clone(), + msg.proof_height_on_a.revision_number(), + msg.proof_height_on_a.revision_height(), + ); let consensus_state_of_a_on_b = ctx_b.consensus_state(&client_cons_state_path_on_b)?; let prefix_on_a = conn_end_on_b.counterparty().prefix(); @@ -88,10 +90,7 @@ where Ok(()) } -pub(crate) fn execute( - ctx_b: &mut Ctx, - msg: &MsgConnectionOpenConfirm, -) -> Result<(), ContextError> +pub fn execute(ctx_b: &mut Ctx, msg: &MsgConnectionOpenConfirm) -> Result<(), ContextError> where Ctx: ExecutionContext, { diff --git a/crates/ibc/src/core/ics03_connection/handler/conn_open_init.rs b/crates/ibc-core/ics03-connection/src/handler/conn_open_init.rs similarity index 72% rename from crates/ibc/src/core/ics03_connection/handler/conn_open_init.rs rename to crates/ibc-core/ics03-connection/src/handler/conn_open_init.rs index f1ba3c95a..d7470c19c 100644 --- a/crates/ibc/src/core/ics03_connection/handler/conn_open_init.rs +++ b/crates/ibc-core/ics03-connection/src/handler/conn_open_init.rs @@ -1,17 +1,17 @@ //! Protocol logic specific to ICS3 messages of type `MsgConnectionOpenInit`. -use crate::core::context::ContextError; -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::ClientStateValidation; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::{ConnectionEnd, Counterparty, State}; -use crate::core::ics03_connection::events::OpenInit; -use crate::core::ics03_connection::msgs::conn_open_init::MsgConnectionOpenInit; -use crate::core::ics24_host::identifier::ConnectionId; -use crate::core::ics24_host::path::{ClientConnectionPath, ConnectionPath}; -use crate::core::{ExecutionContext, ValidationContext}; -use crate::prelude::*; +use ibc_core_client::context::client_state::ClientStateValidation; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection_types::events::OpenInit; +use ibc_core_connection_types::msgs::MsgConnectionOpenInit; +use ibc_core_connection_types::primitives::prelude::*; +use ibc_core_connection_types::{ConnectionEnd, Counterparty, State}; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::identifiers::ConnectionId; +use ibc_core_host_types::path::{ClientConnectionPath, ConnectionPath}; -pub(crate) fn validate(ctx_a: &Ctx, msg: MsgConnectionOpenInit) -> Result<(), ContextError> +pub fn validate(ctx_a: &Ctx, msg: MsgConnectionOpenInit) -> Result<(), ContextError> where Ctx: ValidationContext, { @@ -35,7 +35,7 @@ where Ok(()) } -pub(crate) fn execute(ctx_a: &mut Ctx, msg: MsgConnectionOpenInit) -> Result<(), ContextError> +pub fn execute(ctx_a: &mut Ctx, msg: MsgConnectionOpenInit) -> Result<(), ContextError> where Ctx: ExecutionContext, { diff --git a/crates/ibc/src/core/ics03_connection/handler/conn_open_try.rs b/crates/ibc-core/ics03-connection/src/handler/conn_open_try.rs similarity index 80% rename from crates/ibc/src/core/ics03_connection/handler/conn_open_try.rs rename to crates/ibc-core/ics03-connection/src/handler/conn_open_try.rs index 965cd4b0d..b4bcc7a70 100644 --- a/crates/ibc/src/core/ics03_connection/handler/conn_open_try.rs +++ b/crates/ibc-core/ics03-connection/src/handler/conn_open_try.rs @@ -1,25 +1,23 @@ -//! Protocol logic specific to processing ICS3 messages of type `MsgConnectionOpenTry`. - -use ibc_proto::Protobuf; -use prost::Message; - -use crate::core::context::ContextError; -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::{ConnectionEnd, Counterparty, State}; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics03_connection::events::OpenTry; -use crate::core::ics03_connection::msgs::conn_open_try::MsgConnectionOpenTry; -use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; -use crate::core::ics24_host::path::{ +//! Protocol logic specific to processing ICS3 messages of type `MsgConnectionOpenTry`.; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection_types::error::ConnectionError; +use ibc_core_connection_types::events::OpenTry; +use ibc_core_connection_types::msgs::MsgConnectionOpenTry; +use ibc_core_connection_types::primitives::prelude::*; +use ibc_core_connection_types::{ConnectionEnd, Counterparty, State}; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::identifiers::{ClientId, ConnectionId}; +use ibc_core_host_types::path::{ ClientConnectionPath, ClientConsensusStatePath, ClientStatePath, ConnectionPath, Path, }; -use crate::core::{ExecutionContext, ValidationContext}; -use crate::prelude::*; +use ibc_proto::Protobuf; +use prost::Message; -pub(crate) fn validate(ctx_b: &Ctx, msg: MsgConnectionOpenTry) -> Result<(), ContextError> +pub fn validate(ctx_b: &Ctx, msg: MsgConnectionOpenTry) -> Result<(), ContextError> where Ctx: ValidationContext, { @@ -66,8 +64,12 @@ where } client_state_of_a_on_b.validate_proof_height(msg.proofs_height_on_a)?; - let client_cons_state_path_on_b = - ClientConsensusStatePath::new(&msg.client_id_on_b, &msg.proofs_height_on_a); + let client_cons_state_path_on_b = ClientConsensusStatePath::new( + msg.client_id_on_b.clone(), + msg.proofs_height_on_a.revision_number(), + msg.proofs_height_on_a.revision_height(), + ); + let consensus_state_of_a_on_b = ctx_b.consensus_state(&client_cons_state_path_on_b)?; let prefix_on_a = vars.conn_end_on_b.counterparty().prefix(); @@ -109,8 +111,11 @@ where let expected_consensus_state_of_b_on_a = ctx_b.host_consensus_state(&msg.consensus_height_of_b_on_a)?; - let client_cons_state_path_on_a = - ClientConsensusStatePath::new(client_id_on_a, &msg.consensus_height_of_b_on_a); + let client_cons_state_path_on_a = ClientConsensusStatePath::new( + client_id_on_a.clone(), + msg.consensus_height_of_b_on_a.revision_number(), + msg.consensus_height_of_b_on_a.revision_height(), + ); client_state_of_a_on_b .verify_membership( @@ -129,7 +134,7 @@ where Ok(()) } -pub(crate) fn execute(ctx_b: &mut Ctx, msg: MsgConnectionOpenTry) -> Result<(), ContextError> +pub fn execute(ctx_b: &mut Ctx, msg: MsgConnectionOpenTry) -> Result<(), ContextError> where Ctx: ExecutionContext, { diff --git a/crates/ibc-core/ics03-connection/src/handler/mod.rs b/crates/ibc-core/ics03-connection/src/handler/mod.rs new file mode 100644 index 000000000..c504edc00 --- /dev/null +++ b/crates/ibc-core/ics03-connection/src/handler/mod.rs @@ -0,0 +1,4 @@ +pub mod conn_open_ack; +pub mod conn_open_confirm; +pub mod conn_open_init; +pub mod conn_open_try; diff --git a/crates/ibc-core/ics03-connection/src/lib.rs b/crates/ibc-core/ics03-connection/src/lib.rs new file mode 100644 index 000000000..82b94b96c --- /dev/null +++ b/crates/ibc-core/ics03-connection/src/lib.rs @@ -0,0 +1,9 @@ +//! This module implements the processing logic for ICS3 (connection open +//! handshake) messages. +pub mod delay; +pub mod handler; + +pub mod types { + #[doc(inline)] + pub use ibc_core_connection_types::*; +} diff --git a/crates/ibc-core/ics03-connection/types/Cargo.toml b/crates/ibc-core/ics03-connection/types/Cargo.toml new file mode 100644 index 000000000..fe2c62379 --- /dev/null +++ b/crates/ibc-core/ics03-connection/types/Cargo.toml @@ -0,0 +1,82 @@ +[package] +name = "ibc-core-connection-types" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +borsh = { workspace = true, optional = true } +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +schemars = { workspace = true, optional = true} +serde = { workspace = true, optional = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc-core-client-types = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-primitives = { workspace = true } +ibc-proto = { workspace = true } + +# cosmos dependencies +tendermint = { workspace = true } + +# parity dependencies +parity-scale-codec = { workspace = true, optional = true } +scale-info = { workspace = true, optional = true } + +[dev-dependencies] +ibc-testkit = { workspace = true } +[features] +default = ["std"] +std = [ + "displaydoc/std", + "prost/std", + "subtle-encoding/std", + "serde/std", + "ibc-core-client-types/std", + "ibc-core-commitment-types/std", + "ibc-core-host-types/std", + "ibc-primitives/std", + "ibc-proto/std", + "tendermint/std", + +] +serde = [ + "dep:serde", + "ibc-core-host-types/serde", + "ibc-core-commitment-types/serde", + "ibc-core-client-types/serde", + "ibc-proto/serde", +] +schema = [ + "dep:schemars", + "ibc-core-host-types/schema", + "ibc-core-client-types/schema", + "ibc-proto/json-schema", + "serde", + "std" +] +borsh = [ + "dep:borsh", +] +parity-scale-codec = [ + "dep:parity-scale-codec", + "dep:scale-info", + "ibc-core-client-types/parity-scale-codec", + "ibc-core-host-types/parity-scale-codec", +] \ No newline at end of file diff --git a/crates/ibc/src/core/ics03_connection/connection.rs b/crates/ibc-core/ics03-connection/types/src/connection.rs similarity index 97% rename from crates/ibc/src/core/ics03_connection/connection.rs rename to crates/ibc-core/ics03-connection/types/src/connection.rs index ae989a9a0..2af44ec5f 100644 --- a/crates/ibc/src/core/ics03_connection/connection.rs +++ b/crates/ibc-core/ics03-connection/types/src/connection.rs @@ -4,19 +4,19 @@ use core::fmt::{Display, Error as FmtError, Formatter}; use core::time::Duration; use core::u64; +use ibc_core_client_types::error::ClientError; +use ibc_core_commitment_types::commitment::CommitmentPrefix; +use ibc_core_host_types::identifiers::{ClientId, ConnectionId}; +use ibc_primitives::prelude::*; +use ibc_primitives::ZERO_DURATION; use ibc_proto::ibc::core::connection::v1::{ ConnectionEnd as RawConnectionEnd, Counterparty as RawCounterparty, IdentifiedConnection as RawIdentifiedConnection, }; use ibc_proto::Protobuf; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics03_connection::version::Version; -use crate::core::ics23_commitment::commitment::CommitmentPrefix; -use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; -use crate::core::timestamp::ZERO_DURATION; -use crate::prelude::*; +use crate::error::ConnectionError; +use crate::version::Version; #[cfg_attr( feature = "parity-scale-codec", diff --git a/crates/ibc/src/core/ics03_connection/error.rs b/crates/ibc-core/ics03-connection/types/src/error.rs similarity index 92% rename from crates/ibc/src/core/ics03_connection/error.rs rename to crates/ibc-core/ics03-connection/types/src/error.rs index db7e95dd8..b9cb0460b 100644 --- a/crates/ibc/src/core/ics03_connection/error.rs +++ b/crates/ibc-core/ics03-connection/types/src/error.rs @@ -1,14 +1,13 @@ //! Defines the connection error type -use alloc::string::String; - use displaydoc::Display; +use ibc_core_client_types::{error as client_error, Height}; +use ibc_core_host_types::error::IdentifierError; +use ibc_core_host_types::identifiers::{ClientId, ConnectionId}; +use ibc_primitives::prelude::*; +use ibc_primitives::{Timestamp, TimestampOverflowError}; -use crate::core::ics02_client::error as client_error; -use crate::core::ics03_connection::version::Version; -use crate::core::ics24_host::identifier::{ClientId, ConnectionId, IdentifierError}; -use crate::core::timestamp::{Timestamp, TimestampOverflowError}; -use crate::Height; +use crate::version::Version; #[derive(Debug, Display)] pub enum ConnectionError { diff --git a/crates/ibc/src/core/ics03_connection/events.rs b/crates/ibc-core/ics03-connection/types/src/events.rs similarity index 98% rename from crates/ibc/src/core/ics03_connection/events.rs rename to crates/ibc-core/ics03-connection/types/src/events.rs index dcc0f38f9..9bc5f0e8a 100644 --- a/crates/ibc/src/core/ics03_connection/events.rs +++ b/crates/ibc-core/ics03-connection/types/src/events.rs @@ -1,10 +1,9 @@ //! Types for the IBC events emitted from Tendermint Websocket by the connection module. +use ibc_core_host_types::identifiers::{ClientId, ConnectionId}; +use ibc_primitives::prelude::*; use tendermint::abci; -use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; -use crate::prelude::*; - /// Connection event types const CONNECTION_OPEN_INIT_EVENT: &str = "connection_open_init"; const CONNECTION_OPEN_TRY_EVENT: &str = "connection_open_try"; @@ -308,10 +307,10 @@ mod tests { use std::str::FromStr; + use ibc_core_host_types::identifiers::ClientType; use tendermint::abci::Event as AbciEvent; use super::*; - use crate::core::ics02_client::client_type::ClientType; #[test] fn ibc_to_abci_connection_events() { diff --git a/crates/ibc-core/ics03-connection/types/src/lib.rs b/crates/ibc-core/ics03-connection/types/src/lib.rs new file mode 100644 index 000000000..8ff8d0403 --- /dev/null +++ b/crates/ibc-core/ics03-connection/types/src/lib.rs @@ -0,0 +1,35 @@ +//! ICS 03: Connection implementation for connecting a client +//! on the local chain with a client on a remote chain. +#![no_std] +#![forbid(unsafe_code)] +#![cfg_attr(not(test), deny(clippy::unwrap_used))] +#![cfg_attr(not(test), deny(clippy::disallowed_methods, clippy::disallowed_types,))] +#![deny( + warnings, + trivial_numeric_casts, + unused_import_braces, + unused_qualifications, + rust_2018_idioms +)] + +#[cfg(feature = "std")] +extern crate std; + +mod connection; +pub use connection::*; + +pub mod error; +pub mod events; +pub mod msgs; +pub mod version; + +pub mod primitives { + #[doc(inline)] + pub use ibc_primitives::*; +} + +pub mod proto { + pub use ibc_proto::google::protobuf::Any; + pub use ibc_proto::ibc::core::connection::*; + pub use ibc_proto::Protobuf; +} diff --git a/crates/ibc/src/core/ics03_connection/msgs/conn_open_ack.rs b/crates/ibc-core/ics03-connection/types/src/msgs/conn_open_ack.rs similarity index 93% rename from crates/ibc/src/core/ics03_connection/msgs/conn_open_ack.rs rename to crates/ibc-core/ics03-connection/types/src/msgs/conn_open_ack.rs index cbdbbfcba..3ba244ed9 100644 --- a/crates/ibc/src/core/ics03_connection/msgs/conn_open_ack.rs +++ b/crates/ibc-core/ics03-connection/types/src/msgs/conn_open_ack.rs @@ -1,17 +1,16 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_host_types::identifiers::ConnectionId; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenAck as RawMsgConnectionOpenAck; use ibc_proto::Protobuf; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics03_connection::version::Version; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::ics24_host::identifier::ConnectionId; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::error::ConnectionError; +use crate::version::Version; -pub(crate) const TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionOpenAck"; +pub const CONN_OPEN_ACK_TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionOpenAck"; /// Per our convention, this message is sent to chain A. /// The handler will check proofs of chain B. @@ -49,7 +48,7 @@ impl Msg for MsgConnectionOpenAck { type Raw = RawMsgConnectionOpenAck; fn type_url(&self) -> String { - TYPE_URL.to_string() + CONN_OPEN_ACK_TYPE_URL.to_string() } } @@ -132,13 +131,12 @@ impl From for RawMsgConnectionOpenAck { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::client::v1::Height; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenAck as RawMsgConnectionOpenAck; use ibc_testkit::utils::core::connection::dummy_raw_msg_conn_open_ack; - use test_log::test; - use crate::core::ics03_connection::msgs::conn_open_ack::MsgConnectionOpenAck; - use crate::prelude::*; + use crate::msgs::conn_open_ack::MsgConnectionOpenAck; #[test] fn parse_connection_open_ack_msg() { diff --git a/crates/ibc/src/core/ics03_connection/msgs/conn_open_confirm.rs b/crates/ibc-core/ics03-connection/types/src/msgs/conn_open_confirm.rs similarity index 89% rename from crates/ibc/src/core/ics03_connection/msgs/conn_open_confirm.rs rename to crates/ibc-core/ics03-connection/types/src/msgs/conn_open_confirm.rs index 5a1200c78..545805c37 100644 --- a/crates/ibc/src/core/ics03_connection/msgs/conn_open_confirm.rs +++ b/crates/ibc-core/ics03-connection/types/src/msgs/conn_open_confirm.rs @@ -1,15 +1,14 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_host_types::identifiers::ConnectionId; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenConfirm as RawMsgConnectionOpenConfirm; use ibc_proto::Protobuf; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::ics24_host::identifier::ConnectionId; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::error::ConnectionError; -pub(crate) const TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionOpenConfirm"; +pub const CONN_OPEN_CONFIRM_TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionOpenConfirm"; /// Per our convention, this message is sent to chain B. /// The handler will check proofs of chain A. @@ -33,7 +32,7 @@ impl Msg for MsgConnectionOpenConfirm { type Raw = RawMsgConnectionOpenConfirm; fn type_url(&self) -> String { - TYPE_URL.to_string() + CONN_OPEN_CONFIRM_TYPE_URL.to_string() } } @@ -74,13 +73,12 @@ impl From for RawMsgConnectionOpenConfirm { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::client::v1::Height; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenConfirm as RawMsgConnectionOpenConfirm; use ibc_testkit::utils::core::connection::dummy_raw_msg_conn_open_confirm; - use test_log::test; - use crate::core::ics03_connection::msgs::conn_open_confirm::MsgConnectionOpenConfirm; - use crate::prelude::*; + use crate::msgs::conn_open_confirm::MsgConnectionOpenConfirm; #[test] fn parse_connection_open_confirm_msg() { diff --git a/crates/ibc/src/core/ics03_connection/msgs/conn_open_init.rs b/crates/ibc-core/ics03-connection/types/src/msgs/conn_open_init.rs similarity index 94% rename from crates/ibc/src/core/ics03_connection/msgs/conn_open_init.rs rename to crates/ibc-core/ics03-connection/types/src/msgs/conn_open_init.rs index d0fd2572a..1638fc8ae 100644 --- a/crates/ibc/src/core/ics03_connection/msgs/conn_open_init.rs +++ b/crates/ibc-core/ics03-connection/types/src/msgs/conn_open_init.rs @@ -1,17 +1,16 @@ use core::time::Duration; +use ibc_core_host_types::identifiers::ClientId; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenInit as RawMsgConnectionOpenInit; use ibc_proto::Protobuf; -use crate::core::ics03_connection::connection::Counterparty; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics03_connection::version::Version; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; +use crate::connection::Counterparty; +use crate::error::ConnectionError; +use crate::version::Version; -pub(crate) const TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionOpenInit"; +pub const CONN_OPEN_INIT_TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionOpenInit"; /// Per our convention, this message is sent to chain A. /// The handler will check proofs of chain B. @@ -30,7 +29,7 @@ impl Msg for MsgConnectionOpenInit { type Raw = RawMsgConnectionOpenInit; fn type_url(&self) -> String { - TYPE_URL.to_string() + CONN_OPEN_INIT_TYPE_URL.to_string() } } @@ -130,16 +129,15 @@ impl From for RawMsgConnectionOpenInit { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::connection::v1::{ Counterparty as RawCounterparty, MsgConnectionOpenInit as RawMsgConnectionOpenInit, }; use ibc_testkit::utils::core::connection::{ dummy_raw_counterparty_conn, dummy_raw_msg_conn_open_init, }; - use test_log::test; use super::MsgConnectionOpenInit; - use crate::prelude::*; #[test] fn parse_connection_open_init_msg() { diff --git a/crates/ibc/src/core/ics03_connection/msgs/conn_open_try.rs b/crates/ibc-core/ics03-connection/types/src/msgs/conn_open_try.rs similarity index 96% rename from crates/ibc/src/core/ics03_connection/msgs/conn_open_try.rs rename to crates/ibc-core/ics03-connection/types/src/msgs/conn_open_try.rs index ab778f2e3..4999f54c4 100644 --- a/crates/ibc/src/core/ics03_connection/msgs/conn_open_try.rs +++ b/crates/ibc-core/ics03-connection/types/src/msgs/conn_open_try.rs @@ -1,21 +1,20 @@ use core::convert::{TryFrom, TryInto}; use core::time::Duration; +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_host_types::identifiers::ClientId; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::google::protobuf::Any; use ibc_proto::ibc::core::connection::v1::MsgConnectionOpenTry as RawMsgConnectionOpenTry; use ibc_proto::Protobuf; -use crate::core::ics03_connection::connection::Counterparty; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics03_connection::version::Version; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::ics24_host::identifier::ClientId; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::connection::Counterparty; +use crate::error::ConnectionError; +use crate::version::Version; -pub(crate) const TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionOpenTry"; +pub const CONN_OPEN_TRY_TYPE_URL: &str = "/ibc.core.connection.v1.MsgConnectionOpenTry"; /// Per our convention, this message is sent to chain B. /// The handler will check proofs of chain A. @@ -55,7 +54,7 @@ impl Msg for MsgConnectionOpenTry { type Raw = RawMsgConnectionOpenTry; fn type_url(&self) -> String { - TYPE_URL.to_string() + CONN_OPEN_TRY_TYPE_URL.to_string() } } #[allow(deprecated)] @@ -244,6 +243,7 @@ impl From for RawMsgConnectionOpenTry { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::client::v1::Height; use ibc_proto::ibc::core::connection::v1::{ Counterparty as RawCounterparty, MsgConnectionOpenTry as RawMsgConnectionOpenTry, @@ -251,10 +251,8 @@ mod tests { use ibc_testkit::utils::core::connection::{ dummy_raw_counterparty_conn, dummy_raw_msg_conn_open_try, }; - use test_log::test; - use crate::core::ics03_connection::msgs::conn_open_try::MsgConnectionOpenTry; - use crate::prelude::*; + use crate::msgs::conn_open_try::MsgConnectionOpenTry; #[test] fn parse_connection_open_try_msg() { diff --git a/crates/ibc/src/core/ics03_connection/msgs.rs b/crates/ibc-core/ics03-connection/types/src/msgs/mod.rs similarity index 75% rename from crates/ibc/src/core/ics03_connection/msgs.rs rename to crates/ibc-core/ics03-connection/types/src/msgs/mod.rs index f80617d82..406001e36 100644 --- a/crates/ibc/src/core/ics03_connection/msgs.rs +++ b/crates/ibc-core/ics03-connection/types/src/msgs/mod.rs @@ -12,16 +12,17 @@ //! Another difference to ICS3 specs is that each message comprises an additional field called //! `signer` which is specific to Cosmos-SDK. -use crate::core::ics03_connection::msgs::conn_open_ack::MsgConnectionOpenAck; -use crate::core::ics03_connection::msgs::conn_open_confirm::MsgConnectionOpenConfirm; -use crate::core::ics03_connection::msgs::conn_open_init::MsgConnectionOpenInit; -use crate::core::ics03_connection::msgs::conn_open_try::MsgConnectionOpenTry; -use crate::prelude::*; +use ibc_primitives::prelude::*; -pub mod conn_open_ack; -pub mod conn_open_confirm; -pub mod conn_open_init; -pub mod conn_open_try; +mod conn_open_ack; +mod conn_open_confirm; +mod conn_open_init; +mod conn_open_try; + +pub use conn_open_ack::*; +pub use conn_open_confirm::*; +pub use conn_open_init::*; +pub use conn_open_try::*; /// Enumeration of all possible messages that the ICS3 protocol processes. #[cfg_attr( diff --git a/crates/ibc/src/core/ics03_connection/version.rs b/crates/ibc-core/ics03-connection/types/src/version.rs similarity index 95% rename from crates/ibc/src/core/ics03_connection/version.rs rename to crates/ibc-core/ics03-connection/types/src/version.rs index 2052bb12c..46029c68c 100644 --- a/crates/ibc/src/core/ics03_connection/version.rs +++ b/crates/ibc-core/ics03-connection/types/src/version.rs @@ -2,13 +2,12 @@ use core::fmt::Display; +use ibc_primitives::prelude::*; +use ibc_primitives::utils::PrettySlice; use ibc_proto::ibc::core::connection::v1::Version as RawVersion; use ibc_proto::Protobuf; -use crate::core::ics03_connection::error::ConnectionError; -use crate::core::ics04_channel::channel::Order; -use crate::prelude::*; -use crate::utils::pretty::PrettySlice; +use crate::error::ConnectionError; /// Stores the identifier and the features supported by a version #[cfg_attr( @@ -94,10 +93,7 @@ impl Default for Version { fn default() -> Self { Version { identifier: "1".to_string(), - features: vec![ - Order::Ordered.as_str().to_owned(), - Order::Unordered.as_str().to_owned(), - ], + features: vec!["ORDER_ORDERED".to_string(), "ORDER_UNORDERED".to_string()], } } } @@ -189,12 +185,11 @@ fn get_feature_set_intersection( #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::connection::v1::Version as RawVersion; - use test_log::test; - use crate::core::ics03_connection::error::ConnectionError; - use crate::core::ics03_connection::version::{get_compatible_versions, pick_version, Version}; - use crate::prelude::*; + use crate::error::ConnectionError; + use crate::version::{get_compatible_versions, pick_version, Version}; fn get_dummy_features() -> Vec { vec!["ORDER_RANDOM".to_string(), "ORDER_UNORDERED".to_string()] diff --git a/crates/ibc-core/ics04-channel/Cargo.toml b/crates/ibc-core/ics04-channel/Cargo.toml new file mode 100644 index 000000000..a2dfc3175 --- /dev/null +++ b/crates/ibc-core/ics04-channel/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "ibc-core-channel" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +prost = { workspace = true } + +# ibc dependencies +ibc-core-client = { workspace = true } +ibc-core-connection = { workspace = true } +ibc-core-channel-types = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-context = { workspace = true } +ibc-core-router = { workspace = true } + +[features] +default = ["std"] +std = [ + "ibc-core-client/std", + "ibc-core-connection/std", + "ibc-core-channel-types/std", + "ibc-core-commitment-types/std", + "ibc-core-host-types/std", + "ibc-core-context/std", + "ibc-core-router/std", +] +serde = [ + "ibc-core-client/serde", + "ibc-core-connection/serde", + "ibc-core-channel-types/serde", + "ibc-core-commitment-types/serde", + "ibc-core-host-types/serde", + "ibc-core-context/serde", + "ibc-core-router/serde", +] \ No newline at end of file diff --git a/crates/ibc/src/core/ics04_channel/context.rs b/crates/ibc-core/ics04-channel/src/context.rs similarity index 67% rename from crates/ibc/src/core/ics04_channel/context.rs rename to crates/ibc-core/ics04-channel/src/context.rs index 40c51d3fc..6e77c0181 100644 --- a/crates/ibc/src/core/ics04_channel/context.rs +++ b/crates/ibc-core/ics04-channel/src/context.rs @@ -1,21 +1,18 @@ //! ICS4 (channel) context. -use core::time::Duration; - -use super::packet::Sequence; -use crate::core::events::IbcEvent; -use crate::core::ics02_client::client_state::ClientState; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::{ClientExecutionContext, ClientValidationContext}; -use crate::core::ics03_connection::connection::ConnectionEnd; -use crate::core::ics04_channel::channel::ChannelEnd; -use crate::core::ics04_channel::commitment::PacketCommitment; -use crate::core::ics24_host::identifier::{ClientId, ConnectionId}; -use crate::core::ics24_host::path::{ +use ibc_core_channel_types::channel::ChannelEnd; +use ibc_core_channel_types::commitment::PacketCommitment; +use ibc_core_client::context::client_state::ClientState; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::context::{ClientExecutionContext, ClientValidationContext}; +use ibc_core_connection::types::ConnectionEnd; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::IbcEvent; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::identifiers::{ClientId, ConnectionId, Sequence}; +use ibc_core_host_types::path::{ ChannelEndPath, ClientConsensusStatePath, CommitmentPath, SeqSendPath, }; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; /// Methods required in send packet validation, to be implemented by the host pub trait SendPacketValidationContext { @@ -135,47 +132,3 @@ where self.log_message(message) } } - -pub(crate) fn calculate_block_delay( - delay_period_time: &Duration, - max_expected_time_per_block: &Duration, -) -> u64 { - let delay_period_time = delay_period_time.as_secs(); - let max_expected_time_per_block = max_expected_time_per_block.as_secs(); - if max_expected_time_per_block == 0 { - return 0; - } - if delay_period_time % max_expected_time_per_block == 0 { - return delay_period_time / max_expected_time_per_block; - } - (delay_period_time / max_expected_time_per_block) + 1 -} - -#[cfg(test)] -mod tests { - - use rstest::rstest; - - use super::*; - - #[rstest] - #[case::remainder_zero(10, 2, 5)] - #[case::remainder_not_zero(10, 3, 4)] - #[case::max_expected_zero(10, 0, 0)] - #[case::delay_period_zero(0, 2, 0)] - #[case::both_zero(0, 0, 0)] - #[case::delay_less_than_max(10, 11, 1)] - fn test_calculate_block_delay_zero( - #[case] delay_period_time: u64, - #[case] max_expected_time_per_block: u64, - #[case] expected: u64, - ) { - assert_eq!( - calculate_block_delay( - &Duration::from_secs(delay_period_time), - &Duration::from_secs(max_expected_time_per_block) - ), - expected - ); - } -} diff --git a/crates/ibc/src/core/ics04_channel/handler/acknowledgement.rs b/crates/ibc-core/ics04-channel/src/handler/acknowledgement.rs similarity index 84% rename from crates/ibc/src/core/ics04_channel/handler/acknowledgement.rs rename to crates/ibc-core/ics04-channel/src/handler/acknowledgement.rs index 4680e86d2..6567fb4ad 100644 --- a/crates/ibc/src/core/ics04_channel/handler/acknowledgement.rs +++ b/crates/ibc-core/ics04-channel/src/handler/acknowledgement.rs @@ -1,22 +1,23 @@ -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::State as ConnectionState; -use crate::core::ics03_connection::delay::verify_conn_delay_passed; -use crate::core::ics04_channel::channel::{Counterparty, Order, State as ChannelState}; -use crate::core::ics04_channel::commitment::{compute_ack_commitment, compute_packet_commitment}; -use crate::core::ics04_channel::error::{ChannelError, PacketError}; -use crate::core::ics04_channel::events::AcknowledgePacket; -use crate::core::ics04_channel::msgs::acknowledgement::MsgAcknowledgement; -use crate::core::ics24_host::path::{ +use ibc_core_channel_types::channel::{Counterparty, Order, State as ChannelState}; +use ibc_core_channel_types::commitment::{compute_ack_commitment, compute_packet_commitment}; +use ibc_core_channel_types::error::{ChannelError, PacketError}; +use ibc_core_channel_types::events::AcknowledgePacket; +use ibc_core_channel_types::msgs::MsgAcknowledgement; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection::delay::verify_conn_delay_passed; +use ibc_core_connection::types::State as ConnectionState; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::path::{ AckPath, ChannelEndPath, ClientConsensusStatePath, CommitmentPath, Path, SeqAckPath, }; -use crate::core::router::Module; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; +use ibc_core_router::module::Module; -pub(crate) fn acknowledgement_packet_validate( +pub fn acknowledgement_packet_validate( ctx_a: &ValCtx, module: &dyn Module, msg: MsgAcknowledgement, @@ -31,7 +32,7 @@ where .map_err(ContextError::PacketError) } -pub(crate) fn acknowledgement_packet_execute( +pub fn acknowledgement_packet_execute( ctx_a: &mut ExecCtx, module: &mut dyn Module, msg: MsgAcknowledgement, @@ -186,8 +187,11 @@ where } client_state_of_b_on_a.validate_proof_height(msg.proof_height_on_b)?; - let client_cons_state_path_on_a = - ClientConsensusStatePath::new(client_id_on_a, &msg.proof_height_on_b); + let client_cons_state_path_on_a = ClientConsensusStatePath::new( + client_id_on_a.clone(), + msg.proof_height_on_b.revision_number(), + msg.proof_height_on_b.revision_height(), + ); let consensus_state_of_b_on_a = ctx_a.consensus_state(&client_cons_state_path_on_a)?; let ack_commitment = compute_ack_commitment(&msg.acknowledgement); let ack_path_on_b = diff --git a/crates/ibc/src/core/ics04_channel/handler/chan_close_confirm.rs b/crates/ibc-core/ics04-channel/src/handler/chan_close_confirm.rs similarity index 80% rename from crates/ibc/src/core/ics04_channel/handler/chan_close_confirm.rs rename to crates/ibc-core/ics04-channel/src/handler/chan_close_confirm.rs index 28ce154d9..6814608cd 100644 --- a/crates/ibc/src/core/ics04_channel/handler/chan_close_confirm.rs +++ b/crates/ibc-core/ics04-channel/src/handler/chan_close_confirm.rs @@ -1,22 +1,22 @@ //! Protocol logic specific to ICS4 messages of type `MsgChannelCloseConfirm`. -use ibc_proto::Protobuf; - -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::State as ConnectionState; -use crate::core::ics04_channel::channel::{ChannelEnd, Counterparty, State, State as ChannelState}; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::events::CloseConfirm; -use crate::core::ics04_channel::msgs::chan_close_confirm::MsgChannelCloseConfirm; -use crate::core::ics24_host::path::{ChannelEndPath, ClientConsensusStatePath, Path}; -use crate::core::router::Module; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; - -pub(crate) fn chan_close_confirm_validate( +use ibc_core_channel_types::channel::{ChannelEnd, Counterparty, State, State as ChannelState}; +use ibc_core_channel_types::error::ChannelError; +use ibc_core_channel_types::events::CloseConfirm; +use ibc_core_channel_types::msgs::MsgChannelCloseConfirm; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_channel_types::proto::Protobuf; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection::types::State as ConnectionState; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::path::{ChannelEndPath, ClientConsensusStatePath, Path}; +use ibc_core_router::module::Module; + +pub fn chan_close_confirm_validate( ctx_b: &ValCtx, module: &dyn Module, msg: MsgChannelCloseConfirm, @@ -31,7 +31,7 @@ where Ok(()) } -pub(crate) fn chan_close_confirm_execute( +pub fn chan_close_confirm_execute( ctx_b: &mut ExecCtx, module: &mut dyn Module, msg: MsgChannelCloseConfirm, @@ -124,8 +124,11 @@ where } client_state_of_a_on_b.validate_proof_height(msg.proof_height_on_a)?; - let client_cons_state_path_on_b = - ClientConsensusStatePath::new(client_id_on_b, &msg.proof_height_on_a); + let client_cons_state_path_on_b = ClientConsensusStatePath::new( + client_id_on_b.clone(), + msg.proof_height_on_a.revision_number(), + msg.proof_height_on_a.revision_height(), + ); let consensus_state_of_a_on_b = ctx_b.consensus_state(&client_cons_state_path_on_b)?; let prefix_on_a = conn_end_on_b.counterparty().prefix(); let port_id_on_a = &chan_end_on_b.counterparty().port_id; diff --git a/crates/ibc/src/core/ics04_channel/handler/chan_close_init.rs b/crates/ibc-core/ics04-channel/src/handler/chan_close_init.rs similarity index 81% rename from crates/ibc/src/core/ics04_channel/handler/chan_close_init.rs rename to crates/ibc-core/ics04-channel/src/handler/chan_close_init.rs index b5856e9f6..79d9a78da 100644 --- a/crates/ibc/src/core/ics04_channel/handler/chan_close_init.rs +++ b/crates/ibc-core/ics04-channel/src/handler/chan_close_init.rs @@ -1,18 +1,19 @@ //! Protocol logic specific to ICS4 messages of type `MsgChannelCloseInit`. -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::ClientStateValidation; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::State as ConnectionState; -use crate::core::ics04_channel::channel::State; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::events::CloseInit; -use crate::core::ics04_channel::msgs::chan_close_init::MsgChannelCloseInit; -use crate::core::ics24_host::path::ChannelEndPath; -use crate::core::router::Module; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; - -pub(crate) fn chan_close_init_validate( +use ibc_core_channel_types::channel::State; +use ibc_core_channel_types::error::ChannelError; +use ibc_core_channel_types::events::CloseInit; +use ibc_core_channel_types::msgs::MsgChannelCloseInit; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_client::context::client_state::ClientStateValidation; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection::types::State as ConnectionState; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::path::ChannelEndPath; +use ibc_core_router::module::Module; + +pub fn chan_close_init_validate( ctx_a: &ValCtx, module: &dyn Module, msg: MsgChannelCloseInit, @@ -27,7 +28,7 @@ where Ok(()) } -pub(crate) fn chan_close_init_execute( +pub fn chan_close_init_execute( ctx_a: &mut ExecCtx, module: &mut dyn Module, msg: MsgChannelCloseInit, diff --git a/crates/ibc/src/core/ics04_channel/handler/chan_open_ack.rs b/crates/ibc-core/ics04-channel/src/handler/chan_open_ack.rs similarity index 80% rename from crates/ibc/src/core/ics04_channel/handler/chan_open_ack.rs rename to crates/ibc-core/ics04-channel/src/handler/chan_open_ack.rs index 4267437d2..a6b18705f 100644 --- a/crates/ibc/src/core/ics04_channel/handler/chan_open_ack.rs +++ b/crates/ibc-core/ics04-channel/src/handler/chan_open_ack.rs @@ -1,22 +1,21 @@ //! Protocol logic specific to ICS4 messages of type `MsgChannelOpenAck`. - -use ibc_proto::Protobuf; - -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::State as ConnectionState; -use crate::core::ics04_channel::channel::{ChannelEnd, Counterparty, State, State as ChannelState}; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::events::OpenAck; -use crate::core::ics04_channel::msgs::chan_open_ack::MsgChannelOpenAck; -use crate::core::ics24_host::path::{ChannelEndPath, ClientConsensusStatePath, Path}; -use crate::core::router::Module; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; - -pub(crate) fn chan_open_ack_validate( +use ibc_core_channel_types::channel::{ChannelEnd, Counterparty, State, State as ChannelState}; +use ibc_core_channel_types::error::ChannelError; +use ibc_core_channel_types::events::OpenAck; +use ibc_core_channel_types::msgs::MsgChannelOpenAck; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_channel_types::proto::Protobuf; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection::types::State as ConnectionState; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::path::{ChannelEndPath, ClientConsensusStatePath, Path}; +use ibc_core_router::module::Module; + +pub fn chan_open_ack_validate( ctx_a: &ValCtx, module: &dyn Module, msg: MsgChannelOpenAck, @@ -31,7 +30,7 @@ where Ok(()) } -pub(crate) fn chan_open_ack_execute( +pub fn chan_open_ack_execute( ctx_a: &mut ExecCtx, module: &mut dyn Module, msg: MsgChannelOpenAck, @@ -122,8 +121,11 @@ where } client_state_of_b_on_a.validate_proof_height(msg.proof_height_on_b)?; - let client_cons_state_path_on_a = - ClientConsensusStatePath::new(client_id_on_a, &msg.proof_height_on_b); + let client_cons_state_path_on_a = ClientConsensusStatePath::new( + client_id_on_a.clone(), + msg.proof_height_on_b.revision_number(), + msg.proof_height_on_b.revision_height(), + ); let consensus_state_of_b_on_a = ctx_a.consensus_state(&client_cons_state_path_on_a)?; let prefix_on_b = conn_end_on_a.counterparty().prefix(); let port_id_on_b = &chan_end_on_a.counterparty().port_id; diff --git a/crates/ibc/src/core/ics04_channel/handler/chan_open_confirm.rs b/crates/ibc-core/ics04-channel/src/handler/chan_open_confirm.rs similarity index 80% rename from crates/ibc/src/core/ics04_channel/handler/chan_open_confirm.rs rename to crates/ibc-core/ics04-channel/src/handler/chan_open_confirm.rs index 7e5ecf93b..cbd5bb665 100644 --- a/crates/ibc/src/core/ics04_channel/handler/chan_open_confirm.rs +++ b/crates/ibc-core/ics04-channel/src/handler/chan_open_confirm.rs @@ -1,22 +1,22 @@ //! Protocol logic specific to ICS4 messages of type `MsgChannelOpenConfirm`. -use ibc_proto::Protobuf; - -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::State as ConnectionState; -use crate::core::ics04_channel::channel::{ChannelEnd, Counterparty, State, State as ChannelState}; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::events::OpenConfirm; -use crate::core::ics04_channel::msgs::chan_open_confirm::MsgChannelOpenConfirm; -use crate::core::ics24_host::path::{ChannelEndPath, ClientConsensusStatePath, Path}; -use crate::core::router::Module; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; - -pub(crate) fn chan_open_confirm_validate( +use ibc_core_channel_types::channel::{ChannelEnd, Counterparty, State, State as ChannelState}; +use ibc_core_channel_types::error::ChannelError; +use ibc_core_channel_types::events::OpenConfirm; +use ibc_core_channel_types::msgs::MsgChannelOpenConfirm; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_channel_types::proto::Protobuf; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection::types::State as ConnectionState; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::path::{ChannelEndPath, ClientConsensusStatePath, Path}; +use ibc_core_router::module::Module; + +pub fn chan_open_confirm_validate( ctx_b: &ValCtx, module: &dyn Module, msg: MsgChannelOpenConfirm, @@ -31,7 +31,7 @@ where Ok(()) } -pub(crate) fn chan_open_confirm_execute( +pub fn chan_open_confirm_execute( ctx_b: &mut ExecCtx, module: &mut dyn Module, msg: MsgChannelOpenConfirm, @@ -126,8 +126,11 @@ where } client_state_of_a_on_b.validate_proof_height(msg.proof_height_on_a)?; - let client_cons_state_path_on_b = - ClientConsensusStatePath::new(client_id_on_b, &msg.proof_height_on_a); + let client_cons_state_path_on_b = ClientConsensusStatePath::new( + client_id_on_b.clone(), + msg.proof_height_on_a.revision_number(), + msg.proof_height_on_a.revision_height(), + ); let consensus_state_of_a_on_b = ctx_b.consensus_state(&client_cons_state_path_on_b)?; let prefix_on_a = conn_end_on_b.counterparty().prefix(); let port_id_on_a = &chan_end_on_b.counterparty().port_id; diff --git a/crates/ibc/src/core/ics04_channel/handler/chan_open_init.rs b/crates/ibc-core/ics04-channel/src/handler/chan_open_init.rs similarity index 83% rename from crates/ibc/src/core/ics04_channel/handler/chan_open_init.rs rename to crates/ibc-core/ics04-channel/src/handler/chan_open_init.rs index 17dc77df3..7ffd58e50 100644 --- a/crates/ibc/src/core/ics04_channel/handler/chan_open_init.rs +++ b/crates/ibc-core/ics04-channel/src/handler/chan_open_init.rs @@ -1,18 +1,19 @@ //! Protocol logic specific to ICS4 messages of type `MsgChannelOpenInit`. -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::ClientStateValidation; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics04_channel::channel::{ChannelEnd, Counterparty, State}; -use crate::core::ics04_channel::events::OpenInit; -use crate::core::ics04_channel::msgs::chan_open_init::MsgChannelOpenInit; -use crate::core::ics24_host::identifier::ChannelId; -use crate::core::ics24_host::path::{ChannelEndPath, SeqAckPath, SeqRecvPath, SeqSendPath}; -use crate::core::router::Module; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; - -pub(crate) fn chan_open_init_validate( +use ibc_core_channel_types::channel::{ChannelEnd, Counterparty, State}; +use ibc_core_channel_types::events::OpenInit; +use ibc_core_channel_types::msgs::MsgChannelOpenInit; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_client::context::client_state::ClientStateValidation; +use ibc_core_client::types::error::ClientError; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::identifiers::ChannelId; +use ibc_core_host_types::path::{ChannelEndPath, SeqAckPath, SeqRecvPath, SeqSendPath}; +use ibc_core_router::module::Module; + +pub fn chan_open_init_validate( ctx_a: &ValCtx, module: &dyn Module, msg: MsgChannelOpenInit, @@ -35,7 +36,7 @@ where Ok(()) } -pub(crate) fn chan_open_init_execute( +pub fn chan_open_init_execute( ctx_a: &mut ExecCtx, module: &mut dyn Module, msg: MsgChannelOpenInit, diff --git a/crates/ibc/src/core/ics04_channel/handler/chan_open_try.rs b/crates/ibc-core/ics04-channel/src/handler/chan_open_try.rs similarity index 81% rename from crates/ibc/src/core/ics04_channel/handler/chan_open_try.rs rename to crates/ibc-core/ics04-channel/src/handler/chan_open_try.rs index ff27b0eff..0596158fe 100644 --- a/crates/ibc/src/core/ics04_channel/handler/chan_open_try.rs +++ b/crates/ibc-core/ics04-channel/src/handler/chan_open_try.rs @@ -1,25 +1,25 @@ //! Protocol logic specific to ICS4 messages of type `MsgChannelOpenTry`. -use ibc_proto::Protobuf; - -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::State as ConnectionState; -use crate::core::ics04_channel::channel::{ChannelEnd, Counterparty, State, State as ChannelState}; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::events::OpenTry; -use crate::core::ics04_channel::msgs::chan_open_try::MsgChannelOpenTry; -use crate::core::ics24_host::identifier::ChannelId; -use crate::core::ics24_host::path::{ +use ibc_core_channel_types::channel::{ChannelEnd, Counterparty, State as ChannelState}; +use ibc_core_channel_types::error::ChannelError; +use ibc_core_channel_types::events::OpenTry; +use ibc_core_channel_types::msgs::MsgChannelOpenTry; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_channel_types::proto::Protobuf; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection::types::State as ConnectionState; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::identifiers::ChannelId; +use ibc_core_host_types::path::{ ChannelEndPath, ClientConsensusStatePath, Path, SeqAckPath, SeqRecvPath, SeqSendPath, }; -use crate::core::router::Module; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; +use ibc_core_router::module::Module; -pub(crate) fn chan_open_try_validate( +pub fn chan_open_try_validate( ctx_b: &ValCtx, module: &dyn Module, msg: MsgChannelOpenTry, @@ -43,7 +43,7 @@ where Ok(()) } -pub(crate) fn chan_open_try_execute( +pub fn chan_open_try_execute( ctx_b: &mut ExecCtx, module: &mut dyn Module, msg: MsgChannelOpenTry, @@ -66,7 +66,7 @@ where // state changes { let chan_end_on_b = ChannelEnd::new( - State::TryOpen, + ChannelState::TryOpen, msg.ordering, Counterparty::new(msg.port_id_on_a.clone(), Some(msg.chan_id_on_a.clone())), msg.connection_hops_on_b.clone(), @@ -147,8 +147,11 @@ where } client_state_of_a_on_b.validate_proof_height(msg.proof_height_on_a)?; - let client_cons_state_path_on_b = - ClientConsensusStatePath::new(client_id_on_b, &msg.proof_height_on_a); + let client_cons_state_path_on_b = ClientConsensusStatePath::new( + client_id_on_b.clone(), + msg.proof_height_on_a.revision_number(), + msg.proof_height_on_a.revision_height(), + ); let consensus_state_of_a_on_b = ctx_b.consensus_state(&client_cons_state_path_on_b)?; let prefix_on_a = conn_end_on_b.counterparty().prefix(); let port_id_on_a = msg.port_id_on_a.clone(); diff --git a/crates/ibc-core/ics04-channel/src/handler/mod.rs b/crates/ibc-core/ics04-channel/src/handler/mod.rs new file mode 100644 index 000000000..b1ea237a1 --- /dev/null +++ b/crates/ibc-core/ics04-channel/src/handler/mod.rs @@ -0,0 +1,24 @@ +//! This module implements the processing logic for ICS4 (channel) messages. +mod acknowledgement; +mod chan_close_confirm; +mod chan_close_init; +mod chan_open_ack; +mod chan_open_confirm; +mod chan_open_init; +mod chan_open_try; +mod recv_packet; +mod send_packet; +mod timeout; +mod timeout_on_close; + +pub use acknowledgement::*; +pub use chan_close_confirm::*; +pub use chan_close_init::*; +pub use chan_open_ack::*; +pub use chan_open_confirm::*; +pub use chan_open_init::*; +pub use chan_open_try::*; +pub use recv_packet::*; +pub use send_packet::*; +pub use timeout::*; +pub use timeout_on_close::*; diff --git a/crates/ibc/src/core/ics04_channel/handler/recv_packet.rs b/crates/ibc-core/ics04-channel/src/handler/recv_packet.rs similarity index 86% rename from crates/ibc/src/core/ics04_channel/handler/recv_packet.rs rename to crates/ibc-core/ics04-channel/src/handler/recv_packet.rs index f99d184a1..a8198ac18 100644 --- a/crates/ibc/src/core/ics04_channel/handler/recv_packet.rs +++ b/crates/ibc-core/ics04-channel/src/handler/recv_packet.rs @@ -1,28 +1,26 @@ -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::connection::State as ConnectionState; -use crate::core::ics03_connection::delay::verify_conn_delay_passed; -use crate::core::ics04_channel::channel::{Counterparty, Order, State as ChannelState}; -use crate::core::ics04_channel::commitment::{compute_ack_commitment, compute_packet_commitment}; -use crate::core::ics04_channel::error::{ChannelError, PacketError}; -use crate::core::ics04_channel::events::{ReceivePacket, WriteAcknowledgement}; -use crate::core::ics04_channel::msgs::recv_packet::MsgRecvPacket; -use crate::core::ics04_channel::packet::Receipt; -use crate::core::ics24_host::path::{ +use ibc_core_channel_types::channel::{Counterparty, Order, State as ChannelState}; +use ibc_core_channel_types::commitment::{compute_ack_commitment, compute_packet_commitment}; +use ibc_core_channel_types::error::{ChannelError, PacketError}; +use ibc_core_channel_types::events::{ReceivePacket, WriteAcknowledgement}; +use ibc_core_channel_types::msgs::MsgRecvPacket; +use ibc_core_channel_types::packet::Receipt; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_channel_types::primitives::Expiry; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection::delay::verify_conn_delay_passed; +use ibc_core_connection::types::State as ConnectionState; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::path::{ AckPath, ChannelEndPath, ClientConsensusStatePath, CommitmentPath, Path, ReceiptPath, SeqRecvPath, }; -use crate::core::router::Module; -use crate::core::timestamp::Expiry; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; +use ibc_core_router::module::Module; -pub(crate) fn recv_packet_validate( - ctx_b: &ValCtx, - msg: MsgRecvPacket, -) -> Result<(), ContextError> +pub fn recv_packet_validate(ctx_b: &ValCtx, msg: MsgRecvPacket) -> Result<(), ContextError> where ValCtx: ValidationContext, { @@ -33,7 +31,7 @@ where // If any error occurs, then an "error acknowledgement" must be returned. } -pub(crate) fn recv_packet_execute( +pub fn recv_packet_execute( ctx_b: &mut ExecCtx, module: &mut dyn Module, msg: MsgRecvPacket, @@ -193,8 +191,12 @@ where } client_state_of_a_on_b.validate_proof_height(msg.proof_height_on_a)?; - let client_cons_state_path_on_b = - ClientConsensusStatePath::new(client_id_on_b, &msg.proof_height_on_a); + let client_cons_state_path_on_b = ClientConsensusStatePath::new( + client_id_on_b.clone(), + msg.proof_height_on_a.revision_number(), + msg.proof_height_on_a.revision_height(), + ); + let consensus_state_of_a_on_b = ctx_b.consensus_state(&client_cons_state_path_on_b)?; let expected_commitment_on_a = compute_packet_commitment( diff --git a/crates/ibc/src/core/ics04_channel/handler/send_packet.rs b/crates/ibc-core/ics04-channel/src/handler/send_packet.rs similarity index 81% rename from crates/ibc/src/core/ics04_channel/handler/send_packet.rs rename to crates/ibc-core/ics04-channel/src/handler/send_packet.rs index 4a9134f57..2b864f66e 100644 --- a/crates/ibc/src/core/ics04_channel/handler/send_packet.rs +++ b/crates/ibc-core/ics04-channel/src/handler/send_packet.rs @@ -1,21 +1,20 @@ -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics04_channel::channel::Counterparty; -use crate::core::ics04_channel::commitment::compute_packet_commitment; -use crate::core::ics04_channel::context::{ - SendPacketExecutionContext, SendPacketValidationContext, -}; -use crate::core::ics04_channel::error::PacketError; -use crate::core::ics04_channel::events::SendPacket; -use crate::core::ics04_channel::packet::Packet; -use crate::core::ics24_host::path::{ +use ibc_core_channel_types::channel::Counterparty; +use ibc_core_channel_types::commitment::compute_packet_commitment; +use ibc_core_channel_types::error::PacketError; +use ibc_core_channel_types::events::SendPacket; +use ibc_core_channel_types::packet::Packet; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_channel_types::primitives::Expiry; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_host_types::path::{ ChannelEndPath, ClientConsensusStatePath, CommitmentPath, SeqSendPath, }; -use crate::core::timestamp::Expiry; -use crate::core::ContextError; -use crate::prelude::*; + +use crate::context::{SendPacketExecutionContext, SendPacketValidationContext}; /// Send the given packet, including all necessary validation. /// @@ -73,8 +72,11 @@ pub fn send_packet_validate( .into()); } - let client_cons_state_path_on_a = - ClientConsensusStatePath::new(client_id_on_a, &latest_height_on_a); + let client_cons_state_path_on_a = ClientConsensusStatePath::new( + client_id_on_a.clone(), + latest_height_on_a.revision_number(), + latest_height_on_a.revision_height(), + ); let consensus_state_of_b_on_a = ctx_a.client_consensus_state(&client_cons_state_path_on_a)?; let latest_timestamp = consensus_state_of_b_on_a.timestamp(); let packet_timestamp = packet.timeout_timestamp_on_b; diff --git a/crates/ibc/src/core/ics04_channel/handler/timeout.rs b/crates/ibc-core/ics04-channel/src/handler/timeout.rs similarity index 87% rename from crates/ibc/src/core/ics04_channel/handler/timeout.rs rename to crates/ibc-core/ics04-channel/src/handler/timeout.rs index 5235f9a8c..53cd809eb 100644 --- a/crates/ibc/src/core/ics04_channel/handler/timeout.rs +++ b/crates/ibc-core/ics04-channel/src/handler/timeout.rs @@ -1,30 +1,30 @@ -use prost::Message; - -use crate::core::events::{IbcEvent, MessageEvent}; -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::delay::verify_conn_delay_passed; -use crate::core::ics04_channel::channel::{Counterparty, Order, State}; -use crate::core::ics04_channel::commitment::compute_packet_commitment; -use crate::core::ics04_channel::error::{ChannelError, PacketError}; -use crate::core::ics04_channel::events::{ChannelClosed, TimeoutPacket}; -use crate::core::ics04_channel::handler::timeout_on_close; -use crate::core::ics04_channel::msgs::timeout::MsgTimeout; -use crate::core::ics04_channel::msgs::timeout_on_close::MsgTimeoutOnClose; -use crate::core::ics24_host::path::{ +use ibc_core_channel_types::channel::{Counterparty, Order, State}; +use ibc_core_channel_types::commitment::compute_packet_commitment; +use ibc_core_channel_types::error::{ChannelError, PacketError}; +use ibc_core_channel_types::events::{ChannelClosed, TimeoutPacket}; +use ibc_core_channel_types::msgs::{MsgTimeout, MsgTimeoutOnClose}; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection::delay::verify_conn_delay_passed; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::events::{IbcEvent, MessageEvent}; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_host_types::path::{ ChannelEndPath, ClientConsensusStatePath, CommitmentPath, Path, ReceiptPath, SeqRecvPath, }; -use crate::core::router::Module; -use crate::core::{ContextError, ExecutionContext, ValidationContext}; -use crate::prelude::*; +use ibc_core_router::module::Module; +use prost::Message; + +use super::timeout_on_close; -pub(crate) enum TimeoutMsgType { +pub enum TimeoutMsgType { Timeout(MsgTimeout), TimeoutOnClose(MsgTimeoutOnClose), } -pub(crate) fn timeout_packet_validate( +pub fn timeout_packet_validate( ctx_a: &ValCtx, module: &dyn Module, timeout_msg_type: TimeoutMsgType, @@ -47,7 +47,7 @@ where .map_err(ContextError::PacketError) } -pub(crate) fn timeout_packet_execute( +pub fn timeout_packet_execute( ctx_a: &mut ExecCtx, module: &mut dyn Module, timeout_msg_type: TimeoutMsgType, @@ -200,8 +200,11 @@ where client_state_of_b_on_a.validate_proof_height(msg.proof_height_on_b)?; // check that timeout height or timeout timestamp has passed on the other end - let client_cons_state_path_on_a = - ClientConsensusStatePath::new(client_id_on_a, &msg.proof_height_on_b); + let client_cons_state_path_on_a = ClientConsensusStatePath::new( + client_id_on_a.clone(), + msg.proof_height_on_b.revision_number(), + msg.proof_height_on_b.revision_height(), + ); let consensus_state_of_b_on_a = ctx_a.consensus_state(&client_cons_state_path_on_a)?; let timestamp_of_b = consensus_state_of_b_on_a.timestamp(); diff --git a/crates/ibc/src/core/ics04_channel/handler/timeout_on_close.rs b/crates/ibc-core/ics04-channel/src/handler/timeout_on_close.rs similarity index 86% rename from crates/ibc/src/core/ics04_channel/handler/timeout_on_close.rs rename to crates/ibc-core/ics04-channel/src/handler/timeout_on_close.rs index cb0a9b40a..fd518811e 100644 --- a/crates/ibc/src/core/ics04_channel/handler/timeout_on_close.rs +++ b/crates/ibc-core/ics04-channel/src/handler/timeout_on_close.rs @@ -1,19 +1,19 @@ -use ibc_proto::Protobuf; -use prost::Message; - -use crate::core::ics02_client::client_state::{ClientStateCommon, ClientStateValidation}; -use crate::core::ics02_client::consensus_state::ConsensusState; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics03_connection::delay::verify_conn_delay_passed; -use crate::core::ics04_channel::channel::{ChannelEnd, Counterparty, Order, State}; -use crate::core::ics04_channel::commitment::compute_packet_commitment; -use crate::core::ics04_channel::error::{ChannelError, PacketError}; -use crate::core::ics04_channel::msgs::timeout_on_close::MsgTimeoutOnClose; -use crate::core::ics24_host::path::{ +use ibc_core_channel_types::channel::{ChannelEnd, Counterparty, Order, State}; +use ibc_core_channel_types::commitment::compute_packet_commitment; +use ibc_core_channel_types::error::{ChannelError, PacketError}; +use ibc_core_channel_types::msgs::MsgTimeoutOnClose; +use ibc_core_channel_types::primitives::prelude::*; +use ibc_core_channel_types::proto::Protobuf; +use ibc_core_client::context::client_state::{ClientStateCommon, ClientStateValidation}; +use ibc_core_client::context::consensus_state::ConsensusState; +use ibc_core_client::types::error::ClientError; +use ibc_core_connection::delay::verify_conn_delay_passed; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::ValidationContext; +use ibc_core_host_types::path::{ ChannelEndPath, ClientConsensusStatePath, CommitmentPath, Path, ReceiptPath, SeqRecvPath, }; -use crate::core::{ContextError, ValidationContext}; -use crate::prelude::*; +use prost::Message; pub fn validate(ctx_a: &Ctx, msg: &MsgTimeoutOnClose) -> Result<(), ContextError> where @@ -78,8 +78,11 @@ where } client_state_of_b_on_a.validate_proof_height(msg.proof_height_on_b)?; - let client_cons_state_path_on_a = - ClientConsensusStatePath::new(client_id_on_a, &msg.proof_height_on_b); + let client_cons_state_path_on_a = ClientConsensusStatePath::new( + client_id_on_a.clone(), + msg.proof_height_on_b.revision_number(), + msg.proof_height_on_b.revision_height(), + ); let consensus_state_of_b_on_a = ctx_a.consensus_state(&client_cons_state_path_on_a)?; let prefix_on_b = conn_end_on_a.counterparty().prefix(); let port_id_on_b = chan_end_on_a.counterparty().port_id.clone(); diff --git a/crates/ibc-core/ics04-channel/src/lib.rs b/crates/ibc-core/ics04-channel/src/lib.rs new file mode 100644 index 000000000..6e9f844e4 --- /dev/null +++ b/crates/ibc-core/ics04-channel/src/lib.rs @@ -0,0 +1,7 @@ +pub mod context; +pub mod handler; + +pub mod types { + #[doc(inline)] + pub use ibc_core_channel_types::*; +} diff --git a/crates/ibc-core/ics04-channel/types/Cargo.toml b/crates/ibc-core/ics04-channel/types/Cargo.toml new file mode 100644 index 000000000..5852aa507 --- /dev/null +++ b/crates/ibc-core/ics04-channel/types/Cargo.toml @@ -0,0 +1,73 @@ +[package] +name = "ibc-core-channel-types" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +borsh = { workspace = true, optional = true } +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +sha2 = { workspace = true } +serde = { workspace = true, optional = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc-core-client-types = { workspace = true } +ibc-core-connection-types = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-primitives = { workspace = true } +ibc-proto = { workspace = true } + +# cosmos dependencies +tendermint = { workspace = true } + +# parity dependencies +parity-scale-codec = { workspace = true, optional = true } +scale-info = { workspace = true, optional = true } + +[dev-dependencies] +ibc-testkit = { workspace = true } + +[features] +default = ["std"] +std = [ +] +serde = [ + "dep:serde", + "ibc-core-client-types/serde", + "ibc-core-connection-types/serde", + "ibc-core-host-types/serde", + "ibc-core-commitment-types/serde", + "ibc-primitives/serde", + "ibc-proto/serde", +] +schema = [] +borsh = [ + "dep:borsh", + "ibc-core-client-types/borsh", + "ibc-core-connection-types/borsh", + "ibc-core-host-types/borsh", + "ibc-primitives/borsh", +] +parity-scale-codec = [ + "dep:parity-scale-codec", + "dep:scale-info", + "ibc-core-client-types/parity-scale-codec", + "ibc-core-connection-types/parity-scale-codec", + "ibc-core-host-types/parity-scale-codec", +] diff --git a/crates/ibc/src/core/ics04_channel/acknowledgement.rs b/crates/ibc-core/ics04-channel/types/src/acknowledgement.rs similarity index 99% rename from crates/ibc/src/core/ics04_channel/acknowledgement.rs rename to crates/ibc-core/ics04-channel/types/src/acknowledgement.rs index 732234103..b30f14454 100644 --- a/crates/ibc/src/core/ics04_channel/acknowledgement.rs +++ b/crates/ibc-core/ics04-channel/types/src/acknowledgement.rs @@ -3,9 +3,9 @@ use core::fmt::{Display, Error as FmtError, Formatter}; use derive_more::Into; +use ibc_primitives::prelude::*; use super::error::PacketError; -use crate::prelude::*; /// A generic Acknowledgement type that modules may interpret as they like. /// diff --git a/crates/ibc/src/core/ics04_channel/channel.rs b/crates/ibc-core/ics04-channel/types/src/channel.rs similarity index 98% rename from crates/ibc/src/core/ics04_channel/channel.rs rename to crates/ibc-core/ics04-channel/types/src/channel.rs index 43eceacb5..2d980a60d 100644 --- a/crates/ibc/src/core/ics04_channel/channel.rs +++ b/crates/ibc-core/ics04-channel/types/src/channel.rs @@ -3,17 +3,17 @@ use core::fmt::{Display, Error as FmtError, Formatter}; use core::str::FromStr; +use ibc_core_host_types::identifiers::{ChannelId, ConnectionId, PortId}; +use ibc_primitives::prelude::*; +use ibc_primitives::utils::PrettySlice; use ibc_proto::ibc::core::channel::v1::{ Channel as RawChannel, Counterparty as RawCounterparty, IdentifiedChannel as RawIdentifiedChannel, }; use ibc_proto::Protobuf; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::Version; -use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; -use crate::prelude::*; -use crate::utils::pretty::PrettySlice; +use crate::error::ChannelError; +use crate::Version; /// A [`ChannelEnd`] along with its ID and the port it is bound to #[cfg_attr( @@ -570,12 +570,11 @@ impl Display for State { mod tests { use core::str::FromStr; + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::Channel as RawChannel; use ibc_testkit::utils::core::channel::dummy_raw_channel_end; - use test_log::test; - use crate::core::ics04_channel::channel::ChannelEnd; - use crate::prelude::*; + use crate::channel::ChannelEnd; #[test] fn channel_end_try_from_raw() { diff --git a/crates/ibc/src/core/ics04_channel/commitment.rs b/crates/ibc-core/ics04-channel/types/src/commitment.rs similarity index 95% rename from crates/ibc/src/core/ics04_channel/commitment.rs rename to crates/ibc-core/ics04-channel/types/src/commitment.rs index 67f8fbae6..ba5da70c5 100644 --- a/crates/ibc/src/core/ics04_channel/commitment.rs +++ b/crates/ibc-core/ics04-channel/types/src/commitment.rs @@ -1,9 +1,10 @@ //! Types and utilities related to packet commitments. +use ibc_primitives::prelude::*; +use ibc_primitives::Timestamp; + use super::acknowledgement::Acknowledgement; -use crate::core::ics04_channel::timeout::TimeoutHeight; -use crate::core::timestamp::Timestamp; -use crate::prelude::*; +use crate::timeout::TimeoutHeight; /// Packet commitment #[cfg_attr( @@ -124,7 +125,7 @@ mod test { ]; let actual = compute_packet_commitment( "packet data".as_bytes(), - &TimeoutHeight::At(crate::Height::new(42, 24).unwrap()), + &TimeoutHeight::At(ibc_core_client_types::Height::new(42, 24).unwrap()), &Timestamp::from_nanoseconds(0x42).unwrap(), ); assert_eq!(&expected[..], actual.as_ref()); diff --git a/crates/ibc/src/core/ics04_channel/error.rs b/crates/ibc-core/ics04-channel/types/src/error.rs similarity index 94% rename from crates/ibc/src/core/ics04_channel/error.rs rename to crates/ibc-core/ics04-channel/types/src/error.rs index 88a8abcb0..13e33db9c 100644 --- a/crates/ibc/src/core/ics04_channel/error.rs +++ b/crates/ibc-core/ics04-channel/types/src/error.rs @@ -1,18 +1,17 @@ //! Defines the main channel, port and packet error types use displaydoc::Display; +use ibc_core_client_types::{error as client_error, Height}; +use ibc_core_connection_types::error as connection_error; +use ibc_core_host_types::error::IdentifierError; +use ibc_core_host_types::identifiers::{ChannelId, ConnectionId, PortId, Sequence}; +use ibc_primitives::prelude::*; +use ibc_primitives::{ParseTimestampError, Timestamp}; use super::channel::Counterparty; -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::ics04_channel::Version; -use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, IdentifierError, PortId}; -use crate::core::timestamp::{ParseTimestampError, Timestamp}; -use crate::prelude::*; -use crate::Height; +use crate::channel::State; +use crate::Version; #[derive(Debug, Display)] pub enum ChannelError { diff --git a/crates/ibc/src/core/ics04_channel/events.rs b/crates/ibc-core/ics04-channel/types/src/events.rs similarity index 99% rename from crates/ibc/src/core/ics04_channel/events.rs rename to crates/ibc-core/ics04-channel/types/src/events.rs index 58baab970..606d248db 100644 --- a/crates/ibc/src/core/ics04_channel/events.rs +++ b/crates/ibc-core/ics04-channel/types/src/events.rs @@ -3,6 +3,9 @@ mod channel_attributes; mod packet_attributes; +use ibc_core_host_types::identifiers::{ChannelId, ConnectionId, PortId, Sequence}; +use ibc_primitives::prelude::*; +use ibc_primitives::Timestamp; use tendermint::abci; use self::channel_attributes::{ @@ -17,14 +20,10 @@ use self::packet_attributes::{ }; use super::acknowledgement::Acknowledgement; use super::channel::Order; -use super::packet::Sequence; use super::timeout::TimeoutHeight; use super::Version; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::packet::Packet; -use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; -use crate::core::timestamp::Timestamp; -use crate::prelude::*; +use crate::error::ChannelError; +use crate::packet::Packet; /// Channel event types const CHANNEL_OPEN_INIT_EVENT: &str = "channel_open_init"; diff --git a/crates/ibc/src/core/ics04_channel/events/channel_attributes.rs b/crates/ibc-core/ics04-channel/types/src/events/channel_attributes.rs similarity index 97% rename from crates/ibc/src/core/ics04_channel/events/channel_attributes.rs rename to crates/ibc-core/ics04-channel/types/src/events/channel_attributes.rs index d802a50b0..8032fb44d 100644 --- a/crates/ibc/src/core/ics04_channel/events/channel_attributes.rs +++ b/crates/ibc-core/ics04-channel/types/src/events/channel_attributes.rs @@ -1,10 +1,10 @@ //! This module holds all the abci event attributes for IBC events emitted //! during the channel handshake. use derive_more::From; +use ibc_core_host_types::identifiers::{ChannelId, ConnectionId, PortId}; use tendermint::abci; -use crate::core::ics04_channel::Version; -use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; +use crate::Version; const CONNECTION_ID_ATTRIBUTE_KEY: &str = "connection_id"; const CHANNEL_ID_ATTRIBUTE_KEY: &str = "channel_id"; diff --git a/crates/ibc/src/core/ics04_channel/events/packet_attributes.rs b/crates/ibc-core/ics04-channel/types/src/events/packet_attributes.rs similarity index 95% rename from crates/ibc/src/core/ics04_channel/events/packet_attributes.rs rename to crates/ibc-core/ics04-channel/types/src/events/packet_attributes.rs index 58d820635..44a7970a8 100644 --- a/crates/ibc/src/core/ics04_channel/events/packet_attributes.rs +++ b/crates/ibc-core/ics04-channel/types/src/events/packet_attributes.rs @@ -4,17 +4,16 @@ use core::str; use derive_more::From; +use ibc_core_host_types::identifiers::{ChannelId, ConnectionId, PortId, Sequence}; +use ibc_primitives::prelude::*; +use ibc_primitives::Timestamp; use subtle_encoding::hex; use tendermint::abci; -use crate::core::ics04_channel::acknowledgement::Acknowledgement; -use crate::core::ics04_channel::channel::Order; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::packet::Sequence; -use crate::core::ics04_channel::timeout::TimeoutHeight; -use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; -use crate::core::timestamp::Timestamp; -use crate::prelude::*; +use crate::acknowledgement::Acknowledgement; +use crate::channel::Order; +use crate::error::ChannelError; +use crate::timeout::TimeoutHeight; const PKT_SEQ_ATTRIBUTE_KEY: &str = "packet_sequence"; const PKT_DATA_ATTRIBUTE_KEY: &str = "packet_data"; diff --git a/crates/ibc/src/core/ics04_channel/mod.rs b/crates/ibc-core/ics04-channel/types/src/lib.rs similarity index 59% rename from crates/ibc/src/core/ics04_channel/mod.rs rename to crates/ibc-core/ics04-channel/types/src/lib.rs index a969a9cde..29af15dbf 100644 --- a/crates/ibc/src/core/ics04_channel/mod.rs +++ b/crates/ibc-core/ics04-channel/types/src/lib.rs @@ -1,12 +1,12 @@ //! ICS 04: Channel implementation that facilitates communication between //! applications and the chains those applications are built upon. +extern crate alloc; + pub mod channel; -pub mod context; pub mod error; pub mod events; -pub mod handler; pub mod msgs; pub mod packet; pub mod timeout; @@ -15,3 +15,13 @@ pub mod acknowledgement; pub mod commitment; mod version; pub use version::Version; + +pub mod primitives { + pub use ibc_primitives::*; +} + +pub mod proto { + pub use ibc_proto::google::protobuf::Any; + pub use ibc_proto::ibc::core::channel::*; + pub use ibc_proto::Protobuf; +} diff --git a/crates/ibc/src/core/ics04_channel/msgs/acknowledgement.rs b/crates/ibc-core/ics04-channel/types/src/msgs/acknowledgement.rs similarity index 87% rename from crates/ibc/src/core/ics04_channel/msgs/acknowledgement.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/acknowledgement.rs index 7195be630..0b5be9ea8 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/acknowledgement.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/acknowledgement.rs @@ -1,16 +1,15 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgAcknowledgement as RawMsgAcknowledgement; use ibc_proto::Protobuf; -use crate::core::ics04_channel::acknowledgement::Acknowledgement; -use crate::core::ics04_channel::error::PacketError; -use crate::core::ics04_channel::packet::Packet; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::acknowledgement::Acknowledgement; +use crate::error::PacketError; +use crate::packet::Packet; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgAcknowledgement"; +pub const ACKNOWLEDGEMENT_TYPE_URL: &str = "/ibc.core.channel.v1.MsgAcknowledgement"; /// /// Message definition for packet acknowledgements. @@ -35,7 +34,7 @@ impl Msg for MsgAcknowledgement { type Raw = RawMsgAcknowledgement; fn type_url(&self) -> String { - TYPE_URL.to_string() + ACKNOWLEDGEMENT_TYPE_URL.to_string() } } @@ -78,14 +77,13 @@ impl From for RawMsgAcknowledgement { #[cfg(test)] mod test { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgAcknowledgement as RawMsgAcknowledgement; use ibc_testkit::utils::core::channel::dummy_raw_msg_acknowledgement; use ibc_testkit::utils::core::signer::dummy_bech32_account; - use test_log::test; - use crate::core::ics04_channel::error::PacketError; - use crate::core::ics04_channel::msgs::acknowledgement::MsgAcknowledgement; - use crate::prelude::*; + use crate::error::PacketError; + use crate::msgs::acknowledgement::MsgAcknowledgement; #[test] fn msg_acknowledgment_try_from_raw() { diff --git a/crates/ibc/src/core/ics04_channel/msgs/chan_close_confirm.rs b/crates/ibc-core/ics04-channel/types/src/msgs/chan_close_confirm.rs similarity index 92% rename from crates/ibc/src/core/ics04_channel/msgs/chan_close_confirm.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/chan_close_confirm.rs index d9c9867c1..8c028cf11 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/chan_close_confirm.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/chan_close_confirm.rs @@ -1,15 +1,14 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_host_types::identifiers::{ChannelId, PortId}; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgChannelCloseConfirm as RawMsgChannelCloseConfirm; use ibc_proto::Protobuf; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::ics24_host::identifier::{ChannelId, PortId}; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::error::ChannelError; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelCloseConfirm"; +pub const CHAN_CLOSE_CONFIRM_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelCloseConfirm"; /// /// Message definition for the second step in the channel close handshake (the `ChanCloseConfirm` @@ -34,7 +33,7 @@ impl Msg for MsgChannelCloseConfirm { type Raw = RawMsgChannelCloseConfirm; fn type_url(&self) -> String { - TYPE_URL.to_string() + CHAN_CLOSE_CONFIRM_TYPE_URL.to_string() } } @@ -74,12 +73,12 @@ impl From for RawMsgChannelCloseConfirm { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgChannelCloseConfirm as RawMsgChannelCloseConfirm; use ibc_proto::ibc::core::client::v1::Height; use ibc_testkit::utils::core::channel::dummy_raw_msg_chan_close_confirm; - use crate::core::ics04_channel::msgs::chan_close_confirm::MsgChannelCloseConfirm; - use crate::prelude::*; + use crate::msgs::chan_close_confirm::MsgChannelCloseConfirm; #[test] fn parse_channel_close_confirm_msg() { diff --git a/crates/ibc/src/core/ics04_channel/msgs/chan_close_init.rs b/crates/ibc-core/ics04-channel/types/src/msgs/chan_close_init.rs similarity index 92% rename from crates/ibc/src/core/ics04_channel/msgs/chan_close_init.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/chan_close_init.rs index dbbea054b..dafc18dcb 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/chan_close_init.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/chan_close_init.rs @@ -1,13 +1,12 @@ +use ibc_core_host_types::identifiers::{ChannelId, PortId}; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgChannelCloseInit as RawMsgChannelCloseInit; use ibc_proto::Protobuf; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics24_host::identifier::{ChannelId, PortId}; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; +use crate::error::ChannelError; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelCloseInit"; +pub const CHAN_CLOSE_INIT_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelCloseInit"; /// /// Message definition for the first step in the channel close handshake (`ChanCloseInit` datagram). @@ -29,7 +28,7 @@ impl Msg for MsgChannelCloseInit { type Raw = RawMsgChannelCloseInit; fn type_url(&self) -> String { - TYPE_URL.to_string() + CHAN_CLOSE_INIT_TYPE_URL.to_string() } } @@ -59,12 +58,11 @@ impl From for RawMsgChannelCloseInit { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgChannelCloseInit as RawMsgChannelCloseInit; use ibc_testkit::utils::core::channel::dummy_raw_msg_chan_close_init; - use test_log::test; - use crate::core::ics04_channel::msgs::chan_close_init::MsgChannelCloseInit; - use crate::prelude::*; + use crate::msgs::chan_close_init::MsgChannelCloseInit; #[test] fn parse_channel_close_init_msg() { diff --git a/crates/ibc/src/core/ics04_channel/msgs/chan_open_ack.rs b/crates/ibc-core/ics04-channel/types/src/msgs/chan_open_ack.rs similarity index 93% rename from crates/ibc/src/core/ics04_channel/msgs/chan_open_ack.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/chan_open_ack.rs index 65bbb1f4b..c2f962d64 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/chan_open_ack.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/chan_open_ack.rs @@ -1,16 +1,15 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_host_types::identifiers::{ChannelId, PortId}; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenAck as RawMsgChannelOpenAck; use ibc_proto::Protobuf; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::Version; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::ics24_host::identifier::{ChannelId, PortId}; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::error::ChannelError; +use crate::Version; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenAck"; +pub const CHAN_OPEN_ACK_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenAck"; /// Message definition for the third step in the channel open handshake (`ChanOpenAck` datagram). /// @@ -35,7 +34,7 @@ impl Msg for MsgChannelOpenAck { type Raw = RawMsgChannelOpenAck; fn type_url(&self) -> String { - TYPE_URL.to_string() + CHAN_OPEN_ACK_TYPE_URL.to_string() } } @@ -79,13 +78,12 @@ impl From for RawMsgChannelOpenAck { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenAck as RawMsgChannelOpenAck; use ibc_proto::ibc::core::client::v1::Height; use ibc_testkit::utils::core::channel::dummy_raw_msg_chan_open_ack; - use test_log::test; - use crate::core::ics04_channel::msgs::chan_open_ack::MsgChannelOpenAck; - use crate::prelude::*; + use crate::msgs::chan_open_ack::MsgChannelOpenAck; #[test] fn parse_channel_open_ack_msg() { diff --git a/crates/ibc/src/core/ics04_channel/msgs/chan_open_confirm.rs b/crates/ibc-core/ics04-channel/types/src/msgs/chan_open_confirm.rs similarity index 92% rename from crates/ibc/src/core/ics04_channel/msgs/chan_open_confirm.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/chan_open_confirm.rs index 01a03e16e..8ff31e03a 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/chan_open_confirm.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/chan_open_confirm.rs @@ -1,15 +1,14 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_host_types::identifiers::{ChannelId, PortId}; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenConfirm as RawMsgChannelOpenConfirm; use ibc_proto::Protobuf; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::ics24_host::identifier::{ChannelId, PortId}; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::error::ChannelError; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenConfirm"; +pub const CHAN_OPEN_CONFIRM_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenConfirm"; /// /// Message definition for the fourth step in the channel open handshake (`ChanOpenConfirm` @@ -34,7 +33,7 @@ impl Msg for MsgChannelOpenConfirm { type Raw = RawMsgChannelOpenConfirm; fn type_url(&self) -> String { - TYPE_URL.to_string() + CHAN_OPEN_CONFIRM_TYPE_URL.to_string() } } @@ -74,13 +73,12 @@ impl From for RawMsgChannelOpenConfirm { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenConfirm as RawMsgChannelOpenConfirm; use ibc_proto::ibc::core::client::v1::Height; use ibc_testkit::utils::core::channel::dummy_raw_msg_chan_open_confirm; - use test_log::test; - use crate::core::ics04_channel::msgs::chan_open_confirm::MsgChannelOpenConfirm; - use crate::prelude::*; + use crate::msgs::chan_open_confirm::MsgChannelOpenConfirm; #[test] fn parse_channel_open_confirm_msg() { diff --git a/crates/ibc/src/core/ics04_channel/msgs/chan_open_init.rs b/crates/ibc-core/ics04-channel/types/src/msgs/chan_open_init.rs similarity index 89% rename from crates/ibc/src/core/ics04_channel/msgs/chan_open_init.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/chan_open_init.rs index 9f68c475e..2a11c07b9 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/chan_open_init.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/chan_open_init.rs @@ -1,17 +1,14 @@ +use ibc_core_host_types::identifiers::{ConnectionId, PortId}; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenInit as RawMsgChannelOpenInit; use ibc_proto::Protobuf; -use crate::core::ics04_channel::channel::{ - verify_connection_hops_length, ChannelEnd, Counterparty, Order, State, -}; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::Version; -use crate::core::ics24_host::identifier::{ConnectionId, PortId}; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; +use crate::channel::{verify_connection_hops_length, ChannelEnd, Counterparty, Order, State}; +use crate::error::ChannelError; +use crate::Version; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenInit"; +pub const CHAN_OPEN_INIT_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenInit"; /// /// Message definition for the first step in the channel open handshake (`ChanOpenInit` datagram). @@ -37,7 +34,7 @@ impl MsgChannelOpenInit { /// Checks if the `connection_hops` has a length of `expected`. /// /// Note: Current IBC version only supports one connection hop. - pub(crate) fn verify_connection_hops_length(&self) -> Result<(), ChannelError> { + pub fn verify_connection_hops_length(&self) -> Result<(), ChannelError> { verify_connection_hops_length(&self.connection_hops_on_a, 1) } } @@ -46,7 +43,7 @@ impl Msg for MsgChannelOpenInit { type Raw = RawMsgChannelOpenInit; fn type_url(&self) -> String { - TYPE_URL.to_string() + CHAN_OPEN_INIT_TYPE_URL.to_string() } } @@ -93,12 +90,11 @@ impl From for RawMsgChannelOpenInit { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenInit as RawMsgChannelOpenInit; use ibc_testkit::utils::core::channel::dummy_raw_msg_chan_open_init; - use test_log::test; - use crate::core::ics04_channel::msgs::chan_open_init::MsgChannelOpenInit; - use crate::prelude::*; + use crate::msgs::chan_open_init::MsgChannelOpenInit; #[test] fn channel_open_init_from_raw() { diff --git a/crates/ibc/src/core/ics04_channel/msgs/chan_open_try.rs b/crates/ibc-core/ics04-channel/types/src/msgs/chan_open_try.rs similarity index 91% rename from crates/ibc/src/core/ics04_channel/msgs/chan_open_try.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/chan_open_try.rs index ae9c60fc2..a671a5352 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/chan_open_try.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/chan_open_try.rs @@ -1,19 +1,16 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_host_types::identifiers::{ChannelId, ConnectionId, PortId}; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenTry as RawMsgChannelOpenTry; use ibc_proto::Protobuf; -use crate::core::ics04_channel::channel::{ - verify_connection_hops_length, ChannelEnd, Counterparty, Order, State, -}; -use crate::core::ics04_channel::error::ChannelError; -use crate::core::ics04_channel::Version; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::channel::{verify_connection_hops_length, ChannelEnd, Counterparty, Order, State}; +use crate::error::ChannelError; +use crate::Version; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenTry"; +pub const CHAN_OPEN_TRY_TYPE_URL: &str = "/ibc.core.channel.v1.MsgChannelOpenTry"; /// /// Message definition for the second step in the channel open handshake (`ChanOpenTry` datagram). @@ -45,7 +42,7 @@ impl MsgChannelOpenTry { /// Checks if the `connection_hops` has a length of `expected`. /// /// Note: Current IBC version only supports one connection hop. - pub(crate) fn verify_connection_hops_length(&self) -> Result<(), ChannelError> { + pub fn verify_connection_hops_length(&self) -> Result<(), ChannelError> { verify_connection_hops_length(&self.connection_hops_on_b, 1) } } @@ -54,7 +51,7 @@ impl Msg for MsgChannelOpenTry { type Raw = RawMsgChannelOpenTry; fn type_url(&self) -> String { - TYPE_URL.to_string() + CHAN_OPEN_TRY_TYPE_URL.to_string() } } @@ -130,13 +127,12 @@ impl From for RawMsgChannelOpenTry { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgChannelOpenTry as RawMsgChannelOpenTry; use ibc_proto::ibc::core::client::v1::Height; use ibc_testkit::utils::core::channel::dummy_raw_msg_chan_open_try; - use test_log::test; - use crate::core::ics04_channel::msgs::chan_open_try::MsgChannelOpenTry; - use crate::prelude::*; + use crate::msgs::chan_open_try::MsgChannelOpenTry; #[test] fn channel_open_try_from_raw() { diff --git a/crates/ibc/src/core/ics04_channel/msgs.rs b/crates/ibc-core/ics04-channel/types/src/msgs/mod.rs similarity index 66% rename from crates/ibc/src/core/ics04_channel/msgs.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/mod.rs index 4b8c39bda..8e518591c 100644 --- a/crates/ibc/src/core/ics04_channel/msgs.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/mod.rs @@ -1,34 +1,32 @@ //! Message definitions for all ICS4 domain types: channel open & close handshake datagrams, as well //! as packets. -use crate::prelude::*; - -pub mod acknowledgement; -pub mod chan_close_confirm; -pub mod chan_close_init; -pub mod chan_open_ack; -pub mod chan_open_confirm; -pub mod chan_open_init; -pub mod chan_open_try; -pub mod recv_packet; -pub mod timeout; -pub mod timeout_on_close; +mod acknowledgement; +mod chan_close_confirm; +mod chan_close_init; +mod chan_open_ack; +mod chan_open_confirm; +mod chan_open_init; +mod chan_open_try; +mod recv_packet; +mod timeout; +mod timeout_on_close; // Opening handshake messages. // Packet specific messages. -pub use acknowledgement::MsgAcknowledgement; +pub use acknowledgement::*; // Closing handshake messages. -pub use chan_close_confirm::MsgChannelCloseConfirm; -pub use chan_close_init::MsgChannelCloseInit; -pub use chan_open_ack::MsgChannelOpenAck; -pub use chan_open_confirm::MsgChannelOpenConfirm; -pub use chan_open_init::MsgChannelOpenInit; -pub use chan_open_try::MsgChannelOpenTry; -pub use recv_packet::MsgRecvPacket; -pub use timeout::MsgTimeout; -pub use timeout_on_close::MsgTimeoutOnClose; - -use crate::core::ics24_host::identifier::PortId; +pub use chan_close_confirm::*; +pub use chan_close_init::*; +pub use chan_open_ack::*; +pub use chan_open_confirm::*; +pub use chan_open_init::*; +pub use chan_open_try::*; +use ibc_core_host_types::identifiers::*; +use ibc_primitives::prelude::*; +pub use recv_packet::*; +pub use timeout::*; +pub use timeout_on_close::*; /// All channel messages #[cfg_attr( @@ -60,7 +58,7 @@ pub enum PacketMsg { TimeoutOnClose(MsgTimeoutOnClose), } -pub(crate) fn channel_msg_to_port_id(msg: &ChannelMsg) -> &PortId { +pub fn channel_msg_to_port_id(msg: &ChannelMsg) -> &PortId { match msg { ChannelMsg::OpenInit(msg) => &msg.port_id_on_a, ChannelMsg::OpenTry(msg) => &msg.port_id_on_b, @@ -71,7 +69,7 @@ pub(crate) fn channel_msg_to_port_id(msg: &ChannelMsg) -> &PortId { } } -pub(crate) fn packet_msg_to_port_id(msg: &PacketMsg) -> &PortId { +pub fn packet_msg_to_port_id(msg: &PacketMsg) -> &PortId { match msg { PacketMsg::Recv(msg) => &msg.packet.port_id_on_b, PacketMsg::Ack(msg) => &msg.packet.port_id_on_a, diff --git a/crates/ibc/src/core/ics04_channel/msgs/recv_packet.rs b/crates/ibc-core/ics04-channel/types/src/msgs/recv_packet.rs similarity index 88% rename from crates/ibc/src/core/ics04_channel/msgs/recv_packet.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/recv_packet.rs index 91bebda00..da5367036 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/recv_packet.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/recv_packet.rs @@ -1,15 +1,14 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgRecvPacket as RawMsgRecvPacket; use ibc_proto::Protobuf; -use crate::core::ics04_channel::error::PacketError; -use crate::core::ics04_channel::packet::Packet; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::error::PacketError; +use crate::packet::Packet; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgRecvPacket"; +pub const RECV_PACKET_TYPE_URL: &str = "/ibc.core.channel.v1.MsgRecvPacket"; /// /// Message definition for the "packet receiving" datagram. @@ -35,7 +34,7 @@ impl Msg for MsgRecvPacket { type Raw = RawMsgRecvPacket; fn type_url(&self) -> String { - TYPE_URL.to_string() + RECV_PACKET_TYPE_URL.to_string() } } @@ -76,14 +75,13 @@ impl From for RawMsgRecvPacket { #[cfg(test)] mod test { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgRecvPacket as RawMsgRecvPacket; use ibc_testkit::utils::core::channel::dummy_raw_msg_recv_packet; use ibc_testkit::utils::core::signer::dummy_bech32_account; - use test_log::test; - use crate::core::ics04_channel::error::PacketError; - use crate::core::ics04_channel::msgs::recv_packet::MsgRecvPacket; - use crate::prelude::*; + use crate::error::PacketError; + use crate::msgs::recv_packet::MsgRecvPacket; #[test] fn msg_recv_packet_try_from_raw() { diff --git a/crates/ibc/src/core/ics04_channel/msgs/timeout.rs b/crates/ibc-core/ics04-channel/types/src/msgs/timeout.rs similarity index 90% rename from crates/ibc/src/core/ics04_channel/msgs/timeout.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/timeout.rs index 55dd4bc62..3ae4ba4ce 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/timeout.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/timeout.rs @@ -1,15 +1,15 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_host_types::identifiers::Sequence; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgTimeout as RawMsgTimeout; use ibc_proto::Protobuf; -use crate::core::ics04_channel::error::PacketError; -use crate::core::ics04_channel::packet::{Packet, Sequence}; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::error::PacketError; +use crate::packet::Packet; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgTimeout"; +pub const TIMEOUT_TYPE_URL: &str = "/ibc.core.channel.v1.MsgTimeout"; /// /// Message definition for packet timeout domain type, @@ -33,7 +33,7 @@ impl Msg for MsgTimeout { type Raw = RawMsgTimeout; fn type_url(&self) -> String { - TYPE_URL.to_string() + TIMEOUT_TYPE_URL.to_string() } } @@ -79,14 +79,13 @@ impl From for RawMsgTimeout { #[cfg(test)] mod test { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgTimeout as RawMsgTimeout; use ibc_testkit::utils::core::channel::dummy_raw_msg_timeout; use ibc_testkit::utils::core::signer::dummy_bech32_account; - use test_log::test; - use crate::core::ics04_channel::error::PacketError; - use crate::core::ics04_channel::msgs::timeout::MsgTimeout; - use crate::prelude::*; + use crate::error::PacketError; + use crate::msgs::timeout::MsgTimeout; #[test] fn msg_timeout_try_from_raw() { diff --git a/crates/ibc/src/core/ics04_channel/msgs/timeout_on_close.rs b/crates/ibc-core/ics04-channel/types/src/msgs/timeout_on_close.rs similarity index 90% rename from crates/ibc/src/core/ics04_channel/msgs/timeout_on_close.rs rename to crates/ibc-core/ics04-channel/types/src/msgs/timeout_on_close.rs index c590e2bf2..e05cf240d 100644 --- a/crates/ibc/src/core/ics04_channel/msgs/timeout_on_close.rs +++ b/crates/ibc-core/ics04-channel/types/src/msgs/timeout_on_close.rs @@ -1,15 +1,15 @@ +use ibc_core_client_types::Height; +use ibc_core_commitment_types::commitment::CommitmentProofBytes; +use ibc_core_host_types::identifiers::Sequence; +use ibc_primitives::prelude::*; +use ibc_primitives::{Msg, Signer}; use ibc_proto::ibc::core::channel::v1::MsgTimeoutOnClose as RawMsgTimeoutOnClose; use ibc_proto::Protobuf; -use crate::core::ics04_channel::error::PacketError; -use crate::core::ics04_channel::packet::{Packet, Sequence}; -use crate::core::ics23_commitment::commitment::CommitmentProofBytes; -use crate::core::Msg; -use crate::prelude::*; -use crate::signer::Signer; -use crate::Height; +use crate::error::PacketError; +use crate::packet::Packet; -pub(crate) const TYPE_URL: &str = "/ibc.core.channel.v1.MsgTimeoutOnClose"; +pub const TIMEOUT_ON_CLOSE_TYPE_URL: &str = "/ibc.core.channel.v1.MsgTimeoutOnClose"; /// /// Message definition for packet timeout domain type. @@ -33,7 +33,7 @@ impl Msg for MsgTimeoutOnClose { type Raw = RawMsgTimeoutOnClose; fn type_url(&self) -> String { - TYPE_URL.to_string() + TIMEOUT_ON_CLOSE_TYPE_URL.to_string() } } @@ -85,12 +85,11 @@ impl From for RawMsgTimeoutOnClose { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::MsgTimeoutOnClose as RawMsgTimeoutOnClose; use ibc_testkit::utils::core::channel::dummy_raw_msg_timeout_on_close; - use test_log::test; - use crate::core::ics04_channel::msgs::timeout_on_close::MsgTimeoutOnClose; - use crate::prelude::*; + use crate::msgs::timeout_on_close::MsgTimeoutOnClose; #[test] fn msg_timeout_on_close_try_from_raw() { diff --git a/crates/ibc/src/core/ics04_channel/packet.rs b/crates/ibc-core/ics04-channel/types/src/packet.rs similarity index 88% rename from crates/ibc/src/core/ics04_channel/packet.rs rename to crates/ibc-core/ics04-channel/types/src/packet.rs index eba1ca8e9..8c09af4c9 100644 --- a/crates/ibc/src/core/ics04_channel/packet.rs +++ b/crates/ibc-core/ics04-channel/types/src/packet.rs @@ -1,16 +1,13 @@ //! Defines the packet type - -use core::str::FromStr; - +use ibc_core_client_types::Height; +use ibc_core_host_types::identifiers::{ChannelId, PortId, Sequence}; +use ibc_primitives::prelude::*; +use ibc_primitives::Expiry::Expired; +use ibc_primitives::Timestamp; use ibc_proto::ibc::core::channel::v1::{Packet as RawPacket, PacketState as RawPacketState}; use super::timeout::TimeoutHeight; -use crate::core::ics04_channel::error::{ChannelError, PacketError}; -use crate::core::ics24_host::identifier::{ChannelId, PortId}; -use crate::core::timestamp::Expiry::Expired; -use crate::core::timestamp::Timestamp; -use crate::prelude::*; -use crate::Height; +use crate::error::PacketError; /// Enumeration of proof carrying ICS4 message, helper for relayer. #[derive(Clone, Debug, PartialEq, Eq)] @@ -53,65 +50,6 @@ impl core::fmt::Display for PacketMsgType { } } -#[cfg_attr( - feature = "parity-scale-codec", - derive( - parity_scale_codec::Encode, - parity_scale_codec::Decode, - scale_info::TypeInfo - ) -)] -#[cfg_attr( - feature = "borsh", - derive(borsh::BorshSerialize, borsh::BorshDeserialize) -)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -/// The sequence number of a packet enforces ordering among packets from the same source. -#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct Sequence(u64); - -impl FromStr for Sequence { - type Err = ChannelError; - - fn from_str(s: &str) -> Result { - Ok(Self::from(s.parse::().map_err(|e| { - ChannelError::InvalidStringAsSequence { - value: s.to_string(), - error: e, - } - })?)) - } -} - -impl Sequence { - pub fn is_zero(&self) -> bool { - self.0 == 0 - } - - pub fn increment(&self) -> Sequence { - Sequence(self.0 + 1) - } -} - -impl From for Sequence { - fn from(seq: u64) -> Self { - Sequence(seq) - } -} - -impl From for u64 { - fn from(s: Sequence) -> u64 { - s.0 - } -} - -impl core::fmt::Display for Sequence { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - write!(f, "{}", self.0) - } -} - /// The packet type; this is what applications send to one another. /// /// Each application defines the structure of the `data` field. @@ -138,7 +76,7 @@ pub struct Packet { pub chan_id_on_b: ChannelId, #[cfg_attr( feature = "serde", - serde(serialize_with = "crate::serializers::ser_hex_upper") + serde(serialize_with = "ibc_core_commitment_types::serializer::ser_hex_upper") )] pub data: Vec, pub timeout_height_on_b: TimeoutHeight, @@ -187,7 +125,7 @@ impl core::fmt::Debug for Packet { impl Packet { /// Checks whether a packet from a - /// [`SendPacket`](crate::core::ics04_channel::events::SendPacket) + /// [`SendPacket`](crate::events::SendPacket) /// event is timed-out relative to the current state of the /// destination chain. /// @@ -196,9 +134,9 @@ impl Packet { /// the height `dst_chain_height`. /// /// Note: a timed-out packet should result in a - /// [`MsgTimeout`](crate::core::ics04_channel::msgs::timeout::MsgTimeout), + /// [`MsgTimeout`](crate::msgs::MsgTimeout), /// instead of the common-case where it results in - /// [`MsgRecvPacket`](crate::core::ics04_channel::msgs::recv_packet::MsgRecvPacket). + /// [`MsgRecvPacket`](crate::msgs::MsgRecvPacket). pub fn timed_out(&self, dst_chain_ts: &Timestamp, dst_chain_height: Height) -> bool { let height_timed_out = self.timeout_height_on_b.has_expired(dst_chain_height); @@ -275,7 +213,7 @@ impl TryFrom for Packet { impl From for RawPacket { fn from(packet: Packet) -> Self { RawPacket { - sequence: packet.seq_on_a.0, + sequence: packet.seq_on_a.value(), source_port: packet.port_id_on_a.to_string(), source_channel: packet.chan_id_on_a.to_string(), destination_port: packet.port_id_on_b.to_string(), @@ -311,7 +249,7 @@ pub struct PacketState { pub seq: Sequence, #[cfg_attr( feature = "serde", - serde(serialize_with = "crate::serializers::ser_hex_upper") + serde(serialize_with = "ibc_core_commitment_types::serializer::ser_hex_upper") )] pub data: Vec, } @@ -364,7 +302,7 @@ impl TryFrom for PacketState { impl From for RawPacketState { fn from(packet: PacketState) -> Self { Self { - sequence: packet.seq.0, + sequence: packet.seq.value(), port_id: packet.port_id.to_string(), channel_id: packet.chan_id.to_string(), data: packet.data, @@ -374,13 +312,12 @@ impl From for RawPacketState { #[cfg(test)] mod tests { + use ibc_primitives::prelude::*; use ibc_proto::ibc::core::channel::v1::Packet as RawPacket; use ibc_proto::ibc::core::client::v1::Height as RawHeight; use ibc_testkit::utils::core::channel::dummy_raw_packet; - use test_log::test; - use crate::core::ics04_channel::packet::Packet; - use crate::prelude::*; + use crate::packet::Packet; #[test] fn packet_try_from_raw() { diff --git a/crates/ibc/src/core/ics04_channel/timeout.rs b/crates/ibc-core/ics04-channel/types/src/timeout.rs similarity index 97% rename from crates/ibc/src/core/ics04_channel/timeout.rs rename to crates/ibc-core/ics04-channel/types/src/timeout.rs index e70a1efd7..3a7e825ce 100644 --- a/crates/ibc/src/core/ics04_channel/timeout.rs +++ b/crates/ibc-core/ics04-channel/types/src/timeout.rs @@ -2,12 +2,11 @@ use core::fmt::{Display, Error as FmtError, Formatter}; +use ibc_core_client_types::error::ClientError; +use ibc_core_client_types::Height; +use ibc_primitives::prelude::*; use ibc_proto::ibc::core::client::v1::Height as RawHeight; -use crate::core::ics02_client::error::ClientError; -use crate::core::ics02_client::height::Height; -use crate::prelude::*; - /// Indicates a consensus height on the destination chain after which the packet /// will no longer be processed, and will instead count as having timed-out. /// @@ -190,7 +189,7 @@ mod tests { where D: serde::Deserializer<'de>, { - use crate::core::ics02_client::height::Height as Ics02Height; + use ibc_core_client_types::Height as Ics02Height; // Here we have to use a bespoke struct as well in order to deserialize // a height which may have a revision height equal to zero. diff --git a/crates/ibc/src/core/ics04_channel/version.rs b/crates/ibc-core/ics04-channel/types/src/version.rs similarity index 98% rename from crates/ibc/src/core/ics04_channel/version.rs rename to crates/ibc-core/ics04-channel/types/src/version.rs index 9e07bfe21..bf41109da 100644 --- a/crates/ibc/src/core/ics04_channel/version.rs +++ b/crates/ibc-core/ics04-channel/types/src/version.rs @@ -6,8 +6,9 @@ use core::convert::Infallible; use core::fmt::{Display, Error as FmtError, Formatter}; use core::str::FromStr; +use ibc_primitives::prelude::*; + use super::error::ChannelError; -use crate::prelude::*; /// The version field for a `ChannelEnd`. /// diff --git a/crates/ibc-core/ics23-commitment/types/Cargo.toml b/crates/ibc-core/ics23-commitment/types/Cargo.toml new file mode 100644 index 000000000..e77df5e9d --- /dev/null +++ b/crates/ibc-core/ics23-commitment/types/Cargo.toml @@ -0,0 +1,44 @@ +[package] +name = "ibc-core-commitment-types" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + `ibc-core-host` provides the core host functionality for IBC relayers. +""" +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# external dependencies +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +serde = { workspace = true, optional = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc-proto = { workspace = true } +ibc-primitives = {workspace = true } +ics23 = { workspace = true, features = ["host-functions"] } + +[features] +default = ["std"] +std = [ + "displaydoc/std", + "prost/std", + "serde/std", + "ibc-primitives/std", + "ibc-proto/std", + "ics23/std", +] +serde = [ + "dep:serde", + "ibc-primitives/serde", + "ibc-proto/serde", + "ics23/serde", +] diff --git a/crates/ibc/src/core/ics23_commitment/commitment.rs b/crates/ibc-core/ics23-commitment/types/src/commitment.rs similarity index 96% rename from crates/ibc/src/core/ics23_commitment/commitment.rs rename to crates/ibc-core/ics23-commitment/types/src/commitment.rs index 556f58458..0969c565c 100644 --- a/crates/ibc/src/core/ics23_commitment/commitment.rs +++ b/crates/ibc-core/ics23-commitment/types/src/commitment.rs @@ -3,12 +3,12 @@ use core::convert::TryFrom; use core::fmt; +use ibc_primitives::prelude::*; use ibc_proto::ibc::core::commitment::v1::MerkleProof as RawMerkleProof; use subtle_encoding::{Encoding, Hex}; use super::merkle::MerkleProof; -use crate::core::ics23_commitment::error::CommitmentError; -use crate::prelude::*; +use crate::error::CommitmentError; /// Encodes a commitment root; most often a Merkle tree root hash. #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -17,7 +17,7 @@ use crate::prelude::*; pub struct CommitmentRoot { #[cfg_attr( feature = "serde", - serde(serialize_with = "crate::serializers::ser_hex_upper") + serde(serialize_with = "crate::serializer::ser_hex_upper") )] bytes: Vec, } @@ -73,7 +73,7 @@ impl From> for CommitmentRoot { pub struct CommitmentProofBytes { #[cfg_attr( feature = "serde", - serde(serialize_with = "crate::serializers::ser_hex_upper") + serde(serialize_with = "crate::serializer::ser_hex_upper") )] bytes: Vec, } diff --git a/crates/ibc/src/core/ics23_commitment/error.rs b/crates/ibc-core/ics23-commitment/types/src/error.rs similarity index 97% rename from crates/ibc/src/core/ics23_commitment/error.rs rename to crates/ibc-core/ics23-commitment/types/src/error.rs index 1a4bcaaeb..3b7b17575 100644 --- a/crates/ibc/src/core/ics23_commitment/error.rs +++ b/crates/ibc-core/ics23-commitment/types/src/error.rs @@ -1,8 +1,7 @@ //! Defines the commitment error type -use alloc::string::String; - use displaydoc::Display; +use ibc_primitives::prelude::*; use prost::DecodeError; #[derive(Debug, Display)] diff --git a/crates/ibc-core/ics23-commitment/types/src/lib.rs b/crates/ibc-core/ics23-commitment/types/src/lib.rs new file mode 100644 index 000000000..04a2d9bbf --- /dev/null +++ b/crates/ibc-core/ics23-commitment/types/src/lib.rs @@ -0,0 +1,15 @@ +//! ICS 23: Commitment implementation of a cryptographic scheme that verifies +//! state transitions between chains. + +pub mod commitment; +pub mod error; +pub mod merkle; +#[cfg(feature = "serde")] +pub mod serializer; +pub mod specs; + +/// Re-exports commitment proto types from the `ibc-proto-rs` crate +pub mod proto { + pub use ibc_proto::ibc::core::commitment::*; + pub use ibc_proto::{ics23, Protobuf}; +} diff --git a/crates/ibc/src/core/ics23_commitment/merkle.rs b/crates/ibc-core/ics23-commitment/types/src/merkle.rs similarity index 96% rename from crates/ibc/src/core/ics23_commitment/merkle.rs rename to crates/ibc-core/ics23-commitment/types/src/merkle.rs index 26908e6f0..50e711c1d 100644 --- a/crates/ibc/src/core/ics23_commitment/merkle.rs +++ b/crates/ibc-core/ics23-commitment/types/src/merkle.rs @@ -1,5 +1,6 @@ //! Merkle proof utilities +use ibc_primitives::prelude::*; use ibc_proto::ibc::core::commitment::v1::{MerklePath, MerkleProof as RawMerkleProof, MerkleRoot}; use ibc_proto::ics23::commitment_proof::Proof; use ibc_proto::ics23::{ @@ -7,10 +8,9 @@ use ibc_proto::ics23::{ NonExistenceProof, }; -use crate::core::ics23_commitment::commitment::{CommitmentPrefix, CommitmentRoot}; -use crate::core::ics23_commitment::error::CommitmentError; -use crate::core::ics23_commitment::specs::ProofSpecs; -use crate::prelude::*; +use crate::commitment::{CommitmentPrefix, CommitmentRoot}; +use crate::error::CommitmentError; +use crate::specs::ProofSpecs; pub fn apply_prefix(prefix: &CommitmentPrefix, mut path: Vec) -> MerklePath { let mut key_path: Vec = vec![format!("{prefix:?}")]; diff --git a/crates/ibc-core/ics23-commitment/types/src/serializer.rs b/crates/ibc-core/ics23-commitment/types/src/serializer.rs new file mode 100644 index 000000000..b3950b218 --- /dev/null +++ b/crates/ibc-core/ics23-commitment/types/src/serializer.rs @@ -0,0 +1,14 @@ +use ibc_primitives::prelude::*; +use serde::ser::{Serialize, Serializer}; +use subtle_encoding::{Encoding, Hex}; + +pub fn ser_hex_upper(data: T, serializer: S) -> Result +where + S: Serializer, + T: AsRef<[u8]>, +{ + let hex = Hex::upper_case() + .encode_to_string(data) + .map_err(|e| serde::ser::Error::custom(format!("failed to serialize hex: {}", e)))?; + hex.serialize(serializer) +} diff --git a/crates/ibc/src/core/ics23_commitment/specs.rs b/crates/ibc-core/ics23-commitment/types/src/specs.rs similarity index 99% rename from crates/ibc/src/core/ics23_commitment/specs.rs rename to crates/ibc-core/ics23-commitment/types/src/specs.rs index ae7787a39..3c2b1df75 100644 --- a/crates/ibc/src/core/ics23_commitment/specs.rs +++ b/crates/ibc-core/ics23-commitment/types/src/specs.rs @@ -1,8 +1,7 @@ //! Defines proof specs, which encode the structure of proofs +use ibc_primitives::prelude::*; use ibc_proto::ics23::{InnerSpec as RawInnerSpec, LeafOp as RawLeafOp, ProofSpec as RawProofSpec}; - -use crate::prelude::*; /// An array of proof specifications. /// /// This type encapsulates different types of proof specifications, mostly predefined, e.g., for diff --git a/crates/ibc-core/ics24-host/types/Cargo.toml b/crates/ibc-core/ics24-host/types/Cargo.toml new file mode 100644 index 000000000..6e22fae06 --- /dev/null +++ b/crates/ibc-core/ics24-host/types/Cargo.toml @@ -0,0 +1,54 @@ +[package] +name = "ibc-core-host-types" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + `ibc-core-host` provides the core host functionality for IBC relayers. +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +borsh = { workspace = true, optional = true } +derive_more = { workspace = true } +displaydoc = { workspace = true } +schemars = { workspace = true, optional = true } +serde = { workspace = true, optional = true } +rstest = { workspace = true } + +# ibc dependencies +ibc-primitives = { workspace = true } + +# parity dependencies +parity-scale-codec = { workspace = true, optional = true } +scale-info = { workspace = true, optional = true } + +[features] +default = ["std"] +std = [ + "displaydoc/std", + "ibc-primitives/std", +] +serde = [ + "dep:serde", +] +schema = [ + "dep:schemars", + "serde", + "std" +] +borsh = [ + "dep:borsh", +] +parity-scale-codec = [ + "dep:parity-scale-codec", + "dep:scale-info", +] diff --git a/crates/ibc-core/ics24-host/types/src/error.rs b/crates/ibc-core/ics24-host/types/src/error.rs new file mode 100644 index 000000000..5060d6ebb --- /dev/null +++ b/crates/ibc-core/ics24-host/types/src/error.rs @@ -0,0 +1,30 @@ +use displaydoc::Display; + +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[derive(Debug, Display)] +pub enum IdentifierError { + /// identifier `{id}` cannot contain separator '/' + ContainSeparator { id: String }, + /// identifier `{id}` has invalid length `{length}` must be between `{min}`-`{max}` characters + InvalidLength { + id: String, + length: u64, + min: u64, + max: u64, + }, + /// identifier `{id}` must only contain alphanumeric characters or `.`, `_`, `+`, `-`, `#`, - `[`, `]`, `<`, `>` + InvalidCharacter { id: String }, + /// identifier prefix `{prefix}` is invalid + InvalidPrefix { prefix: String }, + /// chain identifier is not formatted with revision number + UnformattedRevisionNumber { chain_id: String }, + /// revision number overflowed + RevisionNumberOverflow, + /// String `{value}` cannot be converted to packet sequence, error: `{reason}` + InvalidStringAsSequence { value: String, reason: String }, + /// identifier cannot be empty + Empty, +} + +#[cfg(feature = "std")] +impl std::error::Error for IdentifierError {} diff --git a/crates/ibc-core/ics24-host/types/src/identifiers/chain_id.rs b/crates/ibc-core/ics24-host/types/src/identifiers/chain_id.rs new file mode 100644 index 000000000..283a12ef4 --- /dev/null +++ b/crates/ibc-core/ics24-host/types/src/identifiers/chain_id.rs @@ -0,0 +1,270 @@ +use core::fmt::{Debug, Display, Error as FmtError, Formatter}; +use core::str::FromStr; + +use crate::error::IdentifierError; +use crate::validate::{ + validate_identifier_chars, validate_identifier_length, validate_prefix_length, +}; + +/// Defines the domain type for chain identifiers. +/// +/// A valid `ChainId` follows the format {chain name}-{revision number} where +/// the revision number indicates how many times the chain has been upgraded. +/// Creating `ChainId`s not in this format will result in an error. +/// +/// It should be noted this format is not standardized yet, though it is widely +/// accepted and compatible with Cosmos SDK driven chains. +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ChainId { + id: String, + revision_number: u64, +} + +impl ChainId { + /// Creates a new `ChainId` with the given chain identifier. + /// + /// It checks the identifier for valid characters according to `ICS-24` + /// specification and returns a `ChainId` successfully. + /// Stricter checks beyond `ICS-24` rests with the users, + /// based on their requirements. + /// + /// If the chain identifier is in the {chain name}-{revision number} format, + /// the revision number is parsed. Otherwise, revision number is set to 0. + /// + /// ``` + /// use ibc_core_host_types::identifiers::ChainId; + /// + /// let chain_id = "chainA"; + /// let id = ChainId::new(chain_id).unwrap(); + /// assert_eq!(id.revision_number(), 0); + /// assert_eq!(id.as_str(), chain_id); + /// + /// let chain_id = "chainA-12"; + /// let id = ChainId::new(chain_id).unwrap(); + /// assert_eq!(id.revision_number(), 12); + /// assert_eq!(id.as_str(), chain_id); + /// ``` + pub fn new(chain_id: &str) -> Result { + Self::from_str(chain_id) + } + + /// Get a reference to the underlying string. + pub fn as_str(&self) -> &str { + &self.id + } + + pub fn split_chain_id(&self) -> Result<(&str, u64), IdentifierError> { + parse_chain_id_string(self.as_str()) + } + + /// Extract the revision number from the chain identifier + pub fn revision_number(&self) -> u64 { + self.revision_number + } + + /// Increases `ChainId`s revision number by one. + /// Fails if the chain identifier is not in + /// `{chain_name}-{revision_number}` format or + /// the revision number overflows. + /// + /// ``` + /// use ibc_core_host_types::identifiers::ChainId; + /// + /// let mut chain_id = ChainId::new("chainA-1").unwrap(); + /// assert!(chain_id.increment_revision_number().is_ok()); + /// assert_eq!(chain_id.revision_number(), 2); + /// + /// let mut chain_id = ChainId::new(&format!("chainA-{}", u64::MAX)).unwrap(); + /// assert!(chain_id.increment_revision_number().is_err()); + /// assert_eq!(chain_id.revision_number(), u64::MAX); + /// ``` + pub fn increment_revision_number(&mut self) -> Result<(), IdentifierError> { + let (chain_name, _) = self.split_chain_id()?; + let inc_revision_number = self + .revision_number + .checked_add(1) + .ok_or(IdentifierError::RevisionNumberOverflow)?; + self.id = format!("{}-{}", chain_name, inc_revision_number); + self.revision_number = inc_revision_number; + Ok(()) + } + + /// A convenient method to check if the `ChainId` forms a valid identifier + /// with the desired min/max length. However, ICS-24 does not specify a + /// certain min or max lengths for chain identifiers. + pub fn validate_length(&self, min_length: u64, max_length: u64) -> Result<(), IdentifierError> { + match self.split_chain_id() { + Ok((chain_name, _)) => validate_prefix_length(chain_name, min_length, max_length), + _ => validate_identifier_length(&self.id, min_length, max_length), + } + } +} + +/// Construct a `ChainId` from a string literal only if it forms a valid +/// identifier. +impl FromStr for ChainId { + type Err = IdentifierError; + + fn from_str(id: &str) -> Result { + // Identifier string must have a maximum length of 64 characters. + + // Validates the chain name for allowed characters according to ICS-24. + validate_identifier_chars(id)?; + match parse_chain_id_string(id) { + Ok((chain_name, revision_number)) => { + // Validate if the chain name with revision number has a valid length. + validate_prefix_length(chain_name, 1, 64)?; + Ok(Self { + id: id.into(), + revision_number, + }) + } + + _ => { + // Validate if the identifier has a valid length. + validate_identifier_length(id, 1, 64)?; + Ok(Self { + id: id.into(), + revision_number: 0, + }) + } + } + } +} + +impl Display for ChainId { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + write!(f, "{}", self.id) + } +} + +/// Parses a string intended to represent a `ChainId` and, if successful, +/// returns a tuple containing the chain name and revision number. +fn parse_chain_id_string(chain_id_str: &str) -> Result<(&str, u64), IdentifierError> { + chain_id_str + .rsplit_once('-') + .filter(|(_, rev_number_str)| { + // Validates the revision number not to start with leading zeros, like "01". + // Zero is the only allowed revision number with leading zero. + rev_number_str.as_bytes().first() != Some(&b'0') || rev_number_str.len() == 1 + }) + .and_then(|(chain_name, rev_number_str)| { + // Parses the revision number string into a `u64` and checks its validity. + rev_number_str + .parse() + .ok() + .map(|revision_number| (chain_name, revision_number)) + }) + .ok_or(IdentifierError::UnformattedRevisionNumber { + chain_id: chain_id_str.to_string(), + }) +} + +#[cfg(test)] +mod tests { + use rstest::rstest; + + use super::*; + + #[rstest] + #[case("chainA-0", "chainA", 0)] + #[case("chainA-1", "chainA", 1)] + #[case("chainA--1", "chainA-", 1)] + #[case("chainA-1-2", "chainA-1", 2)] + #[case("111-2", "111", 2)] + #[case("----1", "---", 1)] + #[case("._+-1", "._+", 1)] + #[case(&("A".repeat(43) + "-3"), &("A".repeat(43)), 3)] + fn test_valid_chain_id_with_rev( + #[case] raw_chain_id: &str, + #[case] chain_name: &str, + #[case] revision_number: u64, + ) { + let chain_id = ChainId::new(raw_chain_id).unwrap(); + assert!(chain_id.validate_length(1, 64).is_ok()); + assert_eq!( + chain_id, + ChainId { + id: format!("{chain_name}-{revision_number}"), + revision_number + } + ); + } + + #[rstest] + #[case("chainA")] + #[case("chainA.2")] + #[case("123")] + #[case("._+")] + #[case("chainA-")] + #[case("chainA-a")] + #[case("chainA-01")] + #[case("chainA-1-")] + #[case(&"A".repeat(64))] + #[case::special_case("chainA-0")] + fn test_valid_chain_id_without_rev(#[case] chain_name: &str) { + let chain_id = ChainId::new(chain_name).unwrap(); + assert!(chain_id.validate_length(1, 64).is_ok()); + assert_eq!( + chain_id, + ChainId { + id: chain_name.into(), + revision_number: 0 + } + ); + } + + #[rstest] + #[case(&"A".repeat(65))] + #[case(&("A".repeat(44) + "-123"))] + #[case("-1")] + #[case(" ----1")] + #[case(" ")] + #[case(" chainA")] + #[case("chain A")] + #[case(" chainA.2")] + #[case(" chainA.2-1")] + #[case(" 1")] + #[case(" -")] + #[case(" -1")] + #[case("/chainA-1")] + fn test_invalid_chain_id(#[case] chain_id_str: &str) { + assert!(ChainId::new(chain_id_str).is_err()); + } + + #[test] + fn test_inc_revision_number() { + let mut chain_id = ChainId::new("chainA-1").unwrap(); + + assert!(chain_id.increment_revision_number().is_ok()); + assert_eq!(chain_id.revision_number(), 2); + assert_eq!(chain_id.as_str(), "chainA-2"); + + assert!(chain_id.increment_revision_number().is_ok()); + assert_eq!(chain_id.revision_number(), 3); + assert_eq!(chain_id.as_str(), "chainA-3"); + } + + #[test] + fn test_failed_inc_revision_number() { + let mut chain_id = ChainId::new("chainA").unwrap(); + + assert!(chain_id.increment_revision_number().is_err()); + assert_eq!(chain_id.revision_number(), 0); + assert_eq!(chain_id.as_str(), "chainA"); + } +} diff --git a/crates/ibc-core/ics24-host/types/src/identifiers/channel_id.rs b/crates/ibc-core/ics24-host/types/src/identifiers/channel_id.rs new file mode 100644 index 000000000..19a3c6627 --- /dev/null +++ b/crates/ibc-core/ics24-host/types/src/identifiers/channel_id.rs @@ -0,0 +1,98 @@ +use core::fmt::{Debug, Display, Error as FmtError, Formatter}; +use core::str::FromStr; + +use crate::error::IdentifierError; +use crate::validate::validate_channel_identifier; + +const CHANNEL_ID_PREFIX: &str = "channel"; + +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ChannelId(String); + +impl ChannelId { + /// Builds a new channel identifier. Like client and connection identifiers, channel ids are + /// deterministically formed from two elements: a prefix `prefix`, and a monotonically + /// increasing `counter`, separated by a dash "-". + /// The prefix is currently determined statically (see `ChannelId::prefix()`) so this method + /// accepts a single argument, the `counter`. + /// + /// ``` + /// # use ibc_core_host_types::identifiers::ChannelId; + /// let chan_id = ChannelId::new(27); + /// assert_eq!(chan_id.to_string(), "channel-27"); + /// ``` + pub fn new(identifier: u64) -> Self { + let id = format!("{}-{}", Self::prefix(), identifier); + Self(id) + } + + /// Returns the static prefix to be used across all channel identifiers. + pub fn prefix() -> &'static str { + CHANNEL_ID_PREFIX + } + + /// Get this identifier as a borrowed `&str` + pub fn as_str(&self) -> &str { + &self.0 + } + + /// Get this identifier as a borrowed byte slice + pub fn as_bytes(&self) -> &[u8] { + self.0.as_bytes() + } +} + +/// This implementation provides a `to_string` method. +impl Display for ChannelId { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + write!(f, "{}", self.0) + } +} + +impl FromStr for ChannelId { + type Err = IdentifierError; + + fn from_str(s: &str) -> Result { + validate_channel_identifier(s).map(|_| Self(s.to_string())) + } +} + +impl AsRef for ChannelId { + fn as_ref(&self) -> &str { + &self.0 + } +} + +impl Default for ChannelId { + fn default() -> Self { + Self::new(0) + } +} + +/// Equality check against string literal (satisfies &ChannelId == &str). +/// ``` +/// use core::str::FromStr; +/// use ibc_core_host_types::identifiers::ChannelId; +/// let channel_id = ChannelId::from_str("channelId-0"); +/// assert!(channel_id.is_ok()); +/// channel_id.map(|id| {assert_eq!(&id, "channelId-0")}); +/// ``` +impl PartialEq for ChannelId { + fn eq(&self, other: &str) -> bool { + self.as_str().eq(other) + } +} diff --git a/crates/ibc-core/ics24-host/types/src/identifiers/client_id.rs b/crates/ibc-core/ics24-host/types/src/identifiers/client_id.rs new file mode 100644 index 000000000..2a1b8fd2d --- /dev/null +++ b/crates/ibc-core/ics24-host/types/src/identifiers/client_id.rs @@ -0,0 +1,93 @@ +use core::fmt::{Debug, Display, Error as FmtError, Formatter}; +use core::str::FromStr; + +use derive_more::Into; + +use super::ClientType; +use crate::error::IdentifierError; +use crate::validate::{validate_client_identifier, validate_client_type}; + +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Into)] +pub struct ClientId(String); + +impl ClientId { + /// Builds a new client identifier. Client identifiers are deterministically formed from two + /// elements: a prefix derived from the client type `ctype`, and a monotonically increasing + /// `counter`; these are separated by a dash "-". + /// + /// ``` + /// # use ibc_core_host_types::identifiers::ClientId; + /// # use ibc_core_host_types::identifiers::ClientType; + /// # use std::str::FromStr; + /// let tm_client_id = ClientId::new(ClientType::from_str("07-tendermint").unwrap(), 0); + /// assert!(tm_client_id.is_ok()); + /// tm_client_id.map(|id| { assert_eq!(&id, "07-tendermint-0") }); + /// ``` + pub fn new(client_type: ClientType, counter: u64) -> Result { + let prefix = client_type.as_str().trim(); + validate_client_type(prefix)?; + let id = format!("{prefix}-{counter}"); + Self::from_str(id.as_str()) + } + + /// Get this identifier as a borrowed `&str` + pub fn as_str(&self) -> &str { + &self.0 + } + + /// Get this identifier as a borrowed byte slice + pub fn as_bytes(&self) -> &[u8] { + self.0.as_bytes() + } +} + +/// This implementation provides a `to_string` method. +impl Display for ClientId { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + write!(f, "{}", self.0) + } +} + +impl FromStr for ClientId { + type Err = IdentifierError; + + fn from_str(s: &str) -> Result { + validate_client_identifier(s).map(|_| Self(s.to_string())) + } +} + +impl Default for ClientId { + fn default() -> Self { + let client_type = + ClientType::from_str("07-tendermint").expect("Never fails because it's valid"); + Self::new(client_type, 0).expect("Never fails because we use a valid client type") + } +} + +/// Equality check against string literal (satisfies &ClientId == &str). +/// ``` +/// use core::str::FromStr; +/// use ibc_core_host_types::identifiers::ClientId; +/// let client_id = ClientId::from_str("clientidtwo"); +/// assert!(client_id.is_ok()); +/// client_id.map(|id| {assert_eq!(&id, "clientidtwo")}); +/// ``` +impl PartialEq for ClientId { + fn eq(&self, other: &str) -> bool { + self.as_str().eq(other) + } +} diff --git a/crates/ibc/src/core/ics02_client/client_type.rs b/crates/ibc-core/ics24-host/types/src/identifiers/client_type.rs similarity index 89% rename from crates/ibc/src/core/ics02_client/client_type.rs rename to crates/ibc-core/ics24-host/types/src/identifiers/client_type.rs index b223fbdae..ff1968ebb 100644 --- a/crates/ibc/src/core/ics02_client/client_type.rs +++ b/crates/ibc-core/ics24-host/types/src/identifiers/client_type.rs @@ -3,9 +3,10 @@ use core::fmt::{Display, Error as FmtError, Formatter}; use core::str::FromStr; -use crate::core::ics24_host::identifier::validate::validate_client_type; -use crate::core::ics24_host::identifier::IdentifierError; -use crate::prelude::*; +use ibc_primitives::prelude::*; + +use crate::error::IdentifierError; +use crate::validate::validate_client_type; #[cfg_attr( feature = "parity-scale-codec", diff --git a/crates/ibc-core/ics24-host/types/src/identifiers/connection_id.rs b/crates/ibc-core/ics24-host/types/src/identifiers/connection_id.rs new file mode 100644 index 000000000..79b545b7a --- /dev/null +++ b/crates/ibc-core/ics24-host/types/src/identifiers/connection_id.rs @@ -0,0 +1,91 @@ +use core::fmt::{Display, Error as FmtError, Formatter}; +use core::str::FromStr; + +use crate::error::IdentifierError; +use crate::validate::validate_connection_identifier; + +const CONNECTION_ID_PREFIX: &str = "connection"; + +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ConnectionId(String); + +impl ConnectionId { + /// Builds a new connection identifier. Connection identifiers are deterministically formed from + /// two elements: a prefix `prefix`, and a monotonically increasing `counter`; these are + /// separated by a dash "-". The prefix is currently determined statically (see + /// `ConnectionId::prefix()`) so this method accepts a single argument, the `counter`. + /// + /// ``` + /// # use ibc_core_host_types::identifiers::ConnectionId; + /// let conn_id = ConnectionId::new(11); + /// assert_eq!(&conn_id, "connection-11"); + /// ``` + pub fn new(identifier: u64) -> Self { + let id = format!("{}-{}", Self::prefix(), identifier); + Self(id) + } + + /// Returns the static prefix to be used across all connection identifiers. + pub fn prefix() -> &'static str { + CONNECTION_ID_PREFIX + } + + /// Get this identifier as a borrowed `&str` + pub fn as_str(&self) -> &str { + &self.0 + } + + /// Get this identifier as a borrowed byte slice + pub fn as_bytes(&self) -> &[u8] { + self.0.as_bytes() + } +} + +/// This implementation provides a `to_string` method. +impl Display for ConnectionId { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + write!(f, "{}", self.0) + } +} + +impl FromStr for ConnectionId { + type Err = IdentifierError; + + fn from_str(s: &str) -> Result { + validate_connection_identifier(s).map(|_| Self(s.to_string())) + } +} + +impl Default for ConnectionId { + fn default() -> Self { + Self::new(0) + } +} + +/// Equality check against string literal (satisfies &ConnectionId == &str). +/// ``` +/// use core::str::FromStr; +/// use ibc_core_host_types::identifiers::ConnectionId; +/// let conn_id = ConnectionId::from_str("connectionId-0"); +/// assert!(conn_id.is_ok()); +/// conn_id.map(|id| {assert_eq!(&id, "connectionId-0")}); +/// ``` +impl PartialEq for ConnectionId { + fn eq(&self, other: &str) -> bool { + self.as_str().eq(other) + } +} diff --git a/crates/ibc-core/ics24-host/types/src/identifiers/mod.rs b/crates/ibc-core/ics24-host/types/src/identifiers/mod.rs new file mode 100644 index 000000000..9ae79f673 --- /dev/null +++ b/crates/ibc-core/ics24-host/types/src/identifiers/mod.rs @@ -0,0 +1,17 @@ +//! Defines identifier types + +mod chain_id; +mod channel_id; +mod client_id; +mod client_type; +mod connection_id; +mod port_id; +mod sequence; + +pub use chain_id::ChainId; +pub use channel_id::ChannelId; +pub use client_id::ClientId; +pub use client_type::ClientType; +pub use connection_id::ConnectionId; +pub use port_id::PortId; +pub use sequence::Sequence; diff --git a/crates/ibc-core/ics24-host/types/src/identifiers/port_id.rs b/crates/ibc-core/ics24-host/types/src/identifiers/port_id.rs new file mode 100644 index 000000000..28842f306 --- /dev/null +++ b/crates/ibc-core/ics24-host/types/src/identifiers/port_id.rs @@ -0,0 +1,70 @@ +use core::fmt::{Display, Error as FmtError, Formatter}; +use core::str::FromStr; + +use crate::error::IdentifierError; +use crate::validate::validate_port_identifier; + +const TRANSFER_PORT_ID: &str = "transfer"; + +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct PortId(String); + +impl PortId { + pub fn new(id: String) -> Result { + Self::from_str(&id) + } + + /// Infallible creation of the well-known transfer port + pub fn transfer() -> Self { + Self(TRANSFER_PORT_ID.to_string()) + } + + /// Get this identifier as a borrowed `&str` + pub fn as_str(&self) -> &str { + &self.0 + } + + /// Get this identifier as a borrowed byte slice + pub fn as_bytes(&self) -> &[u8] { + self.0.as_bytes() + } + + pub fn validate(&self) -> Result<(), IdentifierError> { + validate_port_identifier(self.as_str()) + } +} + +/// This implementation provides a `to_string` method. +impl Display for PortId { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + write!(f, "{}", self.0) + } +} + +impl FromStr for PortId { + type Err = IdentifierError; + + fn from_str(s: &str) -> Result { + validate_port_identifier(s).map(|_| Self(s.to_string())) + } +} + +impl AsRef for PortId { + fn as_ref(&self) -> &str { + self.0.as_str() + } +} diff --git a/crates/ibc-core/ics24-host/types/src/identifiers/sequence.rs b/crates/ibc-core/ics24-host/types/src/identifiers/sequence.rs new file mode 100644 index 000000000..d92755c3e --- /dev/null +++ b/crates/ibc-core/ics24-host/types/src/identifiers/sequence.rs @@ -0,0 +1,63 @@ +use crate::error::IdentifierError; + +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +/// The sequence number of a packet enforces ordering among packets from the same source. +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct Sequence(u64); + +impl std::str::FromStr for Sequence { + type Err = IdentifierError; + + fn from_str(s: &str) -> Result { + Ok(Self::from(s.parse::().map_err(|e| { + IdentifierError::InvalidStringAsSequence { + value: s.to_string(), + reason: e.to_string(), + } + })?)) + } +} + +impl Sequence { + pub fn value(&self) -> u64 { + self.0 + } + pub fn is_zero(&self) -> bool { + self.0 == 0 + } + + pub fn increment(&self) -> Sequence { + Sequence(self.0 + 1) + } +} + +impl From for Sequence { + fn from(seq: u64) -> Self { + Sequence(seq) + } +} + +impl From for u64 { + fn from(s: Sequence) -> u64 { + s.0 + } +} + +impl core::fmt::Display for Sequence { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + write!(f, "{}", self.0) + } +} diff --git a/crates/ibc/src/core/ics24_host/mod.rs b/crates/ibc-core/ics24-host/types/src/lib.rs similarity index 69% rename from crates/ibc/src/core/ics24_host/mod.rs rename to crates/ibc-core/ics24-host/types/src/lib.rs index c7ceab539..0de75f1e4 100644 --- a/crates/ibc/src/core/ics24_host/mod.rs +++ b/crates/ibc-core/ics24-host/types/src/lib.rs @@ -1,5 +1,7 @@ //! ICS 24: Host defines the minimal set of interfaces that a //! state machine hosting an IBC-enabled chain must implement. -pub mod identifier; +pub mod error; +pub mod identifiers; pub mod path; +pub(crate) mod validate; diff --git a/crates/ibc/src/core/ics24_host/path.rs b/crates/ibc-core/ics24-host/types/src/path.rs similarity index 97% rename from crates/ibc/src/core/ics24_host/path.rs rename to crates/ibc-core/ics24-host/types/src/path.rs index 6630abbf0..ede974372 100644 --- a/crates/ibc/src/core/ics24_host/path.rs +++ b/crates/ibc-core/ics24-host/types/src/path.rs @@ -7,11 +7,9 @@ use core::str::FromStr; use derive_more::{Display, From}; +use ibc_primitives::prelude::*; -use crate::core::ics04_channel::packet::Sequence; -use crate::core::ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}; -use crate::prelude::*; -use crate::Height; +use crate::identifiers::{ChannelId, ClientId, ConnectionId, PortId, Sequence}; /// ABCI client upgrade keys /// - The key identifying the upgraded IBC state within the upgrade sub-store @@ -76,19 +74,23 @@ impl ClientStatePath { )] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Display)] -#[display(fmt = "clients/{client_id}/consensusStates/{epoch}-{height}")] +#[display(fmt = "clients/{client_id}/consensusStates/{revision_number}-{revision_height}")] pub struct ClientConsensusStatePath { pub client_id: ClientId, - pub epoch: u64, - pub height: u64, + pub revision_number: u64, + pub revision_height: u64, } impl ClientConsensusStatePath { - pub fn new(client_id: &ClientId, height: &Height) -> ClientConsensusStatePath { + pub fn new( + client_id: ClientId, + revision_number: u64, + revision_height: u64, + ) -> ClientConsensusStatePath { ClientConsensusStatePath { - client_id: client_id.clone(), - epoch: height.revision_number(), - height: height.revision_height(), + client_id, + revision_number, + revision_height, } } } @@ -464,15 +466,15 @@ fn parse_client_paths(components: &[&str]) -> Option { return None; } - let epoch = epoch_height[0]; - let height = epoch_height[1]; + let revision_number = epoch_height[0]; + let revision_height = epoch_height[1]; - let epoch = match epoch.parse::() { + let revision_number = match revision_number.parse::() { Ok(ep) => ep, Err(_) => return None, }; - let height = match height.parse::() { + let revision_height = match revision_height.parse::() { Ok(h) => h, Err(_) => return None, }; @@ -480,8 +482,8 @@ fn parse_client_paths(components: &[&str]) -> Option { Some( ClientConsensusStatePath { client_id, - epoch, - height, + revision_number, + revision_height, } .into(), ) @@ -862,8 +864,8 @@ mod tests { parse_client_paths(&components), Some(Path::ClientConsensusState(ClientConsensusStatePath { client_id: ClientId::default(), - epoch: 15, - height: 31, + revision_number: 15, + revision_height: 31, })) ); } @@ -890,8 +892,8 @@ mod tests { path.unwrap(), Path::ClientConsensusState(ClientConsensusStatePath { client_id: ClientId::default(), - epoch: 15, - height: 31, + revision_number: 15, + revision_height: 31, }) ); } diff --git a/crates/ibc/src/core/ics24_host/identifier/validate.rs b/crates/ibc-core/ics24-host/types/src/validate.rs similarity index 98% rename from crates/ibc/src/core/ics24_host/identifier/validate.rs rename to crates/ibc-core/ics24-host/types/src/validate.rs index c16fcdf12..5fb164020 100644 --- a/crates/ibc/src/core/ics24_host/identifier/validate.rs +++ b/crates/ibc-core/ics24-host/types/src/validate.rs @@ -1,5 +1,6 @@ -use super::IdentifierError as Error; -use crate::prelude::*; +use ibc_primitives::prelude::*; + +use crate::error::IdentifierError as Error; /// Path separator (ie. forward slash '/') const PATH_SEPARATOR: char = '/'; @@ -113,7 +114,6 @@ pub fn validate_channel_identifier(id: &str) -> Result<(), Error> { #[cfg(test)] mod tests { use rstest::rstest; - use test_log::test; use super::*; @@ -241,7 +241,6 @@ mod tests { #[case::u64_min_max_boundary("a", 3, 22, true)] #[case("chainA", 1, 32, true)] #[case("chainA", 1, 64, true)] - #[test_log::test] fn test_prefix_length_validation( #[case] prefix: &str, #[case] min: u64, diff --git a/crates/ibc-core/ics26-routing/Cargo.toml b/crates/ibc-core/ics26-routing/Cargo.toml new file mode 100644 index 000000000..365795064 --- /dev/null +++ b/crates/ibc-core/ics26-routing/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "ibc-core-router" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc-primitives = { workspace = true } +ibc-core-channel-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-router-types = { workspace = true } + + +[features] +default = ["std"] +std = [ +] +serde = [ +] \ No newline at end of file diff --git a/crates/ibc-core/ics26-routing/src/lib.rs b/crates/ibc-core/ics26-routing/src/lib.rs new file mode 100644 index 000000000..45e9beef1 --- /dev/null +++ b/crates/ibc-core/ics26-routing/src/lib.rs @@ -0,0 +1,9 @@ +extern crate alloc; + +pub mod module; +pub mod router; + +pub mod types { + #[doc(inline)] + pub use ibc_core_router_types::*; +} diff --git a/crates/ibc/src/core/router.rs b/crates/ibc-core/ics26-routing/src/module.rs similarity index 58% rename from crates/ibc/src/core/router.rs rename to crates/ibc-core/ics26-routing/src/module.rs index 4cdb66524..26b296713 100644 --- a/crates/ibc/src/core/router.rs +++ b/crates/ibc-core/ics26-routing/src/module.rs @@ -1,99 +1,16 @@ -//! Defines the `Router`, which binds modules to ports - -use alloc::borrow::Borrow; -use core::fmt::{Debug, Display, Error as FmtError, Formatter}; - -use crate::core::events::ModuleEvent; -use crate::core::ics04_channel::acknowledgement::Acknowledgement; -use crate::core::ics04_channel::channel::{Counterparty, Order}; -use crate::core::ics04_channel::error::{ChannelError, PacketError}; -use crate::core::ics04_channel::packet::Packet; -use crate::core::ics04_channel::Version; -use crate::core::ics24_host::identifier::{ChannelId, ConnectionId, PortId}; -use crate::prelude::*; -use crate::signer::Signer; - -/// Router as defined in ICS-26, which binds modules to ports. -pub trait Router { - /// Returns a reference to a `Module` registered against the specified `ModuleId` - fn get_route(&self, module_id: &ModuleId) -> Option<&dyn Module>; - - /// Returns a mutable reference to a `Module` registered against the specified `ModuleId` - fn get_route_mut(&mut self, module_id: &ModuleId) -> Option<&mut dyn Module>; - - /// Return the module_id associated with a given port_id - fn lookup_module(&self, port_id: &PortId) -> Option; -} - -/// Module name, internal to the chain. -/// -/// That is, the IBC protocol never exposes this name. Note that this is -/// different from IBC host [identifiers][crate::core::ics24_host::identifier], -/// which are exposed to other chains by the protocol. -#[cfg_attr( - feature = "parity-scale-codec", - derive( - parity_scale_codec::Encode, - parity_scale_codec::Decode, - scale_info::TypeInfo - ) -)] -#[cfg_attr( - feature = "borsh", - derive(borsh::BorshSerialize, borsh::BorshDeserialize) -)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub struct ModuleId(String); - -impl ModuleId { - pub fn new(s: String) -> Self { - Self(s) - } -} - -impl Display for ModuleId { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { - write!(f, "{}", self.0) - } -} - -impl Borrow for ModuleId { - fn borrow(&self) -> &str { - self.0.as_str() - } -} - -/// Logs and events produced during module callbacks -#[cfg_attr( - feature = "parity-scale-codec", - derive( - parity_scale_codec::Encode, - parity_scale_codec::Decode, - scale_info::TypeInfo - ) -)] -#[cfg_attr( - feature = "borsh", - derive(borsh::BorshSerialize, borsh::BorshDeserialize) -)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[derive(Clone, Debug)] -pub struct ModuleExtras { - pub events: Vec, - pub log: Vec, -} - -impl ModuleExtras { - pub fn empty() -> Self { - ModuleExtras { - events: Vec::new(), - log: Vec::new(), - } - } -} - /// The trait that defines an IBC application +use core::fmt::Debug; + +use ibc_core_channel_types::acknowledgement::Acknowledgement; +use ibc_core_channel_types::channel::{Counterparty, Order}; +use ibc_core_channel_types::error::{ChannelError, PacketError}; +use ibc_core_channel_types::packet::Packet; +use ibc_core_channel_types::Version; +use ibc_core_host_types::identifiers::{ChannelId, ConnectionId, PortId}; +use ibc_core_router_types::module::ModuleExtras; +use ibc_primitives::prelude::*; +use ibc_primitives::Signer; + pub trait Module: Debug { fn on_chan_open_init_validate( &self, diff --git a/crates/ibc-core/ics26-routing/src/router.rs b/crates/ibc-core/ics26-routing/src/router.rs new file mode 100644 index 000000000..b73d16d5c --- /dev/null +++ b/crates/ibc-core/ics26-routing/src/router.rs @@ -0,0 +1,18 @@ +//! Defines the `Router`, which binds modules to ports + +use ibc_core_host_types::identifiers::PortId; +use ibc_core_router_types::module::ModuleId; + +use crate::module::Module; + +/// Router as defined in ICS-26, which binds modules to ports. +pub trait Router { + /// Returns a reference to a `Module` registered against the specified `ModuleId` + fn get_route(&self, module_id: &ModuleId) -> Option<&dyn Module>; + + /// Returns a mutable reference to a `Module` registered against the specified `ModuleId` + fn get_route_mut(&mut self, module_id: &ModuleId) -> Option<&mut dyn Module>; + + /// Return the module_id associated with a given port_id + fn lookup_module(&self, port_id: &PortId) -> Option; +} diff --git a/crates/ibc-core/ics26-routing/types/Cargo.toml b/crates/ibc-core/ics26-routing/types/Cargo.toml new file mode 100644 index 000000000..373b1c2bf --- /dev/null +++ b/crates/ibc-core/ics26-routing/types/Cargo.toml @@ -0,0 +1,82 @@ +[package] +name = "ibc-core-router-types" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +borsh = { workspace = true, optional = true } +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +schemars = { workspace = true, optional = true } +serde = { workspace = true, optional = true } +subtle-encoding = { workspace = true } + +# ibc dependencies +ibc-primitives = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-channel-types = { workspace = true } +ibc-proto = {workspace = true } +ics23 = { workspace = true } + +# cosmos dependencies +tendermint = { workspace = true } + +# parity dependencies +parity-scale-codec = { workspace = true, optional = true } +scale-info = { workspace = true, optional = true } + +[features] +default = ["std"] +std = [ + "displaydoc/std", + "prost/std", + "subtle-encoding/std", + "ibc-primitives/std", + "ibc-core-host-types/std", + "ibc-core-channel-types/std", + "ibc-proto/std", + "ics23/std", + "tendermint/std", +] +serde = [ + "dep:serde", + "ibc-primitives/serde", + "ibc-core-host-types/serde", + "ibc-core-channel-types/serde", + "ibc-proto/serde", + "ics23/serde", +] +borsh = [ + "dep:borsh", + "ibc-primitives/borsh", + "ibc-core-host-types/borsh", + "ibc-core-channel-types/borsh", + "ibc-proto/borsh", +] +schema = [ + "dep:schemars", + "ibc-primitives/schema", + "ibc-core-host-types/schema", + "ibc-core-channel-types/schema", + "ibc-proto/json-schema", +] +parity-scale-codec = [ + "dep:parity-scale-codec", + "dep:scale-info", + "ibc-core-host-types/parity-scale-codec", + "ibc-core-channel-types/parity-scale-codec", +] \ No newline at end of file diff --git a/crates/ibc-core/ics26-routing/types/src/error.rs b/crates/ibc-core/ics26-routing/types/src/error.rs new file mode 100644 index 000000000..3c62ff931 --- /dev/null +++ b/crates/ibc-core/ics26-routing/types/src/error.rs @@ -0,0 +1,18 @@ +use displaydoc::Display; +use ibc_core_host_types::identifiers::PortId; + +/// Error type for the router module. +#[derive(Debug, Display)] +pub enum RouterError { + /// unknown type URL `{url}` + UnknownMessageTypeUrl { url: String }, + /// the message is malformed and cannot be decoded error: `{reason}` + MalformedMessageBytes { reason: String }, + /// port `{port_id}` is unknown + UnknownPort { port_id: PortId }, + /// module not found + ModuleNotFound, +} + +#[cfg(feature = "std")] +impl std::error::Error for RouterError {} diff --git a/crates/ibc-core/ics26-routing/types/src/event.rs b/crates/ibc-core/ics26-routing/types/src/event.rs new file mode 100644 index 000000000..29ec2cecf --- /dev/null +++ b/crates/ibc-core/ics26-routing/types/src/event.rs @@ -0,0 +1,66 @@ +use tendermint::abci; + +/// The event type emitted by IBC applications +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModuleEvent { + pub kind: String, + pub attributes: Vec, +} + +impl From for abci::Event { + fn from(event: ModuleEvent) -> Self { + let attributes = event.attributes.into_iter().map(Into::into).collect(); + abci::Event { + kind: event.kind, + attributes, + } + } +} + +/// A single key/value pair in a [`ModuleEvent`] +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ModuleEventAttribute { + pub key: String, + pub value: String, +} + +impl From<(K, V)> for ModuleEventAttribute { + fn from((k, v): (K, V)) -> Self { + Self { + key: k.to_string(), + value: v.to_string(), + } + } +} + +impl From for abci::EventAttribute { + fn from(attr: ModuleEventAttribute) -> Self { + (attr.key, attr.value).into() + } +} diff --git a/crates/ibc-core/ics26-routing/types/src/lib.rs b/crates/ibc-core/ics26-routing/types/src/lib.rs new file mode 100644 index 000000000..463d1d327 --- /dev/null +++ b/crates/ibc-core/ics26-routing/types/src/lib.rs @@ -0,0 +1,9 @@ +extern crate alloc; + +pub mod error; +pub mod event; +pub mod module; + +pub mod primitives { + pub use ibc_primitives::*; +} diff --git a/crates/ibc-core/ics26-routing/types/src/module.rs b/crates/ibc-core/ics26-routing/types/src/module.rs new file mode 100644 index 000000000..82867fde0 --- /dev/null +++ b/crates/ibc-core/ics26-routing/types/src/module.rs @@ -0,0 +1,74 @@ +use alloc::borrow::Borrow; +use core::fmt::{Debug, Display, Error as FmtError, Formatter}; + +use ibc_primitives::prelude::*; + +use crate::event::ModuleEvent; + +/// Module name, internal to the chain. +/// +/// That is, the IBC protocol never exposes this name. Note that this is +/// different from IBC host [identifiers][ibc_core_host_types::identifiers], +/// which are exposed to other chains by the protocol. +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct ModuleId(String); + +impl ModuleId { + pub fn new(s: String) -> Self { + Self(s) + } +} + +impl Display for ModuleId { + fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { + write!(f, "{}", self.0) + } +} + +impl Borrow for ModuleId { + fn borrow(&self) -> &str { + self.0.as_str() + } +} + +/// Logs and events produced during module callbacks +#[cfg_attr( + feature = "parity-scale-codec", + derive( + parity_scale_codec::Encode, + parity_scale_codec::Decode, + scale_info::TypeInfo + ) +)] +#[cfg_attr( + feature = "borsh", + derive(borsh::BorshSerialize, borsh::BorshDeserialize) +)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Clone, Debug)] +pub struct ModuleExtras { + pub events: Vec, + pub log: Vec, +} + +impl ModuleExtras { + pub fn empty() -> Self { + ModuleExtras { + events: Vec::new(), + log: Vec::new(), + } + } +} diff --git a/crates/ibc/src/core/handler.rs b/crates/ibc-core/src/entrypoint.rs similarity index 79% rename from crates/ibc/src/core/handler.rs rename to crates/ibc-core/src/entrypoint.rs index 7c766a0dd..d67f6680c 100644 --- a/crates/ibc/src/core/handler.rs +++ b/crates/ibc-core/src/entrypoint.rs @@ -1,44 +1,32 @@ -use super::context::RouterError; -use super::ics02_client::handler::{create_client, update_client, upgrade_client}; -use super::ics02_client::msgs::{ClientMsg, MsgUpdateOrMisbehaviour}; -use super::ics03_connection::handler::{ - conn_open_ack, conn_open_confirm, conn_open_init, conn_open_try, -}; -use super::ics03_connection::msgs::ConnectionMsg; -use super::ics04_channel::handler::acknowledgement::{ - acknowledgement_packet_execute, acknowledgement_packet_validate, -}; -use super::ics04_channel::handler::chan_close_confirm::{ - chan_close_confirm_execute, chan_close_confirm_validate, -}; -use super::ics04_channel::handler::chan_close_init::{ - chan_close_init_execute, chan_close_init_validate, -}; -use super::ics04_channel::handler::chan_open_ack::{chan_open_ack_execute, chan_open_ack_validate}; -use super::ics04_channel::handler::chan_open_confirm::{ - chan_open_confirm_execute, chan_open_confirm_validate, -}; -use super::ics04_channel::handler::chan_open_init::{ - chan_open_init_execute, chan_open_init_validate, -}; -use super::ics04_channel::handler::chan_open_try::{chan_open_try_execute, chan_open_try_validate}; -use super::ics04_channel::handler::recv_packet::{recv_packet_execute, recv_packet_validate}; -use super::ics04_channel::handler::timeout::{ +use ibc_core_channel::handler::{ + acknowledgement_packet_execute, acknowledgement_packet_validate, chan_close_confirm_execute, + chan_close_confirm_validate, chan_close_init_execute, chan_close_init_validate, + chan_open_ack_execute, chan_open_ack_validate, chan_open_confirm_execute, + chan_open_confirm_validate, chan_open_init_execute, chan_open_init_validate, + chan_open_try_execute, chan_open_try_validate, recv_packet_execute, recv_packet_validate, timeout_packet_execute, timeout_packet_validate, TimeoutMsgType, }; -use super::ics04_channel::msgs::{ +use ibc_core_channel::types::msgs::{ channel_msg_to_port_id, packet_msg_to_port_id, ChannelMsg, PacketMsg, }; -use super::msgs::MsgEnvelope; -use super::router::Router; -use super::{ExecutionContext, ValidationContext}; +use ibc_core_client::handler::{create_client, update_client, upgrade_client}; +use ibc_core_client::types::msgs::{ClientMsg, MsgUpdateOrMisbehaviour}; +use ibc_core_connection::handler::{ + conn_open_ack, conn_open_confirm, conn_open_init, conn_open_try, +}; +use ibc_core_connection::types::msgs::ConnectionMsg; +use ibc_core_context::types::error::ContextError; +use ibc_core_context::types::msgs::MsgEnvelope; +use ibc_core_context::{ExecutionContext, ValidationContext}; +use ibc_core_router::router::Router; +use ibc_core_router::types::error::RouterError; /// Entrypoint which performs both validation and message execution pub fn dispatch( ctx: &mut impl ExecutionContext, router: &mut impl Router, msg: MsgEnvelope, -) -> Result<(), RouterError> { +) -> Result<(), ContextError> { validate(ctx, router, msg.clone())?; execute(ctx, router, msg) } @@ -51,7 +39,7 @@ pub fn dispatch( /// That is, the state transition of message `i` must be applied before /// message `i+1` is validated. This is equivalent to calling /// `dispatch()` on each successively. -pub fn validate(ctx: &Ctx, router: &impl Router, msg: MsgEnvelope) -> Result<(), RouterError> +pub fn validate(ctx: &Ctx, router: &impl Router, msg: MsgEnvelope) -> Result<(), ContextError> where Ctx: ValidationContext, { @@ -65,15 +53,13 @@ where update_client::validate(ctx, MsgUpdateOrMisbehaviour::Misbehaviour(msg)) } ClientMsg::UpgradeClient(msg) => upgrade_client::validate(ctx, msg), - } - .map_err(RouterError::ContextError), + }, MsgEnvelope::Connection(msg) => match msg { ConnectionMsg::OpenInit(msg) => conn_open_init::validate(ctx, msg), ConnectionMsg::OpenTry(msg) => conn_open_try::validate(ctx, msg), ConnectionMsg::OpenAck(msg) => conn_open_ack::validate(ctx, msg), ConnectionMsg::OpenConfirm(ref msg) => conn_open_confirm::validate(ctx, msg), - } - .map_err(RouterError::ContextError), + }, MsgEnvelope::Channel(msg) => { let port_id = channel_msg_to_port_id(&msg); let module_id = router @@ -93,7 +79,6 @@ where ChannelMsg::CloseInit(msg) => chan_close_init_validate(ctx, module, msg), ChannelMsg::CloseConfirm(msg) => chan_close_confirm_validate(ctx, module, msg), } - .map_err(RouterError::ContextError) } MsgEnvelope::Packet(msg) => { let port_id = packet_msg_to_port_id(&msg); @@ -116,7 +101,6 @@ where timeout_packet_validate(ctx, module, TimeoutMsgType::TimeoutOnClose(msg)) } } - .map_err(RouterError::ContextError) } } } @@ -126,7 +110,7 @@ pub fn execute( ctx: &mut Ctx, router: &mut impl Router, msg: MsgEnvelope, -) -> Result<(), RouterError> +) -> Result<(), ContextError> where Ctx: ExecutionContext, { @@ -140,15 +124,13 @@ where update_client::execute(ctx, MsgUpdateOrMisbehaviour::Misbehaviour(msg)) } ClientMsg::UpgradeClient(msg) => upgrade_client::execute(ctx, msg), - } - .map_err(RouterError::ContextError), + }, MsgEnvelope::Connection(msg) => match msg { ConnectionMsg::OpenInit(msg) => conn_open_init::execute(ctx, msg), ConnectionMsg::OpenTry(msg) => conn_open_try::execute(ctx, msg), ConnectionMsg::OpenAck(msg) => conn_open_ack::execute(ctx, msg), ConnectionMsg::OpenConfirm(ref msg) => conn_open_confirm::execute(ctx, msg), - } - .map_err(RouterError::ContextError), + }, MsgEnvelope::Channel(msg) => { let port_id = channel_msg_to_port_id(&msg); let module_id = router @@ -168,7 +150,6 @@ where ChannelMsg::CloseInit(msg) => chan_close_init_execute(ctx, module, msg), ChannelMsg::CloseConfirm(msg) => chan_close_confirm_execute(ctx, module, msg), } - .map_err(RouterError::ContextError) } MsgEnvelope::Packet(msg) => { let port_id = packet_msg_to_port_id(&msg); @@ -191,7 +172,6 @@ where timeout_packet_execute(ctx, module, TimeoutMsgType::TimeoutOnClose(msg)) } } - .map_err(RouterError::ContextError) } } } diff --git a/crates/ibc-core/src/lib.rs b/crates/ibc-core/src/lib.rs new file mode 100644 index 000000000..43abc3b41 --- /dev/null +++ b/crates/ibc-core/src/lib.rs @@ -0,0 +1,54 @@ +//! Exports data structures and implementations of different IBC core (TAO) components. +#![no_std] +#![forbid(unsafe_code)] +#![cfg_attr(not(test), deny(clippy::unwrap_used))] +#![cfg_attr(not(test), deny(clippy::disallowed_methods, clippy::disallowed_types,))] +#![deny( + warnings, + trivial_numeric_casts, + unused_import_braces, + unused_qualifications, + rust_2018_idioms +)] + +pub mod entrypoint; + +pub mod channel { + #[doc(inline)] + pub use ibc_core_channel::*; +} + +pub mod client { + #[doc(inline)] + pub use ibc_core_client::*; +} + +pub mod commitment { + #[doc(inline)] + pub use ibc_core_commitment_types::*; +} + +pub mod connection { + #[doc(inline)] + pub use ibc_core_connection::*; +} + +pub mod context { + #[doc(inline)] + pub use ibc_core_context::*; +} + +pub mod host { + #[doc(inline)] + pub use ibc_core_host_types::*; +} + +pub mod router { + #[doc(inline)] + pub use ibc_core_router::*; +} + +pub mod primitives { + #[doc(inline)] + pub use ibc_primitives::*; +} diff --git a/crates/ibc-data-types/Cargo.toml b/crates/ibc-data-types/Cargo.toml new file mode 100644 index 000000000..41dc73e23 --- /dev/null +++ b/crates/ibc-data-types/Cargo.toml @@ -0,0 +1,82 @@ +[package] +name = "ibc-data-types" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + TBD +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +ibc-primitives = { workspace = true } +ibc-core-client-types = { workspace = true } +ibc-core-connection-types = { workspace = true } +ibc-core-channel-types = { workspace = true } +ibc-core-commitment-types = { workspace = true } +ibc-core-host-types = { workspace = true } +ibc-core-router-types = { workspace = true } +ibc-core-context-types = { workspace = true } +ibc-app-transfer-types = { workspace = true } + + +[features] +default = ["std"] +std = [ + "ibc-primitives/std", + "ibc-core-client-types/std", + "ibc-core-connection-types/std", + "ibc-core-channel-types/std", + "ibc-core-commitment-types/std", + "ibc-core-host-types/std", + "ibc-core-router-types/std", + "ibc-core-context-types/std", + "ibc-app-transfer-types/std", +] +serde = [ + "ibc-primitives/serde", + "ibc-core-client-types/serde", + "ibc-core-connection-types/serde", + "ibc-core-channel-types/serde", + "ibc-core-commitment-types/serde", + "ibc-core-host-types/serde", + "ibc-core-router-types/serde", + "ibc-core-context-types/serde", + "ibc-app-transfer-types/serde", +] +borsh = [ + "ibc-primitives/borsh", + "ibc-core-client-types/borsh", + "ibc-core-connection-types/borsh", + "ibc-core-channel-types/borsh", + "ibc-core-host-types/borsh", + "ibc-core-router-types/borsh", + "ibc-core-context-types/borsh", + "ibc-app-transfer-types/borsh", +] +schema = [ + "ibc-primitives/schema", + "ibc-core-client-types/schema", + "ibc-core-connection-types/schema", + "ibc-core-channel-types/schema", + "ibc-core-host-types/schema", + "ibc-core-router-types/schema", + "ibc-core-context-types/schema", + "ibc-app-transfer-types/schema", +] +parity-scale-codec = [ + "ibc-core-client-types/parity-scale-codec", + "ibc-core-connection-types/parity-scale-codec", + "ibc-core-channel-types/parity-scale-codec", + "ibc-core-host-types/parity-scale-codec", + "ibc-core-router-types/parity-scale-codec", + "ibc-core-context-types/parity-scale-codec", + "ibc-app-transfer-types/parity-scale-codec", +] \ No newline at end of file diff --git a/crates/ibc-data-types/README.md b/crates/ibc-data-types/README.md new file mode 100644 index 000000000..c4a4f6e0c --- /dev/null +++ b/crates/ibc-data-types/README.md @@ -0,0 +1,27 @@ +# `ibc-data-types` + +## Libraries + +Currently, the `ibc-data-types` crate contains the implementation of the following IBC +core libraries: + +## Contributing + +IBC is specified in English in the [cosmos/ibc repo][ibc]. Any +protocol changes or clarifications should be contributed there. + +If you're interested in contributing, please comment on an issue or open a new +one! + +See also [CONTRIBUTING.md](./../../CONTRIBUTING.md). + +## Resources + +- [IBC Website][ibc-homepage] +- [IBC Specification][ibc] +- [IBC Go implementation][ibc-go] + +[//]: # (general links) +[ibc]: https://github.com/cosmos/ibc +[ibc-go]: https://github.com/cosmos/ibc-go +[ibc-homepage]: https://cosmos.network/ibc diff --git a/crates/ibc-data-types/src/lib.rs b/crates/ibc-data-types/src/lib.rs new file mode 100644 index 000000000..187f99dba --- /dev/null +++ b/crates/ibc-data-types/src/lib.rs @@ -0,0 +1,57 @@ +//! Exports data structures and implementations of different IBC core (TAO) components. +#![no_std] +#![forbid(unsafe_code)] +#![cfg_attr(not(test), deny(clippy::unwrap_used))] +#![cfg_attr(not(test), deny(clippy::disallowed_methods, clippy::disallowed_types,))] +#![deny( + warnings, + trivial_numeric_casts, + unused_import_braces, + unused_qualifications, + rust_2018_idioms +)] + +pub mod primitives { + #[doc(inline)] + pub use ibc_primitives::*; +} + +pub mod client { + #[doc(inline)] + pub use ibc_core_client_types::*; +} + +pub mod connection { + #[doc(inline)] + pub use ibc_core_connection_types::*; +} + +pub mod channel { + #[doc(inline)] + pub use ibc_core_channel_types::*; +} + +pub mod commitment { + #[doc(inline)] + pub use ibc_core_commitment_types::*; +} + +pub mod context { + #[doc(inline)] + pub use ibc_core_context_types::*; +} + +pub mod host { + #[doc(inline)] + pub use ibc_core_host_types::*; +} + +pub mod router { + #[doc(inline)] + pub use ibc_core_router_types::*; +} + +pub mod transfer { + #[doc(inline)] + pub use ibc_app_transfer_types::*; +} diff --git a/crates/ibc-derive/src/utils.rs b/crates/ibc-derive/src/utils.rs index 333c18da2..362578027 100644 --- a/crates/ibc-derive/src/utils.rs +++ b/crates/ibc-derive/src/utils.rs @@ -10,67 +10,67 @@ pub struct Imports; impl Imports { pub fn CommitmentRoot() -> TokenStream { - quote! {ibc::core::ics23_commitment::commitment::CommitmentRoot} + quote! {ibc::core::commitment::commitment::CommitmentRoot} } pub fn CommitmentPrefix() -> TokenStream { - quote! {ibc::core::ics23_commitment::commitment::CommitmentPrefix} + quote! {ibc::core::commitment::commitment::CommitmentPrefix} } pub fn CommitmentProofBytes() -> TokenStream { - quote! {ibc::core::ics23_commitment::commitment::CommitmentProofBytes} + quote! {ibc::core::commitment::commitment::CommitmentProofBytes} } pub fn Path() -> TokenStream { - quote! {ibc::core::ics24_host::path::Path} + quote! {ibc::core::host::path::Path} } pub fn ConsensusState() -> TokenStream { - quote! {ibc::core::ics02_client::consensus_state::ConsensusState} + quote! {ibc::core::client::context::consensus_state::ConsensusState} } pub fn ClientStateCommon() -> TokenStream { - quote! {ibc::core::ics02_client::client_state::ClientStateCommon} + quote! {ibc::core::client::context::client_state::ClientStateCommon} } pub fn ClientStateValidation() -> TokenStream { - quote! {ibc::core::ics02_client::client_state::ClientStateValidation} + quote! {ibc::core::client::context::client_state::ClientStateValidation} } pub fn ClientStateExecution() -> TokenStream { - quote! {ibc::core::ics02_client::client_state::ClientStateExecution} + quote! {ibc::core::client::context::client_state::ClientStateExecution} } pub fn ClientId() -> TokenStream { - quote! {ibc::core::ics24_host::identifier::ClientId} + quote! {ibc::core::host::identifiers::ClientId} } pub fn ClientType() -> TokenStream { - quote! {ibc::core::ics02_client::client_type::ClientType} + quote! {ibc::core::host::identifiers::ClientType} } pub fn ClientError() -> TokenStream { - quote! {ibc::core::ics02_client::error::ClientError} + quote! {ibc::core::client::types::error::ClientError} } pub fn Height() -> TokenStream { - quote! {ibc::Height} + quote! {ibc::core::client::types::Height} } pub fn Any() -> TokenStream { - quote! {ibc::proto::Any} + quote! {ibc::core::client::types::proto::Any} } pub fn Timestamp() -> TokenStream { - quote! {ibc::core::timestamp::Timestamp} + quote! {ibc::core::primitives::Timestamp} } pub fn UpdateKind() -> TokenStream { - quote! {ibc::core::ics02_client::client_state::UpdateKind} + quote! {ibc::core::client::types::UpdateKind} } pub fn Status() -> TokenStream { - quote! {ibc::core::ics02_client::client_state::Status} + quote! {ibc::core::client::types::Status} } } diff --git a/crates/ibc-primitives/Cargo.toml b/crates/ibc-primitives/Cargo.toml new file mode 100644 index 000000000..f84c140b6 --- /dev/null +++ b/crates/ibc-primitives/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "ibc-primitives" +version = { workspace = true } +authors = { workspace = true } +edition = { workspace = true } +rust-version = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +keywords = ["blockchain", "cosmos", "ibc"] +readme = "README.md" +description = """ + `ibc-primitives` furnishes essential types and traits universally + utilized in the implementation of diverse IBC modules, encompassing + core functionalities, clients, and applications. +""" + +[package.metadata.docs.rs] +all-features = true + +[dependencies] +# external dependencies +borsh = { workspace = true, optional = true } +derive_more = { workspace = true } +displaydoc = { workspace = true } +prost = { workspace = true } +schemars = { workspace = true, optional = true } +serde = { workspace = true, optional = true } +time = { workspace = true } + +# ibc dependencies +ibc-proto = { workspace = true } + +# cosmos dependencies +tendermint = { workspace = true } + +[features] +default = ["std", "ibc-proto/std", "serde/std", "time/std", "tendermint/std"] +std = [ + "displaydoc/std", + "ibc-proto/std", + "prost/std", + "tendermint/std", + "time/std", +] +schema = [ + "dep:schemars", + "ibc-proto/json-schema", + "serde", + "std" +] +borsh = ["dep:borsh"] diff --git a/crates/ibc-primitives/README.md b/crates/ibc-primitives/README.md new file mode 100644 index 000000000..06dcdb711 --- /dev/null +++ b/crates/ibc-primitives/README.md @@ -0,0 +1,5 @@ +# `ibc-primitives` + +This library furnishes essential types and traits universally utilized in the +implementation of diverse IBC modules, encompassing core functionalities, +clients, and applications. diff --git a/crates/ibc-primitives/src/lib.rs b/crates/ibc-primitives/src/lib.rs new file mode 100644 index 000000000..cdf79791b --- /dev/null +++ b/crates/ibc-primitives/src/lib.rs @@ -0,0 +1,26 @@ +//! Contains primitives types and traits common to various IBC components. +#![no_std] +#![forbid(unsafe_code)] +#![cfg_attr(not(test), deny(clippy::unwrap_used))] +#![cfg_attr(not(test), deny(clippy::disallowed_methods, clippy::disallowed_types,))] +#![deny( + warnings, + trivial_numeric_casts, + unused_import_braces, + unused_qualifications, + rust_2018_idioms +)] + +extern crate alloc; + +#[cfg(feature = "std")] +extern crate std; + +pub mod prelude; +pub mod utils; + +mod traits; +pub use traits::*; + +mod types; +pub use types::*; diff --git a/crates/ibc/src/prelude.rs b/crates/ibc-primitives/src/prelude.rs similarity index 100% rename from crates/ibc/src/prelude.rs rename to crates/ibc-primitives/src/prelude.rs diff --git a/crates/ibc-primitives/src/traits/mod.rs b/crates/ibc-primitives/src/traits/mod.rs new file mode 100644 index 000000000..9eccbc1ec --- /dev/null +++ b/crates/ibc-primitives/src/traits/mod.rs @@ -0,0 +1,3 @@ +mod msg; + +pub use msg::*; diff --git a/crates/ibc-primitives/src/traits/msg.rs b/crates/ibc-primitives/src/traits/msg.rs new file mode 100644 index 000000000..61eeb796a --- /dev/null +++ b/crates/ibc-primitives/src/traits/msg.rs @@ -0,0 +1,23 @@ +use ibc_proto::google::protobuf::Any; + +use crate::prelude::*; + +/// Trait to be implemented by all IBC messages +pub trait Msg: Clone { + type Raw: From + prost::Message; + + /// Unique type identifier for this message, to support encoding to/from `prost_types::Any`. + fn type_url(&self) -> String; + + fn get_sign_bytes(self) -> Vec { + let raw_msg: Self::Raw = self.into(); + prost::Message::encode_to_vec(&raw_msg) + } + + fn to_any(self) -> Any { + Any { + type_url: self.type_url(), + value: self.get_sign_bytes(), + } + } +} diff --git a/crates/ibc-primitives/src/types/mod.rs b/crates/ibc-primitives/src/types/mod.rs new file mode 100644 index 000000000..8df0d3c40 --- /dev/null +++ b/crates/ibc-primitives/src/types/mod.rs @@ -0,0 +1,5 @@ +mod signer; +mod timestamp; + +pub use signer::*; +pub use timestamp::*; diff --git a/crates/ibc/src/signer.rs b/crates/ibc-primitives/src/types/signer.rs similarity index 100% rename from crates/ibc/src/signer.rs rename to crates/ibc-primitives/src/types/signer.rs diff --git a/crates/ibc/src/core/timestamp.rs b/crates/ibc-primitives/src/types/timestamp.rs similarity index 98% rename from crates/ibc/src/core/timestamp.rs rename to crates/ibc-primitives/src/types/timestamp.rs index e7b22780d..ef54a4630 100644 --- a/crates/ibc/src/core/timestamp.rs +++ b/crates/ibc-primitives/src/types/timestamp.rs @@ -1,4 +1,4 @@ -//! Defines the representation of timestamps used in packet timeouts +//! Defines the representation of timestamps used in IBC. use core::fmt::{Display, Error as FmtError, Formatter}; use core::hash::{Hash, Hasher}; @@ -15,7 +15,7 @@ use crate::prelude::*; pub const ZERO_DURATION: Duration = Duration::from_secs(0); -/// A newtype wrapper over `Option