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

Option type should be used with non-zero Height #1009

Closed
5 tasks
soareschen opened this issue May 27, 2021 · 9 comments
Closed
5 tasks

Option type should be used with non-zero Height #1009

soareschen opened this issue May 27, 2021 · 9 comments
Assignees
Labels
A: good-first-issue Admin: good for newcomers O: code-hygiene Objective: cause to improve code hygiene
Milestone

Comments

@soareschen
Copy link
Contributor

Crate

ibc-rs

Summary

Currently the Height type uses a special Height::zero() value to denote the absence of height value. This causes ad hoc checks of whether a height is zero in various places. We should instead use Option<Height> on places where the height value may be optional, and require non-zero value in the Height constructor.

Acceptance Criteria

  • Optional height parameters should use Option<Height> instead of Height.
  • Checking of height == Height::zero() is replaced with Option matching.

For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate milestone (priority) applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned
@adizere adizere added O: code-hygiene Objective: cause to improve code hygiene A: good-first-issue Admin: good for newcomers labels May 28, 2021
@adizere adizere added this to the 06.2021 milestone May 28, 2021
@adizere adizere modified the milestones: 06.2021, 08.2021 Jun 7, 2021
@adizere adizere modified the milestones: 08.2021, 10.2021 Aug 3, 2021
@adizere adizere modified the milestones: 10.2021, 12.2021 Sep 30, 2021
@plafer
Copy link
Contributor

plafer commented Mar 11, 2022

My only potential concern with this solution is that our Height type would no longer be a partially ordered set due to the exclusion of 0, which is required in ICS 2. Here, I'm assuming that None serves as 0, and Option<Height> would correspond to Height in the spec, assuming a proper implementation for cmp().

However, looking at the code, the zero height is often used as a special value, sometimes even explicitly mentioned in comments. This is confusing to me as I don't see any mention in the spec that the zero height should be treated differently.

What am I missing here? I definitely agree that Option<Height> + pattern matching should be used for treating the special case. However, I'm concerned that we might be introducing a bug w.r.t a "real" height == 0 state, since I don't understand how the zero height is used in the implementation, and how that relates back to the spec.

@hu55a1n1
Copy link
Member

Note that Height::zero() can also mean latest height, especially in the context of Tendermint RPC -> https://docs.tendermint.com/master/rpc/#/Info/block

@romac
Copy link
Member

romac commented Mar 14, 2022

We should perhaps encode this across the whole codebase as

enum Height {
  Latest,
  Specific(u64)
}

and then only convert Height::Latest to 0 or None on a case-by-case basis, depending on what the underlying API expects to mean "latest height".

@adizere adizere modified the milestones: v1.0.0, v0.14.0 Mar 15, 2022
@plafer
Copy link
Contributor

plafer commented Mar 29, 2022

It seems like a bunch of events use the zero height as well:

  1. IbcEvent::OpenInitChannel, IbcEvent::OpenTryChannel, etc. use the zero height implicitly by being constructed with default values for all fields but the channel id.
  2. IbcEvent::ReceivePacket is constructed with Height::zero() explicitly, which @adizere suggested should be replaced with current chain height.

It seems to me that these should all use chain height from ChannelReader::host_height(), right?

@romac
Copy link
Member

romac commented Mar 30, 2022

It seems to me that these should all use chain height from ChannelReader::host_height(), right?

Yep, at least that's my understanding. @hu55a1n1 what do you think?

Moreover, we should stop building events via the Attributes struct and its Default instance, but rather

a) define explicitly what data each event carry in the event struct directly
b) use a constructor to build the event

We are already doing (a) for the channel events but eg. not for the connection events.

@soareschen
Copy link
Contributor Author

For context, I tried to solve this by implementing a NonZeroHeight type here in #1011.

The plan was to split the refactoring in multiple phases:

  1. All places that originally used Height do not need to be edited to become Option<Height>.
  2. We can incrementally refactor functions that accept Height to instead use NonZeroHeight.
  3. After all use of Height are eliminated, we can remove Height and then rename NonZeroHeight to Height.

@hu55a1n1
Copy link
Member

hu55a1n1 commented Mar 31, 2022

Yep, at least that's my understanding. @hu55a1n1 what do you think?

It is not clear to me what the event height means from the modules' perspective, because it seems like ibc-go doesn't include a height attribute in the events that it emits. From what I can see, the height is only used by the relayer code to determine the height of the block which included the tx that emitted this event. So I am not sure if we want to keep the height as part of the IbcEvent itself. Furthermore, the event height is only set by the relayer code that deals with events. We also have Tendermint RPC event variants in the IbcEvent enum and maybe we should separate them from core IBC events in the future. (Related #1288 & #1909)

Moreover, we should stop building events via the Attributes struct and its Default instance, but rather
a) define explicitly what data each event carry in the event struct directly
b) use a constructor to build the event

💯

@plafer
Copy link
Contributor

plafer commented Apr 1, 2022

Yep, at least that's my understanding. @hu55a1n1 what do you think?

It is not clear to me what the event height means from the modules' perspective, because it seems like ibc-go doesn't include a height attribute in the events that it emits. From what I can see, the height is only used by the relayer code to determine the height of the block which included the tx that emitted this event. So I am not sure if we want to keep the height as part of the IbcEvent itself. Furthermore, the event height is only set by the relayer code that deals with events. We also have Tendermint RPC event variants in the IbcEvent enum and maybe we should separate them from core IBC events in the future. (Related #1288 & #1909)

Moreover, we should stop building events via the Attributes struct and its Default instance, but rather
a) define explicitly what data each event carry in the event struct directly
b) use a constructor to build the event

💯

Discussion relevant to #2043

@plafer
Copy link
Contributor

plafer commented Apr 8, 2022

FYI I'll wait on #2044 to be merged before I start working on this one to avoid merge conflicts.

@adizere adizere modified the milestones: v0.14.0, v0.15.0 Apr 25, 2022
@adizere adizere removed this from the v0.15.0 milestone May 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A: good-first-issue Admin: good for newcomers O: code-hygiene Objective: cause to improve code hygiene
Projects
No open projects
Status: Closed
Development

No branches or pull requests

5 participants