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

Represent signer as a String and use account prefix from the config #711

Merged
merged 14 commits into from
Mar 11, 2021

Conversation

andynog
Copy link
Contributor

@andynog andynog commented Feb 24, 2021

Closes: cosmos/ibc-rs#88

Description

Major refactoring of signer logic to switch it from AccountId to Signer(String). Also includes logic to use the account_prefix from the config to use in the signer account (#635) so the transactions can be submitted to chains that don't use cosmos as the bech32 prefix.

NOTE: Currently there are 3 failing tests that might be related to this changes but I couldn't fix them yet, so just creating a draft PR for now to check if it also passes e2e test.


For contributor use:

  • Updated the Unreleased section of CHANGELOG.md with the issue.
  • If applicable: Unit tests written, added test to CI.
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Updated relevant documentation (docs/) and code comments.
  • Re-reviewed Files changed in the Github PR explorer.

@romac
Copy link
Member

romac commented Feb 25, 2021

Great stuff @andynog!

While I understand the need to represent the signer as a string rather than a fixed length byte array like AccountId, it would still be nice imho to introduce a wrapper over the String itself to not forfeit some type safety. For example, something like:

#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Signer(String);

@andynog
Copy link
Contributor Author

andynog commented Feb 25, 2021

Great stuff @andynog!

While I understand the need to represent the signer as a string rather than a fixed length byte array like AccountId, it would still be nice imho to introduce a wrapper over the String itself to not forfeit some type safety. For example, something like:

#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Signer(String);

Thanks @romac, just thinking should we use a [u8] or vec instead of string because the SDK has it as []byte in Go
https://github.com/cosmos/cosmos-sdk/blob/5d3f29b0898bc571bc60a1d53e1e8835f7fb89da/types/address.go#L101

@romac
Copy link
Member

romac commented Feb 25, 2021

Right, then yeah something like

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Signer(Vec<u8>);

impl Display for Signer {
  // use bech32 encoding
}

This then gives you to_string() and as_str() to get the bech32-encoded string version.

@andynog
Copy link
Contributor Author

andynog commented Feb 26, 2021

Right, then yeah something like

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Signer(Vec<u8>);

impl Display for Signer {
  // use bech32 encoding
}

This then gives you to_string() and as_str() to get the bech32-encoded string version.

@romac I've been looking into this suggestion to wrap the String but the more I look on all the traits that would need to be implemented the more I think it will look like the AccountId from tendermint-rs that we had before except for the LENGTH constraint.

In the end, the signer basically is retrieved from the address property of the KeyEntry and it's a Vec<u8> that is later encoded to bech-32 when get_signer is called. If the String is not in a proper format for bech32 encoding will fail. So not sure if not just leaving it as a string if in the msgs if that should not be OK for now.

@ancazamfir
Copy link
Collaborator

ancazamfir commented Mar 3, 2021

Trying to follow this, why can't we leave it as String for now? This is how it shows in the raw protocol messages. We should not use any Tendermint AccountId in the ibc crate. Or make any assumptions that we are dealing with an SDK account. All that should be dealt with in the chain impl when we send the messages which are serialized with protobufs so they must be String.
Can still use the wrapper in the domain type messages

#[derive(Clone, Debug, Display, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Signer(String);

but it is not clear to me what we gain as we should never look at signer or make any assumptions about it.

modules/src/address.rs Outdated Show resolved Hide resolved
@romac
Copy link
Member

romac commented Mar 3, 2021

@andynog @ancazamfir Yeah good points! So let's represent it as a String wrapped in a Signer newtype, which we decode from the byte array in CosmosSdkChain::get_signer.

@romac romac changed the title Andy/acct prefix Represent signer as a String and use account prefix from the config Mar 4, 2021
@codecov-io
Copy link

Codecov Report

Merging #711 (fa38d3a) into master (b1b37f5) will increase coverage by 30.5%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    informalsystems/hermes#711      +/-   ##
=========================================
+ Coverage    13.6%   44.1%   +30.5%     
=========================================
  Files          69     156      +87     
  Lines        3752   10288    +6536     
  Branches     1374       0    -1374     
=========================================
+ Hits          513    4546    +4033     
- Misses       2618    5742    +3124     
+ Partials      621       0     -621     
Impacted Files Coverage Δ
...application/ics20_fungible_token_transfer/error.rs 0.0% <ø> (ø)
...ion/ics20_fungible_token_transfer/msgs/transfer.rs 0.0% <ø> (ø)
..._transfer/relay_application_logic/send_transfer.rs 0.0% <ø> (ø)
modules/src/events.rs 0.0% <ø> (ø)
modules/src/handler.rs 100.0% <ø> (ø)
modules/src/ics02_client/client_def.rs 47.3% <ø> (ø)
modules/src/ics02_client/client_type.rs 79.1% <ø> (+31.5%) ⬆️
modules/src/ics02_client/context.rs 100.0% <ø> (ø)
modules/src/ics02_client/error.rs 100.0% <ø> (ø)
modules/src/ics02_client/events.rs 15.7% <ø> (+15.7%) ⬆️
... and 259 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bfd3d8e...fa38d3a. Read the comment docs.

@romac romac marked this pull request as ready for review March 10, 2021 14:30
@romac romac self-requested a review as a code owner March 10, 2021 14:30
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.

This is great work, things are a lot cleaner!

I only left one comment worth discussing: the lock file which seems added by accident.

@@ -30,8 +29,8 @@ pub struct MsgConnectionOpenTry {
pub counterparty: Counterparty,
pub counterparty_versions: Vec<Version>,
pub proofs: Proofs,
pub delay_period: u64,
pub signer: AccountId,
pub delay_period: u64, // FIXME(romac): Introduce newtype for `delay_period`
Copy link
Member

Choose a reason for hiding this comment

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

Yus! Probably the todo should be fixed alongside #640.

@@ -18,22 +18,23 @@ pub const TYPE_URL: &str = "/ibc.core.channel.v1.MsgRecvPacket";
#[derive(Clone, Debug, PartialEq)]
pub struct MsgRecvPacket {
pub packet: Packet,
proofs: Proofs,
signer: AccountId,
pub proofs: Proofs,
Copy link
Member

Choose a reason for hiding this comment

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

@cezarad FYI the diff hunks here. As soon as we merge the present PR, your PR on recv_packet (#737) will need to be adapted.

fn get_signers(&self) -> Vec<AccountId>;
fn get_sign_bytes(self) -> Vec<u8> {
let mut buf = Vec::new();
let raw_msg: Self::Raw = self.into();
Copy link
Member

Choose a reason for hiding this comment

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

Hmm interesting that we're now avoiding a clone here. It used to be let raw_msg: M = self.clone().into();. Perhaps cloning is no longer necessary because we're not using generics anymore?

Later edit: I now see that we're consuming self in the call to to_any and get_sign_bytes, which explains the lack of cloning.

proto-compiler/Cargo.lock Outdated Show resolved Hide resolved
@romac romac requested a review from adizere March 11, 2021 10:02
Copy link
Collaborator

@ancazamfir ancazamfir left a comment

Choose a reason for hiding this comment

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

Looks good! Thanks a lot @andynog and @romac!!

@adizere adizere merged commit 9c0c5d6 into master Mar 11, 2021
@adizere adizere deleted the andy/acct_prefix branch March 11, 2021 12:29
hu55a1n1 pushed a commit to hu55a1n1/hermes that referenced this pull request Sep 13, 2022
…nformalsystems#711)

* Refactoring of signer from AccountId into String (informalsystems#219)

* Logic to add the account_prefix from config to signer (informalsystems#219)

* Uncomment tests that are failing

* Move bech32 encoding of accounts to cosmos chain impl

* Use a newtype for the signer

* Allow empty signer in tests

* Add plain constructor to all ICS04 messages

* Remove default implementation of Msg::type_url

* Use associated type on Msg trait instead of type parameter on Msg::to_any

* Formatting

* Remove proto-compiler lockfile

Co-authored-by: Romain Ruetschi <romain@informal.systems>
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.

Cannot submit a tx on a chain that has a Bech32 prefix other than "cosmos"
5 participants