-
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
Reorganize tendermint::abci
to clean up module organization and conform to Rust RFC356
#856
Comments
I realized after writing this up that what I suggested doesn't actually make sense. The code in question is proto-generated, so it can't be meaningfully edited without being clobbered later, and I missed this on first reading because I didn't realize that the generated code is checked in as part of the source tree. @thanethomson pointed out that the The data modeling suggested above could instead be done on a set of domain types in the |
Makes sense 👍 |
Cool, I'll instead work on a PR to produce those types as part of |
Yes, I think that makes sense. I've been debating whether or not to implement domain types for the ABCI data structures for some time now, and can summarize the pros and cons I've thought of as follows: Pros
Cons
Ultimately it comes down to the fact that it's more work to maintain them, but I think the benefits are worth the effort. @romac, what do you think? |
I am personally a bit wary of exposing the Protobuf type directly, as to me they are a serialization concern only, and I would rather expose properly designed Rust domain types, for all the pros you list above. At the same time I don't want to dismiss the cost of having to maintain this extra code, but if you ask me, I agree that the pros outweigh the cons for the benefit of the users of the library. |
I don't think there's a tension between exposing domain types and exposing protobuf types. There are use-cases that require domain types and use-cases that require raw protos. It seems like the problem is that if there's only one set of types, those use cases get conflated. Even if there are well-modeled domain types and the protos are only a serialization concern, they're still required for anything that needs to work with serialization. For example, I'm working on an alternative ABCI interface. I would like that interface to use well-modeled domain types, but internally it needs to know about the protos to be able to speak TSP. I'm not sure exactly what was meant by "wary of exposing the Protobuf type directly", so my apologies if I misunderstood what you meant, but I don't think it makes sense to try to hide the protos completely, since they're part of the ecosystem. Keeping them in a separate crate means they can be versioned independently of the main API, and people don't need to use them by default. They can opt-in by using the |
@hdevalence I fully agree with you! I should have been clearer about what I meant by "wary of exposing the Protobuf type directly", which is that I would not want to expose the Protobuf types directly in the public API. We definitely want to export them somehow (either in the |
tendermint_proto::abci
to clean up module organization and conform to Rust RFC356tendermint::abci
to clean up module organization and conform to Rust RFC356
Closed by #1022 |
Currently, the ABCI types in
tendermint_proto
have the structural content filled in, but aren't nicely organized yet:Rust's RFC356 recommends that type names should avoid having common prefixes, and instead use module paths to factor a name into components, for instance having
abci::request::{Commit, CheckTx}
instead ofabci::{RequestCommit, RequestCheckTx}
. This has the advantage that the user of the name can decide which parts of the name are required, writing any ofabci::request::Commit
,request::Commit
,Commit
,depending on how much context is assumed at the use site. It also makes navigating the related types in the docs more clear, since the types are organized into categories.
What's the definition of "done" for this issue?
To tidy the module organization:
RequestFoo
torequest::Foo
;Request
enum torequest
andpub use
it in theabci
module;ResponseFoo
toresponse::Foo
;Response
enum toresponse
andpub use
it in theabci
module;response_apply_snapshot_chunk
andresponse_offer_snapshot
modules, by either:response_apply_snapshot_chunk::Result
toresponse::ApplySnapshotChunkResult
(least impact on code that currently uses the structure, it's a clean rename);ApplySnapshotChunk
andOfferSnapshot
to hold enums internally (need to make non-mechanical changes to using code, but potentially cleaner in the long run);I would pick option A above.
To fill in the documentation:
To make it easier to model the four ABCI connections:
Create per-connection enums:
ConsensusRequest
/ConsensusResponse
;MempoolRequest
/MempoolResponse
;InfoRequest
/InfoResponse
;SnapshotRequest
/SnapshotRequest
;with conversions
impl From<FooRequest> for Request
(infallible, all variants of the per-connection enum are variants of the full enum) andimpl TryFrom<Request> for FooRequest
(fallible, not all variants of the full enum are variants of the per-connection enum).The text was updated successfully, but these errors were encountered: