Open thanethomson opened 2 years ago
An alternative approach here as suggested by @soareschen is to support multiple versions of Tendermint Core from within a single codebase. In other words, Tendermint Core version-specific code would live behind versioned modules (e.g. tendermint::v034
and tendermint::v035
) and common code would live in a ::common
module.
It looks as though this may end up being the best approach going forward if we want to be able to ensure the ability to connect networks running different versions of Tendermint Core through IBC.
The nice thing about this approach is that we won't need complex VCS strategies to manage it, and we can easily support semver, but then the complexity will live in the codebase itself.
To assess this meaningfully it would be helpful to understand which types/interfaces actually differ between the versions.
To assess this meaningfully it would be helpful to understand which types/interfaces actually differ between the versions.
This depends on the specific versions, whereas we need a somewhat generic versioning strategy for the codebase that can cope with breaking changes across all of the publicly accessible interfaces Tendermint provides:
Changes in these data structures necessarily require changes to our domain types and possibly serialization strategies. Of course, minimizing data structure duplication is of high priority here, but sometimes it can't be helped.
For specifics we can consult the Tendermint upgrading guide.
As an example of a specific breaking change, Tendermint will be deprecating the WebSocket interface entirely in v0.37 in favor of a long polling interface (which will be available from v0.36). See the ADR. If we wanted to fully support v0.35 and v0.36/v0.37 simultaneously, this will require different client implementations to handle the two different subscription protocols.
After discussing with @hdevalence, it seems like it might be better to move toward a semantic versioning strategy for tendermint-rs.
The current versioning strategy involves allowing for breaking changes in minor and patch releases, which shifts the burden of version management to consumers. Switching directly to a semantic versioning strategy using the current crate names will unfortunately not work, as this restricts us to only being able to make breaking client API changes (e.g. sync to
async
, or domain type changes) when a new version of Tendermint Core is released, which doesn't make sense.The alternative strategy is as follows:
tendermint-v034
v1.0.0,tendermint-rpc-v034
v1.0.0,tendermint-light-client-v034
v1.0.0, etc. would all target Tendermint Core v0.34.xtendermint-v035
v1.0.0,tendermint-rpc-v035
v1.0.0,tendermint-light-client-v035
v1.0.0, etc. would all target Tendermint Core v0.35.xv0.34.x
branch from which we would release thetendermint-v034*
crates,v0.35.x
branch from which we would release thetendermint-v035*
crates,main
(we'll renamemaster
tomain
) will, in a best effort manner, attempt to keep compatibility with Tendermint Coremaster
/main
in anticipation of upcoming Tendermint Core releases. Features should ideally be added to themain
branch first and then back-ported to the relevant long-lived version branch.