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

imp!: define helper trait for Timestamp conversions + update ConsensusState::timestamp() to return Result #1353

Merged
merged 5 commits into from
Sep 26, 2024

Conversation

Farhad-Shabani
Copy link
Member

@Farhad-Shabani Farhad-Shabani commented Sep 24, 2024

Closes: #1352
Closes: #1323


PR author checklist:

  • Added changelog entry, using unclog.
  • 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).

@Farhad-Shabani Farhad-Shabani added this to the 0.55.0 milestone Sep 24, 2024
Copy link

codecov bot commented Sep 24, 2024

Codecov Report

Attention: Patch coverage is 84.21053% with 6 lines in your changes missing coverage. Please review.

Project coverage is 66.85%. Comparing base (ede380f) to head (4f11258).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
ibc-primitives/src/types/timestamp.rs 70.00% 3 Missing ⚠️
ibc-clients/ics07-tendermint/types/src/header.rs 0.00% 2 Missing ⚠️
ibc-testkit/src/hosts/tendermint.rs 66.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1353      +/-   ##
==========================================
+ Coverage   66.76%   66.85%   +0.08%     
==========================================
  Files         225      225              
  Lines       22614    22628      +14     
==========================================
+ Hits        15098    15127      +29     
+ Misses       7516     7501      -15     

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

Comment on lines +186 to 216
/// Utility trait for converting a `Timestamp` into a host-specific time format.
pub trait IntoHostTime<T: Sized> {
/// Converts a `Timestamp` into another time representation of type `T`.
///
/// This method adapts the `Timestamp` to a domain-specific format, which
/// could represent a custom timestamp used by a light client, or any
/// hosting environment that requires its own time format.
fn into_host_time(self) -> Result<T, TimestampError>;
}

/// Utility trait for converting an arbitrary host-specific time format into a
/// `Timestamp`.
pub trait IntoTimestamp {
/// Converts a time representation of type `T` back into a `Timestamp`.
///
/// This can be used to convert from custom light client or host time
/// formats back into the standard `Timestamp` format.
fn into_timestamp(self) -> Result<Timestamp, TimestampError>;
}

impl<T: TryFrom<OffsetDateTime>> IntoHostTime<T> for Timestamp {
fn into_host_time(self) -> Result<T, TimestampError> {
T::try_from(self.into()).map_err(|_| TimestampError::InvalidDate)
}
}

fn try_from(tm_time: Time) -> Result<Self, Self::Error> {
let odt: OffsetDateTime = tm_time.into();
odt.try_into()
impl<T: Into<OffsetDateTime>> IntoTimestamp for T {
fn into_timestamp(self) -> Result<Timestamp, TimestampError> {
Timestamp::try_from(self.into())
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Am I correct to understand, these helper traits with auto-impls only reduce extra function calls and imports ?

Copy link
Member Author

Choose a reason for hiding this comment

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

That’s one benefit. But more importantly it removes tendermint dependency in ibc_primitives. This fits with the plan to completely decouple the ibc-rs core stack from the tendermint.

It also makes things easier for light client developers or integrators. By implementing these traits, they can smoother convert their own time type to Timestamp wherever ibc-rs asks for, or reconstruct their types from ibc-rs’s Timestamp if needed.

Copy link
Collaborator

@rnbguy rnbguy Sep 25, 2024

Choose a reason for hiding this comment

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

I meant whether these traits are just syntactic sugars. Because, the developers could also just use T::try_from(OffsetDateTime::from(ibc_timestamp)) instead of ibc_timestamp.into_host_time() and Timestamp::try_from(OffsetDateTime::from(host_timestamp)) instead of host_timestamp.into_timestamp().

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, I get what you mean now. It’s not quite that way.
We can't really assume the structure of a time type across different hosts or what conversions they use. They might not even be using OffsetDateTime. So, I added default implementations for any time type that follows this conversion path, just for convenience. As it's the case with tendermint::Time. But this won’t necessarily apply to other timestamp types in different ConsensusState structs.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm. I am trying to understand, why would user need these two helper traits?

It seems to me, for a struct HostTime, they can just implement impl TryFrom<Timestamp> for HostTime and impl TryFrom<HostTime> for Timestamp.

We can just use the trait bounds as TryFrom<Timestamp> and TryFrom<HostTime> appropriately in ibc-rs.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Basically, IntoHostTime<T> is equivalent to TryInto<T> and IntoTimestamp is equivalent to TryInto<Timestamp>.

Copy link
Member Author

Choose a reason for hiding this comment

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

Basically, IntoHostTime<T> is equivalent to TryInto<T> and IntoTimestamp is equivalent to TryInto<Timestamp>.

Totally, this works too. But if a host has multiple TryFrom<HostTime> implementations, which usually can be the case, the consumer would need to specify the exact type and use the full path. Can’t simply call try_from or try_into on the time object. Plus, as you mentioned, this would definitely benefit from being syntactic sugar, making it more readable and easier to work with.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yea. I am ok with this. Thanks, Farhad, for explaining.

Copy link
Collaborator

@rnbguy rnbguy left a comment

Choose a reason for hiding this comment

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

LGTM ✨ I will let you decide on the helper traits.

@Farhad-Shabani Farhad-Shabani added this pull request to the merge queue Sep 26, 2024
Merged via the queue into main with commit 1a9690e Sep 26, 2024
14 checks passed
@Farhad-Shabani Farhad-Shabani deleted the farhad/timestamp-to-from-host-time branch September 26, 2024 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
2 participants