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

Rebase ABCI Domain Types onto v0.34.20 branch. #1185

Closed

Conversation

hdevalence
Copy link
Collaborator

@hdevalence hdevalence commented Aug 17, 2022

After a second round of rebasing:

  • The original ABCI domain types work used chrono; this temporarily re-adds
    chrono as a dependency, so that the changes that eliminated it can be
    replayed on top of this rebasing.

  • The original ABCI domain types work was, for some reason, mixed in with
    changes to the RPC test harness for 0.35 compatibility, and that may break
    this code. I didn't attempt to fix this, because I didn't touch the RPC tests
    when writing the ABCI domain types.

  • The RPC tests don't pass, for reasons that are unclear to me. I split the changes to the RPC code into ones that seemed relevant to the ABCI vendoring and the changes for 0.35 compatibility. The changes for 0.35 compatibility, which are not contained in this PR, are here, for reference: penumbra-zone@46bf130

@hdevalence hdevalence force-pushed the abci-domain-types-on-034 branch 2 times, most recently from 3a318ed to 7b414c2 Compare August 18, 2022 00:24
hdevalence and others added 9 commits September 20, 2022 15:24
Replace chrono with time 0.3 (informalsystems#1030)

* pbt-gen: Converted from chrono to time 0.3

chrono has soundness issues (see RUSTSEC-2020-0159) and does not
seem to be maintained.

* Replace dependency on chrono with time 0.3

Change Time implementation to crate time: chrono has soundness issues
(see RUSTSEC-2020-0159) and does not seem to be actively maintained.

* Add Time methods checked_add and checked_sub

These should be used instead of the overloaded operators that broke
the operator convention by returning a Result.

* proto: Don't use formatting methods of time

Drop the "formatting" feature of time, as this brings in std.

* pbt-gen: Add arb_datetime_for_rfc3339

With crate time, the range of supported dates stretches to the ancient
past beyond the common era, which is not representable in RFC 3339.
Add a generator to produce `OffsetDateTime` values that are
within the RFC 3339 spec.

* Ensure Time can only have values good for RFC 3339

As the time values are meant for human-readable representation in
the RFC 3339 format, make it not possible to construct Time with values
that fall outside this standard representation.
Conversion from time::OffsetDateTime is made fallible with
a TryFrom impl replacing the From impl.
Conversion from Unix timestamps is also affected.

* rpc: Replaced chrono with time 0.3

* testgen: Replaced chrono with time 0.3

* Less allocatey ways of formatting date-times

Provide and use another helper in proto mod serializers::timestamp,
one that formats into a provided fmt::Write object rather than
allocating a string.

* light-client: port from chrono to time

* Revert to Add/Sub returning Result

* light-client: changed the MBTs from chrono to time

* tendermint: Remove a comment referencing chrono

We use ErrorDetail::DurationOutOfRange without the source error
from the time library because that is uninformative in the context.
Also move the DateOutOfRange close with DurationOutOfRange
since they can occur in the same operations and are generally similar.

* light-client: add std feature for time

The clock needs OffsetDateTime::now_utc().

* tendermint: Simplify Time::duration_since

* testgen: minor code cleanup

* Restrict valid Time years to 1-9999

Exclude year 0 because the spec on Google protobuf Timestamp forbids it.

Add more helpers in pbt-gen to produce protobuf-safe values in both
OffsetDateTime and RFC 3339 strings.

Restrict the property tests to only use the protobuf-safe values
where expected.

* Test Time::checked_add and Time::checked_sub

* Changelog entries for informalsystems#1030

* Improve documentation of tendermint::Time

* proto: remove the chrono type conversions

The From impls are panicky and do not enforce compliance with
protobuf message value restrictions.

* tendermint: remove direct uses of chrono types

Replace with tendermint::Time.

* Harden Timestamp conversions and serde

Require the timestamp to be in the validity range (years 1-9999 in UTC)
and the nanosecond member value to not exceed  999_999_999.

Rename ErrorDetail::TimestampOverflow to TimestampNanosOutOfRange,
because the old variant was not very informative (the chained
TryFromIntError did not help) and we also use it for the above-range
case now which is not an overflow.

* Changelog entry about changed error variants

* Restore nanosecond range check in Time::from_unix_timestamp

Add a unit test to exercise the check.

* proto: Improve timestamp::fmt_as_rfc3339_nanos

- More ergonomic signature
- A non-allocating implementation

* Fix component name in changelog for 1030-remove-chrono

Co-authored-by: Thane Thomson <thane@informal.systems>

* time: Use Self instead of the type name in methods

Co-authored-by: Thane Thomson <thane@informal.systems>

* Comment on the inner representation of `Time`

* Don't alias crate time in testgen

* Document the Time::from_utc helper

Co-authored-by: Thane Thomson <thane@informal.systems>
@hdevalence hdevalence marked this pull request as ready for review September 20, 2022 20:25
@mzabaluev
Copy link
Contributor

0.35 compatibility

How much should we care about 0.35 at this point? This version has been discarded by cosmos-sdk in favor of 0.37, and judging by my previous work on side-by-side support for it in #1143, the protocol differences with 0.34 are more significant than between 0.34 and 0.37.

proto/src/prost/tendermint.abci.rs Show resolved Hide resolved
@@ -39,7 +39,7 @@ pub struct Response {
pub n_peers: u64,

/// Peer information
pub peers: Vec<PeerInfo>,
pub peers: Option<Vec<PeerInfo>>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a special meaning for None that would be different to Some(vec![]) here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't know, this is the existing domain type modeling.

Copy link
Contributor

@mzabaluev mzabaluev Sep 21, 2022

Choose a reason for hiding this comment

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

My only guess is, it could matter for serialization where the peers field can also have a null value (it cannot be missing/omitted from the struct because that would require serde attributes to allow). But I'd like to know what's the purpose of this special case as a domain type and how does it interop with responses from the wire. In the Go implementation, the field type is an ordinary array, and it's specified as such in the OpenAPI manifest as well. Without more information, I'd suggest removing the Option wart for the 1.0 API.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Cool, removing the Option sounds good.

Copy link
Contributor

@mzabaluev mzabaluev Sep 26, 2022

Choose a reason for hiding this comment

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

I suspect the Go code slips in a null instead of an array value somewhere, and this gets encoded into JSON accordingly. But I'd like to see a case where this is valid or otherwise has to be grandfathered in.

@@ -128,7 +129,7 @@ impl Block {
}

/// Get data
pub fn data(&self) -> &transaction::Data {
pub fn data(&self) -> &Vec<Vec<u8>> {
Copy link
Contributor

Choose a reason for hiding this comment

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

The return type looks dodgy; borrowing as a slice would be better perhaps?

Suggested change
pub fn data(&self) -> &Vec<Vec<u8>> {
pub fn data(&self) -> &[Vec<u8>] {

Copy link
Contributor

Choose a reason for hiding this comment

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

A domain Data type might be stylistically better, but I don't have much history with this API to strongly recommend that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think changes to the existing API should be made after backporting it, rather than as part of the backport, and after a semver-compatible release, so that it's actually possible for downstream users to use the crate at all.

@hdevalence
Copy link
Collaborator Author

0.35 compatibility

How much should we care about 0.35 at this point? This version has been discarded by cosmos-sdk in favor of 0.37, and judging by my previous work on side-by-side support for it in #1143, the protocol differences with 0.34 are more significant than between 0.34 and 0.37.

There's no compatibility with 0.35; the changes for 0.35 compatibility are the ones not included in this rebase.

@mzabaluev
Copy link
Contributor

Superseded by #1203.

@mzabaluev mzabaluev closed this Sep 30, 2022
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.

None yet

2 participants