Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: migrate applications module under the ibc crate into ibc-apps #967

Merged
merged 17 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
resolver = "2"
members = [
"crates/ibc",
"crates/ibc-apps",
"crates/ibc-apps/ics20-transfer",
"crates/ibc-apps/ics20-transfer/types",
"crates/ibc-derive",
"crates/ibc-testkit",
"crates/ibc-query",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ the `ibc` rust crate which defines the main data structures and on-chain logic f
## Libraries

- [ibc](crates/ibc/README.md) - Data structures and on-chain logic for the IBC protocol.
- [ibc-apps](crates/ibc-apps/README.md) - Contains implementation of various IBC applications.
Farhad-Shabani marked this conversation as resolved.
Show resolved Hide resolved
- [ibc-derive](crates/ibc-derive/README.md) - Derive macros for `ClientState`
and `ConsensusState` traits, reducing boilerplate.
- [ibc-testkit](crates/ibc-testkit/README.md) - Testing toolkit to aid `ibc-rs` and host chains in writing integration tests.
Expand Down
29 changes: 29 additions & 0 deletions crates/ibc-apps/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "ibc-apps"
version = { workspace = true }
authors = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
keywords = ["blockchain", "cosmos", "ibc", "applications"]
readme = "README.md"
description = """
`ibc-apps` provides a comprehensive set of libraries for IBC applications,
facilitating seamless integration of IBC business logic into any blockchain system.
"""

[package.metadata.docs.rs]
all-features = true

[dependencies]
ibc-app-transfer = { version = "0.47.0", path = "./ics20-transfer", default-features = false }

[features]
default = ["std"]
std = [
"ibc-app-transfer/std",
]
serde = [
"ibc-app-transfer/serde",
]
48 changes: 48 additions & 0 deletions crates/ibc-apps/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# `ibc-apps`

This crate is top-level library re-exports implemented Inter-Blockchain
Communication (IBC) applications in Rust serves as a centralized hub,
simplifying the process of importing and integrating various IBC applications
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.
Farhad-Shabani marked this conversation as resolved.
Show resolved Hide resolved

The structure within the `ibc-apps` crate is designed to provide flexibility for
external users. It allows you to utilize the own `ibc-apps` crate
Farhad-Shabani marked this conversation as resolved.
Show resolved Hide resolved
comprehensively or selectively import specific libraries, whether you need a
Farhad-Shabani marked this conversation as resolved.
Show resolved Hide resolved
certain IBC application (e.g. `ibc-app-transfer` crate) or only their associated
data structures (e.g. `ibc-app-transfer-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-apps` crate contains the implementation of the following IBC
applications:

### ICS-20: Fungible Token Transfer Application

- [ibc-app-transfer](crates/ibc-apps/ics20-transfer)
- [ibc-app-transfer-types](crates/ibc-apps/ics20-transfer/types)

## 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
44 changes: 44 additions & 0 deletions crates/ibc-apps/ics20-transfer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[package]
name = "ibc-app-transfer"
version = { workspace = true }
authors = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
keywords = ["blockchain", "cosmos", "ibc", "transfer", "ics20"]
readme = "./../README.md"
description = """
Contains the core implementation of the ICS-20 token transfer application logic
along with re-exporting the data structures from `ibc-app-transfer-types` crate.
"""

[package.metadata.docs.rs]
all-features = true

[dependencies]
# external dependencies
serde_json = { workspace = true, optional = true }
sha2 = { workspace = true }

# ibc dependencies
ibc-app-transfer-types = { version = "0.47.0", path = "./types", default-features = false }
ibc = { version = "0.47.0", path = "./../../ibc", default-features = false }

[dev-dependencies]
subtle-encoding = { workspace = true }

[features]
default = ["std"]
std = [
"ibc-app-transfer-types/std",
"ibc/std",
"serde_json/std",
"sha2/std",
]
serde = [
"ibc-app-transfer-types/serde",
"ibc/serde",
"serde_json"
]

134 changes: 134 additions & 0 deletions crates/ibc-apps/ics20-transfer/src/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
//! 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 sha2::{Digest, Sha256};

/// Methods required in token transfer validation, to be implemented by the host
pub trait TokenTransferValidationContext {
type AccountId: TryFrom<Signer>;

/// get_port returns the portID for the transfer module.
fn get_port(&self) -> Result<PortId, TokenTransferError>;

/// Returns the escrow account id for a port and channel combination
fn get_escrow_account(
&self,
port_id: &PortId,
channel_id: &ChannelId,
) -> Result<Self::AccountId, TokenTransferError>;

/// Returns Ok() if the host chain supports sending coins.
fn can_send_coins(&self) -> Result<(), TokenTransferError>;

/// Returns Ok() if the host chain supports receiving coins.
fn can_receive_coins(&self) -> Result<(), TokenTransferError>;

/// Validates the sender and receiver accounts and the coin inputs
fn send_coins_validate(
&self,
from_account: &Self::AccountId,
to_account: &Self::AccountId,
coin: &PrefixedCoin,
) -> Result<(), TokenTransferError>;

/// Validates the receiver account and the coin input
fn mint_coins_validate(
&self,
account: &Self::AccountId,
coin: &PrefixedCoin,
) -> Result<(), TokenTransferError>;

/// Validates the sender account and the coin input
fn burn_coins_validate(
&self,
account: &Self::AccountId,
coin: &PrefixedCoin,
) -> Result<(), TokenTransferError>;

/// Returns a hash of the prefixed denom.
/// Implement only if the host chain supports hashed denominations.
fn denom_hash_string(&self, _denom: &PrefixedDenom) -> Option<String> {
None
}

Check warning on line 56 in crates/ibc-apps/ics20-transfer/src/context.rs

View check run for this annotation

Codecov / codecov/patch

crates/ibc-apps/ics20-transfer/src/context.rs#L54-L56

Added lines #L54 - L56 were not covered by tests
}

/// Methods required in token transfer execution, to be implemented by the host
pub trait TokenTransferExecutionContext: TokenTransferValidationContext {
/// This function should enable sending ibc fungible tokens from one account to another
fn send_coins_execute(
&mut self,
from_account: &Self::AccountId,
to_account: &Self::AccountId,
coin: &PrefixedCoin,
) -> Result<(), TokenTransferError>;

/// This function to enable minting ibc tokens to a user account
fn mint_coins_execute(
&mut self,
account: &Self::AccountId,
coin: &PrefixedCoin,
) -> Result<(), TokenTransferError>;

/// This function should enable burning of minted tokens in a user account
fn burn_coins_execute(
&mut self,
account: &Self::AccountId,
coin: &PrefixedCoin,
) -> Result<(), TokenTransferError>;
}

// https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-028-public-key-addresses.md
Farhad-Shabani marked this conversation as resolved.
Show resolved Hide resolved
pub fn cosmos_adr028_escrow_address(port_id: &PortId, channel_id: &ChannelId) -> Vec<u8> {
let contents = format!("{port_id}/{channel_id}");

let mut hasher = Sha256::new();
hasher.update(VERSION.as_bytes());
hasher.update([0]);
hasher.update(contents.as_bytes());

let mut hash = hasher.finalize().to_vec();
hash.truncate(20);
hash
}

#[cfg(test)]
mod tests {
use subtle_encoding::bech32;

use super::*;
use crate::context::cosmos_adr028_escrow_address;

#[test]
fn test_cosmos_escrow_address() {
fn assert_eq_escrow_address(port_id: &str, channel_id: &str, address: &str) {
let port_id = port_id.parse().unwrap();
let channel_id = channel_id.parse().unwrap();
let gen_address = {
let addr = cosmos_adr028_escrow_address(&port_id, &channel_id);
bech32::encode("cosmos", addr)
};
assert_eq!(gen_address, address.to_owned())
}

// addresses obtained using `gaiad query ibc-transfer escrow-address [port-id] [channel-id]`
assert_eq_escrow_address(
"transfer",
"channel-141",
"cosmos1x54ltnyg88k0ejmk8ytwrhd3ltm84xehrnlslf",
);
assert_eq_escrow_address(
"transfer",
"channel-207",
"cosmos1ju6tlfclulxumtt2kglvnxduj5d93a64r5czge",
);
assert_eq_escrow_address(
"transfer",
"channel-187",
"cosmos177x69sver58mcfs74x6dg0tv6ls4s3xmmcaw53",
);
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
//! Implements the processing logic for ICS20 (token transfer) message.

use super::context::{TokenTransferExecutionContext, TokenTransferValidationContext};
use crate::applications::transfer::error::TokenTransferError;
use crate::applications::transfer::is_sender_chain_source;
use crate::applications::transfer::packet::PacketData;
use crate::core::ics04_channel::packet::Packet;
use crate::prelude::*;

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 crate::context::{TokenTransferExecutionContext, TokenTransferValidationContext};

pub fn refund_packet_token_execute(
ctx_a: &mut impl TokenTransferExecutionContext,
packet: &Packet,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::applications::transfer::context::TokenTransferExecutionContext;
use crate::applications::transfer::error::TokenTransferError;
use crate::applications::transfer::events::DenomTraceEvent;
use crate::applications::transfer::packet::PacketData;
use crate::applications::transfer::{is_receiver_chain_source, TracePrefix};
use crate::core::ics04_channel::packet::Packet;
use crate::core::router::ModuleExtras;
use crate::prelude::*;
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 crate::context::TokenTransferExecutionContext;

/// This function handles the transfer receiving logic.
///
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
use crate::applications::transfer::context::{
TokenTransferExecutionContext, TokenTransferValidationContext,
};
use crate::applications::transfer::error::TokenTransferError;
use crate::applications::transfer::events::TransferEvent;
use crate::applications::transfer::msgs::transfer::MsgTransfer;
use crate::applications::transfer::{is_sender_chain_source, MODULE_ID_STR};
use crate::core::events::{MessageEvent, ModuleEvent};
use crate::core::ics04_channel::context::{
SendPacketExecutionContext, SendPacketValidationContext,
};
use crate::core::ics04_channel::handler::send_packet::{send_packet_execute, send_packet_validate};
use crate::core::ics04_channel::packet::Packet;
use crate::core::ics24_host::path::{ChannelEndPath, SeqSendPath};
use crate::prelude::*;
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 crate::context::{TokenTransferExecutionContext, TokenTransferValidationContext};

/// Initiate a token transfer. Equivalent to calling [`send_transfer_validate`], followed by [`send_transfer_execute`].
pub fn send_transfer<SendPacketCtx, TokenCtx>(
Expand Down
27 changes: 27 additions & 0 deletions crates/ibc-apps/ics20-transfer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! 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) application logic.
#![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_casts,
trivial_numeric_casts,
unused_import_braces,
unused_qualifications,
rust_2018_idioms
)]
#![allow(clippy::result_large_err)]

#[cfg(any(test, feature = "std"))]
extern crate std;

#[doc(inline)]
pub use ibc_app_transfer_types as types;

#[cfg(feature = "serde")]
Farhad-Shabani marked this conversation as resolved.
Show resolved Hide resolved
pub mod context;
#[cfg(feature = "serde")]
pub mod handler;
#[cfg(feature = "serde")]
pub mod module;
Loading
Loading