IntersectMBO / IntersectMBO/cardano-ledger

Change semantics of protocol version in BlockHeader

Open
#5,763 1 comment 0 reactions 1 assignee Claimed by @f-f View on GitHub
DijkstraEra
Dominant language
Haskell
Stars
295
Forks
179
Avg merge
4d 7h
Merged PRs (30d)
29

Description

Protocol version in TPraos and Praos block headers have historically been abused in ways that is not directly compatible with the actual protocol version in the ledger state.

Here is the main purpose for what this field with protocol version was always used for:
* Minor protocol version was abused to indicate what a minor or patch version of the cardano-node was that minted the block, which didn't have any consistent correlation with an actual node version or the protocol version in the ledger state. Also this value was mostly used for statistical and not super reliable metric of how many block producing SPOs actually upgraded their software.
* Major version, on the other hand, always had a semantic meaning that was somewhat related to the actual major protocol version in the ledger state. This version was always set by the node to the latest major protocol version that the node is 100% capable of understanding, i.e. latest version into which this version of cardano-node could safely hard fork into. Since the last few years, after we've switched semantic versioning of `cardano-node`, this would always match the major version of the `cardano-node`, unless it was compiled with experimental flag on. There is also a ledger/consensus rule that checks, that if the major version in the header is lower than the current major protocol version in the ledger state, then this block producer that minted the block is running software that is too old, and such blocks would get rejected by all other newer nodes. This is an intentional measure to drop off all SPOs that failed to upgrade their software in order to prevent them from interfering with normal operation of the network. Strictly speaking it is not a necessary safety requirement, because they would eventually get kicked out from the network as soon as any of the newer nodes would have produced a block that is incompatible with an older protocol version. That being said it is a "nice to have" proactive measure, that forces SPOs to upgrade their software before the hard fork gets enacted.

Aside from social issues listed above, there is also a technical issue that we recently fixed. That protocol version in the block header historically used `ProtVer` type, despite having a different underlying meaning. Because ledger has strict enforcement on which values that `ProtVer` type can take for every era, we were forced to apply the same strict meaning to the protocol version in the block header. Namely, as of recent, major protocol version can only take a value of the current major protocol version or one higher. This works just fine for Mainnet, because we can never be in a situation where block producer is trying to mint a block using software that can either understand only the current protocol version or the very next major protocol version from the current one, because that is how normally software readiness works.
However, this proved to be a problem for various ephemeral testnets that try to enable experimental hard forks or try to pretend that they are building blocks in much older eras, since any version of the `cardano-node` software is actually still capable of doing that.

~There is a [CIP-180 - Block Producer Identification](https://github.com/cardano-foundation/CIPs/pull/1157) that proposes a new field that can be used for identifying the actual name and the version of the software building the block, which makes a hack around minor protocol version in the current field no longer necessary.~ - CIP was closed
~There is also a discussion around making minor version to be used for intra-era hard fork, which seems like a great idea, but it requires a whole another CIP.~ - Discussion didn't go anywhere so far, so this is postponed until better times.

So, we still want to use that field for enforcing SPOs to upgrade their software before hard forks, which means we are not proposing to remove this field. Instead, this ticket is proposing to officially change:
* the semantics of the field to: "highest protocol version that this block producer is capable of understanding"
* and as a consequence change its type from `ProtVer` to a matching one with a different decoder.

This ticket will need to be resolved for Dijkstra era, because it will have a new definition of a block header

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.