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

ICS20 ADR Proposal #1884

Merged

Conversation

Wizdave97
Copy link
Contributor

@Wizdave97 Wizdave97 commented Feb 17, 2022

Closes: https://github.com/informalsystems/ibc-rs/issues/2090

Description


PR author checklist:

  • Added changelog entry, using unclog.
  • Added tests: integration (for Hermes) or unit/mock tests (for modules).
  • Linked to GitHub issue.
  • Updated code comments and documentation (e.g., docs/).

Reviewer checklist:

  • Reviewed Files changed in the GitHub PR explorer.
  • Manually tested (in case integration/unit/mock tests are absent).

@hu55a1n1
Copy link
Member

Thanks, @Wizdave97! 🙏 This is very helpful work! I am currently working on a draft PR (#1838) where I am trying to define the API for ICS26 modules. While this PR is being reviewed, please feel free to check that out.

Copy link
Member

@hu55a1n1 hu55a1n1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks again for this PR @Wizdave97! 🙏 I have added some comments (most of which are just nits 🙂) and observations. I think it would be better to revisit this after we merge #1838, because that will have a significant impact on the module's design.

/// Full denomination path
trace_path: String,
/// Base denimination
base_denom: String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be nice to have a newtype for Domain. This will help us enforce some restrictions (e.g. '/' not permitted, etc.). Ideally, we would want this type to implement to impl Asref<str>, FromStr & Display.

pub struct Denom(String);

}

/// This struct and it's implementations should help identifying denomination traces
pub struct DenomTrace {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DenomTrace could also be a modelled like so ->

struct TracePrefix {
    port_id: PortId,
    channel_id: ChannelId,
}

pub struct DenomTrace {
    trace_path: Vec<TracePrefix>,
    base_denom: Denom
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be relevant for the TracePrefix struct described above -> informalsystems/ibc-rs#745


impl DenomTrace {
/// Creates a denom trace from a raw string
pub fn parse_denom_trace(raw_trace: &str) -> Self {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method can fail as not all strings are valid DenomTraces. I would suggest we instead implement FromStr. And provide no other ctors.

...
}
/// Validates the denom trace fields
fn validate(&self) -> Result<(), ICS20Error> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wouldn't be required if the type is only constructible via FromStr.

fn get_prefix(&self) -> String {
...
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A has_prefix() method would be useful (to determine if the current zone is source or sink).

}
}

type Coin = ibc_proto::cosmos::base::v1beta1::Coin;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have a Coin domain type. cosmrs has a decent implementation -> https://github.com/cosmos/cosmos-rust/blob/main/cosmrs/src/base.rs#L118.

/// acknowledgement written on the receiving chain. If the acknowledgement
/// was a success then nothing occurs. If the acknowledgement failed, then
/// the sender is refunded their tokens.
pub on_acknowledgement_packet<Ctx>(ctx: &Ctx, packet: Packet, data: MsgTransfer) -> Result<(), ICS20Error>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, this function should return an Acknowledgement type - both on success and failure. So we're also missing this Acknowledgement type. We'd also want this type to implement From<GenericAcknowledgement> or From<Vec<u8>>. See ICS20 technical specification ->

pub enum Acknowledgement {
    Success, // => b"AQ=="
    Error(String),
}

Additionally, this type must also implement the Acknowledgement trait -> https://github.com/informalsystems/ibc-rs/pull/1838#discussion_r809215296

```rust
/// Initiates ICS20 token transfer
/// Escrows tokens from sender and registers the send packet
pub send_transfer<Ctx>(ctx: &Ctx, source_port: PortId, msg: MsgTransfer) -> Result<(), ICS20Error>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The source_port should already be available from the MsgTransfer, right? So maybe we can remove the redundant arg.

fn get_port(&self) -> Result<PortId, Error>;
}

pub trait BankKeeper<AccountId: Into<String>> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯


The following handlers are recommended to be implemented in the ics20_fungible_token_transfer application in the ibc-rs crate

These handlers will be executed in the module callbacks of any thirdparty IBCmodule that is implementing an ICS20 application on-chain
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the design of these handlers will depend on the design of the ICS26 Module trait. We might need to impose additional restrictions due to trait object safety. https://github.com/informalsystems/ibc-rs/pull/1838/files#r809237272

@Wizdave97
Copy link
Contributor Author

Thanks again for this PR @Wizdave97! 🙏 I have added some comments (most of which are just nits 🙂) and observations. I think it would be better to revisit this after we merge #1838, because that will have a significant impact on the module's design.

Thank you for the review, I'll work on your comments over the weekend.

fn authenticate_capability(&self, cap: Capability, name: &str) -> bool;
/// claim_capability allows the transfer module to claim a capability that IBC module
/// passes to it
fn claim_capability(&self, cap: Capability, name: &str) -> Result<(), ICS20Error>;
Copy link
Member

@hu55a1n1 hu55a1n1 Feb 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this keeper must provide functions to read/modify the channelEscrowAddresses mapping in the module state.

}

/// Handles incoming packets with ICS20 data
pub on_recv_packet<Ctx>(ctx: &Ctx, packet: Packet, data: MsgTransfer) -> Result<(), ICS20Error>
Copy link
Member

@hu55a1n1 hu55a1n1 Feb 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need to define a PacketData type for this module with a deserialize impl, something like ->

struct FungibleTokenPacketData {
  denomination: Denom,
  amount: U256,
  sender: AccountId,
  receiver: AccountId,
}

@hu55a1n1 hu55a1n1 mentioned this pull request Mar 22, 2022
7 tasks
@Wizdave97
Copy link
Contributor Author

I'll look into this and update it before Friday this week since the router has been merged.

@adizere
Copy link
Member

adizere commented Apr 5, 2022

Thanks David, once this is marked ready for review we'll shift some eyes on it again.

@Wizdave97 Wizdave97 force-pushed the david/ics-20-keeper-proposal branch from 7a57e18 to 71de87f Compare April 7, 2022 15:41
@Wizdave97
Copy link
Contributor Author

The call back handlers are meant to be called inside whatever is implementing the Module trait

@Wizdave97 Wizdave97 marked this pull request as ready for review April 7, 2022 16:06
@Wizdave97 Wizdave97 requested a review from hu55a1n1 April 7, 2022 16:12
@adizere adizere changed the title ICS20 Implementation Proposal ICS20 ADR Proposal Apr 11, 2022

}

pub trait ICS20Keeper: BankKeeper<Self::AccountId>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a general comment about the use of *Keeper and *Reader convention. We typically have *Reader traits all take &self as first argument, and *Keeper traits take &mut self. Could you make sure that this convention is followed throughout the ADR?

I also noticed that some of the functions don't have a &mut self but should, such as set_port().

}

pub trait ICS20Keeper: BankKeeper<Self::AccountId>
+ AccountKeeper<Self::AccountId>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AccountKeeper is never defined

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up. Let's clarify why is AccountKeeper necessary here.

/// Returns if receiving is allowed in the module params
fn is_receive_enabled(&self) -> bool;
/// Set the params (send_enabled and receive_enabled) for the module
fn set_module_params(send_enabled: Option<bool>, receive_enabled: Option<bool>) -> Result<(), ICS20Error>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

&mut self missing


/// sender_chain_is_source returns false if the denomination originally came
/// from the receiving chain and true otherwise.
fn sender_chain_is_source(source_port: &PortId, source_channel: &ChannelId, denom: String) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should combine sender_chain_is_source() and receiver_chain_is_source() into one get_source_chain() -> SourceChain (names TBD, please don't use those necessarily), where

enum SourceChain {
    Sender,
    Receiver,
}

This increases readability, as match statements will be used where both possibilities are made explicit, instead of being captured in an if/else statement.

...
}

impl Acknowledgement for ICS20Acknowledgement {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do Acknowledgement and GenericAcknowledgement refer to?

}

/// Returns the prefix for this trace
pub fn has_prefix(denom: String, prefix: String) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

denom and prefix should be &str. Same goes for all other functions in the ADR that take a String as input

}

/// Implements logic for refunding a sender on packet timeout or acknowledgement error
pub fn refund_packet_token<Ctx>(ctx: &Ctx, data: FungibleTokenPacketData) -> Result<(), ICS20Error>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be data: &FungibleTokenPacketData. This also applies to most other arguments in the ADR that are passed by value (e.g. all the PortId and ChannelId in ICS20Keeper).

@adizere adizere dismissed hu55a1n1’s stale review April 20, 2022 13:26

Please re-review

Copy link
Member

@adizere adizere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took the liberty to address some minor inconsistencies & issues.

@plafer and @hu55a1n1 is there anything outstanding in your opinion? Please have a final look and help ensure this PR gets resolved. Thank you!

}

pub trait ICS20Keeper: BankKeeper<Self::AccountId>
+ AccountKeeper<Self::AccountId>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Up. Let's clarify why is AccountKeeper necessary here.

Copy link
Member

@hu55a1n1 hu55a1n1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💮

Copy link
Contributor

@plafer plafer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, thank you for this @Wizdave97!

@hu55a1n1 hu55a1n1 merged commit 5e886ca into informalsystems:master Apr 22, 2022
@Wizdave97 Wizdave97 deleted the david/ics-20-keeper-proposal branch April 22, 2022 16:13
hu55a1n1 added a commit to hu55a1n1/hermes that referenced this pull request Sep 13, 2022
* create ics20 proposal

* enforce account id to implement string

* update proposal

* updated description

* updated proposal

* add proposal to table of contents

* updates

* pass values by reference

* Minor fixes

* More nits.

* Nites: Spaces for readability

* Rename

* Trimmed down content to its essentials.

Following sync code review with @hu55a1n1 and @plafer.

* Typo & date

* Fix formatting

* Use footnotes

* Document types

* Update trait definitions

* Fix code warnings

Co-authored-by: Adi Seredinschi <[email protected]>
Co-authored-by: Shoaib Ahmed <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ICS20 ADR Proposal
4 participants