Skip to content

Commit

Permalink
Complete ICS20 Implementation (#1989)
Browse files Browse the repository at this point in the history
* Add ics26 Module trait

* newtype for Acknowledgement

* Define Router interface

* Improve Router trait

* Update mock router impl

* Test for router API

* Disallow duplicate module_ids in MockRouter

* Add RouterBuilder for seal-style API

* Fix failing test

* Fix CI after merge

* Chainable RouterBuilder::add_route()

* Fix test

* Add Router::has_route() trait method

* Add comments

* Separate mutating/non-mutating trait methods for shadow-paging style API

* Make most Module trait methods optional

* Default impl for MockModule::on_chan_open_try()

* Acknowledgement trait

* Extend router test

* Simplify OnRechPacketResult using FnOnce()

* Cleanup

* Use Cow<str> for CapabilityName::new()

* Use Cow<str> for CapabilityName::new()

* Use newtype ModuleId instead of trait assoc type

* Module callbacks' args as refs

* Fix mock impl

* WIP channel callbacks

* Fix ModuleId ctor validation

* TypedCapability

* Use typed capabilities

* Add Router::route_mut()

* Implement pre-dispatch channel message validation

* Avoid cloning message during channel msg dispatch

* Add ChannelReader::lookup_module_by_channel()

* Complete ics4 dispatch with callbacks

* Fix compile errors from rebase

* Fix CI test

* Improve mock impl for capabilities

* cargo fmt

* Set channel version returned from on_chan_open_try()

* Implement packet handler verification

* Add missing check already received packets on ordered channels

* Avoid cloning message during packet msg dispatch

* Implement RecvPacket NoOp

* cargo fmt and remove unused errors

* Make on_recv_packet() Ack result optional

* Don't return Result from on_recv_packet() and pass GenericAcknowledgement to on_acknowledgement_packet()

* Implement packet callbacks

* Allow callbacks to write logs and emit events

* Fix test

* Add .changelog entry

* Add a comment for state rollback expectation from dispatch()

* ics26_routing::handler::deliver() takes single message as input

* ics26_routing::handler::deliver() returns logs as well

* Remove ctx_ro

* Callbacks return ModuleOutput<T>

* Return HandlerOutputBuilder from channel and packet dispatch fn

* Revert "Callbacks return ModuleOutput<T>"

This reverts commit 1d430c9.

* Address review feedback for comments

* Extract ChannelMsg::lookup_module()

* Add ICS20 Denom type

* Add ICS20 TracePrefix & TracePath type

* Define Coin and Decimal types

* Impl conversions from/to RawDenomTrace

* Make better use of derive-more

* Impl conversions for Coin type

* Add HashedDenom and polish DenomTrace impl

* Define PacketData domain type and conversions

* Use Coin domain type in MsgTransfer

* Fix usage of Coin type in relayer code

* Always panic on decimal arith overflow

* Polish generic Signer impl

* Implement ICS20 signer type

* Coin type with generic Denom param

* Use IbcCoin in MsgTransfer and PrefixedCoin in PacketData

* Minor refactoring

* Fix test_util

* Impl AsRef<[u8]> for GenericAcknowledgement

* Ics20Context is no longer a supertrait of Ics26Context

* Add ICS20 Ack type

* Add ICS20 event enum placeholder

* Define all ICS20 expected keepers and context

* Update send_transfer() for recent context changes

* Give mut ref to set_channel_escrow_address()

* Define ICS20 callback functions

* Fix test build

* Move denom derive functions to integration tests

* Add version to chan_open_try callback

* Rename ChannelId::counter() to sequence()

* Add AppModule error variant to ChannelError

* Implement validation helpers for callbacks

* Define Ics20 callback errors

* Implement channel handshake callbacks

* Fix clippy errors

* Impl Deserialize for PacketData

* Manually implement AsRef<str> for Signer

* Fix ICS20 Ack success from impl

* Add more ICS20 errors

* Improve ack type ctor

* Add ctor for TracePrefix

* Provide denom trace methods to remove prefix and check for empty trace path

* Implement conversion from PrefixedCoin to IbcCoin

* Add Ics20Reader trait methods to check send/receive enabled

* Provided trait method get_channel_escrow_address()

* Add BankReader trait for is_blocked_account()

* Add FromStr bound for Ics20Context::AccountId

* Use IbcCoins in Bank traits

* Impl on_recv_packet() for cases where receiver chain is source

* Fallible OnRecvPacket::write_fn()

* Complete on_recv_packet impl

* Fix test build

* Fix clippy errors

* Implement remaining packet callbacks for ICS20

* Make set_denom_trace() fallible

* Don't derive AsRef

* Complete send_transfer impl

* Manual deserialize impl for Acknowledgement

* Add ctor for Acknowledgement

* Handle packet-data deserialize error separately

* Use U256 for Denom and move bigint.rs to modules/src

* Rename Denom to Amount

* Cleanup

* Fix trait definitions

* Use source enum

* Fix AccountReader trait

* Validate port_id

* More refactoring

* Rename Signer to Address

* Use Address instead of Signer where applicable

* Fix send_transfer packet creation

* Fix clippy warnings

* Define ICS20 events

* Extract relay code into separate files

* Fix clippy warnings

* Make HandlerOutput/Builder generic over events

* Define ModuleEvent

* Add AppModule variant to IbcEvent

* Impl Display for Acknowledgement

* Derive serde for ModuleId

* Add ModuleId to ModuleEvent

* Impl conversion from tuple for ModuleEventAttribute

* Impl conversions from ICS20 events to ModuleEvent

* Add event for transfer

* Remove bech32 validation from Address

* Change MsgTransfer receiver type to Address

* Extract MockContext IbcStore

* Improve conversion from Signer to AccountId

* Add deliver method to Module trait

* Implement conversions for MsgTransfer to/from Protobuf Any

* Store packet result directly in send_transfer()

* Make all ICS20 mods public

* Make all IbsStore fields public to enable access for app modules

* Implement Ics20Context for DummyTransferModule

* Fix failing test

* Manual Clone impl for MockContext

* Fix failing test

* Revert "Fix failing test"

This reverts commit 40aec61.

* Fix MockContext Clone impl

* Update trait definitions after merge with master

* Replace ModuleOutput with ModuleOutputBuilder in callbacks

* Add inout param ModuleOutputBuilder to Ics20 callback handlers

* Emit ICS20 receive packet events

* Module::deliver() must be able to emit IbcEvents

* Allow HandlerOutputBuilder to merge HandlerOutput

* Emit transfer event

* Add AckStatusEvent

* Emit ICS20 ack events

* Emit ICS20 timeout events

* Remove ABCI error code

* Remove #[allow(unused)]

* Add log for send transfer

* MsgReceipt abstraction

* Handle missing IbcEvent to AbciEvent conversions for RecvPacket and TimeoutOnClose events

* Implement ModuleEvent to AbciEvent conversion

* Make send_transfer() public

* Allow empty TracePaths

* Fix TracePath multiple prefix parse bug

* Fix TracePath empty str parse bug

* Improve DenomTrace FromStr

* Add denom validation test

* Add denom trace and serde tests

* TracePath tests

* Allow Denom with '/'

* Fix HashedDenom FromStr impl for empty hash

* Minor refactoring

* Add IbcCoin tests

* Add .changelog entry

* Fix clippy errors

* Disallow empty Signer and replace Address with it

* Use ToString as trait bound for ICS20 AccountId

* Change AccountId trait bound from FromStr to TryFrom<Signer>

* Remove Signer::new()

* Delete OCap related TODO

* Remove the PortKeeper

* Remove Module::deliver()

* Fix clippy warnings

* Rename transfer module

* Rename mod relay

* Fix tests failing due to empty signer

* Rename PORT_ID const to PORT_ID_STR

* Fix escrow addr gen

* Test cosmos escrow addr gen

* Rename receiver account

* Remove `has_denom_trace()`

* Remove `BankReader::is_blocked_account()`

* Remove `AccountId::ToString` bound

* Remove `AccountReader`

* Mint/burn into user accounts directly

* Use `chunks_exact()` instead of `windows().step_by()`

* Rename `DenomTrace::has_prefix()` to `trace_starts_with()`

* Move trace related methods into `TracePath`

* Fix add/remove prefix

* Add test for add/remove trace prefix

* Set denom trace only if not already set

* Use truncate instead of drain in cosmos_adr028_escrow_address()

* Rename DenomTrace as PrefixedDenom

* Modify all `BankKeeper` methods to use `PrefixedCoin` instead of `IbcCoin`

* Rename `Denom` as `BaseDenom`

* Impl Into<U256> and checked_add/sub() for Amount

* Add more TracePath tests

* Test TracePath is_empty()

* Remove IbcCoin

* Remove HashedDenom and HashedCoin

* Fix test compilation

* Add comment for send_transfer()

* Functions for determining source chain

* Minor refactoring

* cargo fmt

* Derive serde for PacketCommitment and AcknowledgementCommitment

* docstring and comment

Co-authored-by: Philippe Laferriere <plafer@protonmail.com>
  • Loading branch information
hu55a1n1 and plafer committed Jun 1, 2022
1 parent 65a0189 commit adbe235
Show file tree
Hide file tree
Showing 74 changed files with 2,654 additions and 567 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Complete ICS20 implementation ([#1759](https://github.com/informalsystems/ibc-rs/issues/1759))
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion modules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ subtle-encoding = { version = "0.5", default-features = false }
sha2 = { version = "0.10.2", default-features = false }
flex-error = { version = "0.4.4", default-features = false }
num-traits = { version = "0.2.15", default-features = false }
derive_more = { version = "0.99.17", default-features = false, features = ["from", "display"] }
derive_more = { version = "0.99.17", default-features = false, features = ["from", "into", "display"] }
uint = { version = "0.9", default-features = false }

[dependencies.tendermint]
version = "=0.23.7"
Expand Down

This file was deleted.

28 changes: 0 additions & 28 deletions modules/src/applications/ics20_fungible_token_transfer/denom.rs

This file was deleted.

46 changes: 0 additions & 46 deletions modules/src/applications/ics20_fungible_token_transfer/error.rs

This file was deleted.

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion modules/src/applications/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
//! Various packet encoding semantics which underpin the various types of transactions.

pub mod ics20_fungible_token_transfer;
pub mod transfer;
61 changes: 61 additions & 0 deletions modules/src/applications/transfer/acknowledgement.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use super::error::Error;
use crate::core::ics26_routing::context::Acknowledgement as AckTrait;
use crate::prelude::*;
use core::fmt::{Display, Formatter};

use serde::{Deserialize, Deserializer};

/// A string constant included in error acknowledgements.
/// NOTE: Changing this const is state machine breaking as acknowledgements are written into state
pub const ACK_ERR_STR: &str = "error handling packet on destination chain: see events for details";
pub const ACK_SUCCESS_B64: &[u8] = b"AQ==";

#[derive(Clone, Debug)]
pub enum Acknowledgement {
/// Equivalent to b"AQ==" (i.e. `base64::encode(0x01)`)
Success(Vec<u8>),
/// Error Acknowledgement
Error(String),
}

impl Acknowledgement {
pub fn success() -> Self {
Self::Success(ACK_SUCCESS_B64.to_vec())
}

pub fn from_error(err: Error) -> Self {
Self::Error(format!("{}: {}", ACK_ERR_STR, err))
}
}

impl AsRef<[u8]> for Acknowledgement {
fn as_ref(&self) -> &[u8] {
match self {
Acknowledgement::Success(b) => b.as_slice(),
Acknowledgement::Error(s) => s.as_bytes(),
}
}
}

impl<'de> Deserialize<'de> for Acknowledgement {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let s = String::deserialize(deserializer)?;
let ack = if s.as_bytes() == ACK_SUCCESS_B64 {
Self::Success(ACK_SUCCESS_B64.to_vec())
} else {
Self::Error(s)
};
Ok(ack)
}
}

impl Display for Acknowledgement {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
Acknowledgement::Success(_) => write!(f, "AQ=="),
Acknowledgement::Error(err_str) => write!(f, "{}", err_str),
}
}
}

impl AckTrait for Acknowledgement {}
Loading

0 comments on commit adbe235

Please sign in to comment.