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

Proposal for redesigning parts of the ibc-rs modules' API #25

Closed
9 of 20 tasks
hu55a1n1 opened this issue Dec 20, 2021 · 3 comments
Closed
9 of 20 tasks

Proposal for redesigning parts of the ibc-rs modules' API #25

hu55a1n1 opened this issue Dec 20, 2021 · 3 comments
Assignees
Labels
O: logic Objective: aims for better implementation logic

Comments

@hu55a1n1
Copy link
Contributor

hu55a1n1 commented Dec 20, 2021

Crate

ibc

Proposal

Following is a list of ideas for redesigning parts of our ibc-rs modules' API accompanied with some reasoning for why these changes are required. (Some of these have already been implemented in PR informalsystems/hermes#1583.)
This is meant to serve as a meta issue for tracking these design changes. Might make sense to defer this until we start implementing another client (i.e. substrate, etc.) ->

 // change this ->
 pub struct Proofs {
    object_proof: CommitmentProofBytes,
    client_proof: Option<CommitmentProofBytes>,
    consensus_proof: Option<ConsensusProof>,
    other_proof: Option<CommitmentProofBytes>,
    height: Height,
}

// to something like this -> 
pub enum Proofs {
    ChannelOpenTry(ChannelOpenTryProof), 
    // ...
}

// or maybe this -> 
pub struct SimpleProof(CommitmentProofBytes);
pub struct ComplexProof {
    pub proof: CommitmentProofBytes, 
    pub consensus_proof: ConsensusProof,
    // ...
}

pub enum Proofs {
    ConnectionOpenTry(ComplexProof), 
    ChannelOpenTry(SimpleProof), 
    // ...
}
  • ics24_host::Path variants as types - Since Rust doesn't treat enum variants as types, it might be a good idea to extract these variants as distinct types and use those types as the actual enum variants. This will allow us to enforce that certain functions accept only a certain type of path. eg. verify_client_consensus_state() should only accept a Path::ClientConsensusState. (ICS24 Path variants as types informalsystems/hermes#1760)
  • Follow RFC-356-no-module-prefixes. This basically means we rename ibc::core::ics04_channel::msgs::MsgChannelCloseConfirm to ibc::core::ics04_channel::msgs::ChannelCloseConfirm, and either re-export it as MsgChannelCloseConfirm in msgs.rs or add it to the prelude.
  • Public structs should either have public fields or setters/getters (if required), but not both. e.g.
pub struct MsgChannelCloseInit {
    pub port_id: PortId, // <- public
    // ...
}

impl MsgChannelCloseInit {
	pub fn port_id(&self) -> &PortId {
        &self.port_id
    } // <- also has a getter
}
  • Add ParamsReader trait to allow users to get host genesis params like MaxExpectedTimePerBlock. Prefer composition over inheritance (where possible) ->
fn handler<CR: ConnectionReader, PR: ParamsReader>(
  connection_reader: CR,
  params_reader: PR,
  ...
) {}
  • Remove &dyn in trait methods.
  • Errors returned by *Reader trait methods must match API. e.g. ChannelReader::client_state() is usually just a proxy to ClientReader::client_state(), so it doesn't make sense for it to return a ChannelError ->
pub trait ChannelReader {
    fn client_state(&self, client_id: &ClientId) -> Result<AnyClientState, ics04_channel::error::Error>;
    // ...
}
  • Super-traits - There is significant overlap in the various *Reader trait methods, so it might make sense to use inheritance here ->
pub trait ClientReader {}
pub trait ConnectionReader: ClientReader {}
pub trait ChannelReader: ConnectionReader {}
  • Provide verification functions with everything they need and don't give them access to the *Reader contexts. (this may not be feasible due to methods like check_header_and_update_state() requiring access to ctx.next_consensus_state()) The other extreme is to only give verification functions such contexts and allow them to extract everything they need them.
  • ChannelReader::hash() accepts input as (and returns) a String.
pub trait ChannelReader {
    fn hash(&self, value: String) -> String;
}

The method should ideally take a Vec<u8> as input and return a Digest type that is fixed per client. So maybe something like ->

pub trait ChannelReader {
	type Digest: AsRef<&[u8]>;

    fn hash(&self, value: Vec<u8>) -> Self::Digest;
}

Or maybe this should be part of ClientReader?

PS: Thanks to @romac for his valuable insights and suggestions!


For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate milestone (priority) applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned
@mzabaluev
Copy link
Contributor

pub enum Proofs {
    ChannelOpenTry(ChannelOpenTryProof), 
    // ...
}

Bikeshedding:
Does this type mean "all proofs supplied with (necessary for?) this request"?
The variant names suggest that each case can be thought of a singular "proof", and in this case the enum should probably be named Proof.

// or maybe this -> 
pub struct SimpleProof(CommitmentProofBytes);
pub struct ComplexProof {
    pub proof: CommitmentProofBytes, 
    pub consensus_proof: ConsensusProof,
    // ...
}

pub enum Proofs {
    ConnectionOpenTry(ComplexProof), 
    ChannelOpenTry(SimpleProof), 
    // ...
}

Could be, but then a convenience accessor may be needed to get at the commitment proof in all variants where it's available:

impl Proofs {
    pub fn commitment(&self) -> Option<&CommitmentProofBytes> {
        todo!()
    }
}

If there may be benefit in type-checking the proof variants in particular places where only such a variant is meaningful, they each should get their own dedicated type, to be used instead of matching a dynamically multiplexed Proofs value and asserting. This is similar to @hu55a1n1's suggestion for ics24_host::Path

@hu55a1n1 hu55a1n1 self-assigned this Dec 22, 2021
@hu55a1n1 hu55a1n1 transferred this issue from informalsystems/hermes Sep 28, 2022
@plafer plafer mentioned this issue Oct 12, 2022
8 tasks
@Farhad-Shabani Farhad-Shabani added the O: logic Objective: aims for better implementation logic label Jan 5, 2023
@Farhad-Shabani
Copy link
Member

For the remained tasks in this ticket, issues that still make sense are opened (#532, #534, #537). This is done as a pre-work before preparing the "Road to IBC-rs V1".
@plafer Can you please recheck the list to make sure I didn't miss anything before closing the issue?

@plafer
Copy link
Contributor

plafer commented Mar 15, 2023

LGTM

@plafer plafer closed this as completed Mar 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O: logic Objective: aims for better implementation logic
Projects
Status: Done
Development

No branches or pull requests

4 participants