-
Notifications
You must be signed in to change notification settings - Fork 224
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
What's the purpose of tendermint::Time
?
#865
Comments
All right, so if I understand correctly, you're advocating for getting rid of tendermint::Time in lieu of tendermint_proto::Timestamp since there's no real added value. So far, looking at the code I found that
Apart from checking out the JSON serialization I didn't find any other reason why this wouldn't be feasible to do. I'm going to play around with serialization and then attempt to implement this and see what happens. We might just end up with simpler code. |
Just confirmed, tendermint::Time is falling back to tendermint_proto::Timestamp for serialization. No issues there. |
tendermint::Time has a lot of little convenience functions, like We could add these to tendermint_proto so it can be easily reused, but it still requires a new crate to be imported to access these functions. Or we could keep tendermint::Time around with a deprecation warning for a release cycle to get feedback from the downstream projects. Even if we do this, I'd rewrite these convenience functions to call into tendermint_proto so downstream projects have an example on how to do it after these functions go away. I'd be happy to hear additional ideas and opinions before I sink my teeth too much into it. |
No, sorry for being unclear, I'd rather use the
I'd prefer not to use the raw proto types except for cases that really need to care about proto serialization specifically. |
Huh, ok, that's interesting. If you want to use it directly, there's no way to add additional functionality to it, like convenient protobuf-encoding/decoding or JSON serialization/deserialization. As Tony mentioned in the Signal discussion, the newtype I would like to entertain the idea but I can't yet imagine how it would work. We rip out Now, let's look at JSON-serialization. (I'm not going to repeat the blog entry I sent on Signal :) ). I went through the structs with a struct-analyzer and saw that most structs either use a RawType already (like There is one place where this happens: the Genesis JSON serialization is used in (at least) two places: In the RPC So, yeah, I think I can entertain this idea. :) I'd be happy to hear others' opinions. |
I don't think this is quite true, it's possible to monkey-patch additional functionality onto third-party types using extension traits. The downside of this is that the user has to import the extension trait, but the upside is that they maintain access to all of the original API. In contrast, wrapping a struct to add functionality requires either removing access to the original API, making the user jump through a hoop to get it (conversions), or reimplementing it. That said, in terms of the concrete functionality you mentioned:
All the
I guess my feeling here is that, for all of the types that have an associated proto, there's already a generated proto type, so the Serde annotations that define the exact shape of the JSON output would be best defined on the proto type, so that there's only one place in the code that's defining the serialization. For structures that don't have a corresponding proto, like apparently the |
In #1030, I'm steering A case can be made for For serde, I should write these and a few other ideas up in an ADR, probably some time next week. |
Is there actually a performance issue using EDIT: looking at the |
@hdevalence For adding or subtracting a Memory efficiency is another matter. The parsed time struct can fit into 12 bytes with the alignment of 4. A timestamp can be broken down to an So the choice of internal representation depends on the optimization priorities for users of the |
Filed an ADR: #1035 |
The
tendermint
crate has aTime(DateTime<Utc>)
structure that wraps thechrono::DateTime<Utc>
type and implements a bunch of custom methods for it.Currently in #862, I translated the Protobuf
Timestamp
type directly to aDateTime<Utc>
, which I think is a more ergonomic type for downstream users and would prefer to use, unless there is a reason not to use it.I wasn't sure from reading the documentation what the purpose of the custom time type was, but I didn't see an explanation of how it differs from a
DateTime<Utc>
. BecauseTime
hasimpl From<DateTime<Utc>> for Time
, thetendermint
crate's public API is still locked tochrono
0.4
, and becauseFrom
impls are infallible, there's no way for theTime
type to enforce any additional invariants on aDateTime<Utc>
. So I'm not sure that there's really a meaningful encapsulation benefit.Another possible motivation could be for use with JSON serialization -- from looking at the commit history, it seemed like there was a bug involved in the custom serialization (#775). It's easy to add custom serialization to a newtype wrapper compared to a third party type. But if this was the motivation, an alternative that doesn't involve creating and maintaining a new type could be to define JSON serialization on the
tendermint_proto
structs, rather than on all of the domain types, and use theFrom
/TryFrom
impls to apply that serialization to the domain types.The text was updated successfully, but these errors were encountered: