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

fix(ics20): PrefixedDenom parsing #1178

Merged
merged 52 commits into from
Apr 26, 2024
Merged

Conversation

rnbguy
Copy link
Collaborator

@rnbguy rnbguy commented Apr 19, 2024

Closes: #1177

Description


PR author checklist:

  • Added changelog entry, using unclog.
  • Added tests.
  • Linked to GitHub issue.
  • Updated code comments and documentation (e.g., docs/).
  • Tagged one reviewer who will be the one responsible for shepherding this PR.

Reviewer checklist:

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

@rnbguy
Copy link
Collaborator Author

rnbguy commented Apr 19, 2024

I added the client validation logic. But now, the question remains - what happens in the following cases:

assert!(PrefixedDenom::from_str("/uatom").is_err(), "empty prefix");
assert!(PrefixedDenom::from_str("//uatom").is_err(), "empty ids");
assert!(
PrefixedDenom::from_str("transfer/").is_err(),
"single trace"
);
assert!(
PrefixedDenom::from_str("transfer/atom").is_err(),
"single trace with base denom"
);

Note the following are valid cases in this PR:

#[case(
"transfer/channel-75",
"factory/stars16da2uus9zrsy83h23ur42v3lglg5rmyrpqnju4/dust"
)]
#[case(
"transfer/channel-75/transfer/channel-123/transfer/channel-1023/transfer/channel-0",
"factory/stars16da2uus9zrsy83h23ur42v3lglg5rmyrpqnju4/dust"
)]
#[case(
"transfer/channel-75/transfer/channel-123/transfer/channel-1023/transfer/channel-0",
"//////////////////////dust"
)]

Update: looks like ibc-go accepts them.

Copy link

codecov bot commented Apr 19, 2024

Codecov Report

Attention: Patch coverage is 96.69421% with 4 lines in your changes are missing coverage. Please review.

Project coverage is 64.34%. Comparing base (cdf6cf5) to head (6f3eddb).

❗ Current head 6f3eddb differs from pull request most recent head 53fad12. Consider uploading reports for the commit 53fad12 to get more accurate results

Files Patch % Lines
ibc-apps/ics721-nft-transfer/types/src/class.rs 84.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1178      +/-   ##
==========================================
- Coverage   64.40%   64.34%   -0.06%     
==========================================
  Files         229      229              
  Lines       22109    22005     -104     
==========================================
- Hits        14240    14160      -80     
+ Misses       7869     7845      -24     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@rnbguy rnbguy marked this pull request as ready for review April 19, 2024 19:51
Copy link
Contributor

@seanchen1991 seanchen1991 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 for the most part. Would be great if we could add a docstring of the PrefixedDenom::from_str implementation. Feel free to use my suggested description or write a different one.

@@ -294,18 +301,34 @@ impl FromStr for PrefixedDenom {
type Err = TokenTransferError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be helpful to add a description of the logic of this from_str implementation, as it's a little bit convoluted. Here's a suggestion:

/// Initializes a `PrefixedDenom` from a string that adheres to the format
/// `{port-id-1/channel-id-1}/{port-id-2/channel-id-2}/.../{port-id-n/channel-id-n}/base-denom`.
/// A `PrefixedDenom` exhibits between 1..n number of `{port-id/channel-id}` pairs.
/// The set of these pairs makes up the `TracePath`.
///
/// This `from_str` implementation peeks the first two segments split on the `/`
/// delimiter and attempts to convert the first segment into a `PortId` and the 
/// second segment into a `ChannelId`. This continues in a loop until a 
/// `{port-id/channel-id}` pair cannot be created from the top two segments. 
/// The remaining parts of the string are then considered the `BaseDenom`.
///
/// For example, given the following denom trace:
/// "transfer/channel-75/factory/stars16da2uus9zrsy83h23ur42v3lglg5rmyrpqnju4/dust",
/// the first two `/`-delimited segments are `"transfer"` and `"channel-75"`. The
/// first is a valid `PortId` and the second is a valid `ChannelId`, so that becomes
/// the first `{port-id/channel-id}` pair that gets added as part of the `TracePath`
/// of the `PrefixedDenom`. The next two segments are `"factory"`, which is not a
/// valid `PortId`, and `"stars16da2uus9zrsy83h23ur42v3lglg5rmyrpqnju4"`, which is
/// not a valid `ChannelId`. The loop breaks at this point, resulting in a
/// `TracePath` of `"transfer/channel-75"` and a `BaseDenom` of
/// `"factory/stars16da2uus9zrsy83h23ur42v3lglg5rmyrpqnju4/dust"`.

Feel free to edit the above to make the description more clear.

Copy link
Member

Choose a reason for hiding this comment

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

I agree with Sean. The above description helps a lot. Great.

The next two segments are "factory", which is not a valid PortId

Just a small note: "factory" is a valid PortId.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Member

@Farhad-Shabani Farhad-Shabani left a comment

Choose a reason for hiding this comment

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

Thanks @rnbguy for getting into the details! The tests are fantastic.
I have a few suggestions and nitpicks, but overall, everything looks great.

@Farhad-Shabani Farhad-Shabani added this to the 0.52.0 milestone Apr 20, 2024
Co-authored-by: Sean Chen <[email protected]>
Co-authored-by: Farhad Shabani <[email protected]>
Signed-off-by: Rano | Ranadeep <[email protected]>
@seanchen1991
Copy link
Contributor

do you think it makes sense to include the same changes, needed for ics-721, in this PR?

I'm fine either way. If we want to include the ics-721 changes in this PR, then go ahead 👍

ibc-apps/ics20-transfer/types/src/denom.rs Outdated Show resolved Hide resolved
ibc-apps/ics20-transfer/types/src/denom.rs Outdated Show resolved Hide resolved
ibc-apps/ics20-transfer/types/src/denom.rs Outdated Show resolved Hide resolved
ibc-apps/ics20-transfer/types/src/denom.rs Outdated Show resolved Hide resolved
ibc-apps/ics20-transfer/types/src/denom.rs Outdated Show resolved Hide resolved
ibc-apps/ics20-transfer/types/src/denom.rs Outdated Show resolved Hide resolved
@rnbguy rnbguy force-pushed the rano/fix/parsing-prefixed-denom branch from 8a3996f to 736d4a1 Compare April 24, 2024 13:05
@rnbguy
Copy link
Collaborator Author

rnbguy commented Apr 25, 2024

hey @seanchen1991, in recent commits, I added ibc-app-transfer-types dependency to ibc-app-nft-transfer-types and reused TracePath and TracePrefix implementations.

I also updated the algorithm subtly - to handle another incorrect parsing (7408994).

Copy link
Contributor

@seanchen1991 seanchen1991 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 to merge 👍

@rnbguy rnbguy dismissed Farhad-Shabani’s stale review April 26, 2024 15:46

Farhad is on leave and the fix is on 53fad12 .

@rnbguy rnbguy added this pull request to the merge queue Apr 26, 2024
Merged via the queue into main with commit e5c626f Apr 26, 2024
17 checks passed
@rnbguy rnbguy deleted the rano/fix/parsing-prefixed-denom branch April 26, 2024 15:47
Farhad-Shabani added a commit that referenced this pull request Sep 9, 2024
* add failing test

* add TracePath::new

* imp PrefixedDenom parsing

* add validate_named_u64_index

* validate_named_u64_index in channel and connection validation

* add tests for validate_named_u64_index

* update PrefixDenom parsing tests

* update accepted cases in ibc-go

* update accepted cases

* add test cases from ibc-go

* use valid connection id

* failing doc tests

* use existing constants

* changelog entry

* refactor tests

* apply suggestions from code review

Co-authored-by: Sean Chen <[email protected]>
Co-authored-by: Farhad Shabani <[email protected]>
Signed-off-by: Rano | Ranadeep <[email protected]>

* add comment for PrefixedDenom::from_str

* rm TracePath::new

* collect the same tests

* test parsed PrefixedDenom string repr

* test trace order

* more tests

* update tests

* rm redundant error variant

* refactor tests

* update doc string

* add comment on virtual split_twice

* update doc str

* add TracePrefix::strip and TracePath::trim

* add whitespace cases

* refactor tests

* spelling

* parse over from_str

* nit

* apply suggestions from code review

Co-authored-by: Sean Chen <[email protected]>
Signed-off-by: Rano | Ranadeep <[email protected]>

* add failing test

* fix TracePath::from_str

* fix parsing

* fix test

* add ibc-app-transfer-types dep

* rm reusable code

* update impls

* update tests

* accepted class ids

* refactor tests

* update changelog entry

* opt trace prefix and path parsing

* add new tests

* Update changelog entry

* fix trace-prefix index order

---------

Signed-off-by: Rano | Ranadeep <[email protected]>
Co-authored-by: Sean Chen <[email protected]>
Co-authored-by: Farhad Shabani <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

bug(ics20): PrefixedDenom is parsed with invalid ChannelId
4 participants