Skip to content

Commit 35cc0cb

Browse files
committed
TOSQUASH HardForks.md: address some of Alexey's comments
1 parent 43a7afe commit 35cc0cb

File tree

1 file changed

+59
-23
lines changed

1 file changed

+59
-23
lines changed

docs/website/contents/for-developers/HardForks.md

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
## Introduction
44

5-
This document details how the Cardano node handles a [hard fork](https://en.wikipedia.org/wiki/Fork_(blockchain)#Hard_fork).
5+
This document details how the Cardano node handles a [hard fork](https://en.wikipedia.org/wiki/Fork_(blockchain)#Hard_fork), and why it handles hard forks that way.
66

7-
Cardano mainnet is intended to hard fork when and only when the major component of the [`protocol version` protocol parameter](https://github.com/IntersectMBO/cardano-ledger/blob/2ff5fa4e8c6b773748799981ef44ef6a62cd5c92/libs/cardano-ledger-core/src/Cardano/Ledger/Core/PParams.hs#L350) changes.
8-
As an updatable protocol parameter, the protocol version can only change due to on-chain governance [^updatable-protocol-parameters], and in practice the major protocol version should only increase by one when it changes and the lesser components should be reset to zero.
7+
Cardano mainnet is intended to hard fork when and only when the major component of the [`protocol version`](https://github.com/IntersectMBO/cardano-ledger/blob/2ff5fa4e8c6b773748799981ef44ef6a62cd5c92/libs/cardano-ledger-core/src/Cardano/Ledger/Core/PParams.hs#L350) changes.
8+
The protocol version can only change due to on-chain governance [^updating-protver], and in practice the major protocol version must only ever increase by one [^PVP-style].
99

10-
- The requirement that a major protocol version change implies a hard fork and that it only ever increments by one and resets the lessers is merely the traditional semantics of the major component of a version, ie _backwards-incompatibility_ (aka _breaking_ change).
10+
- The requirement that a major protocol version increment implies a hard fork is merely the traditional semantics of the major component of a version, ie _backwards-incompatibility_ (aka _breaking_ change).
1111

1212
- The requirement of on-chain governance for each hard fork means that --- as of the arrival of decentralized governance to the Cardano mainnet chain --- it's the community that decides when to transition to the next iteration of the protocol rules and/or ledger rules, ie when to abandon any nodes that have not yet updated their software in preparation for the hard fork.
1313

@@ -16,39 +16,61 @@ By their essential nature, though, testnets should also use mainnet's mapping be
1616
On the other hand, these other networks must be able to hard fork at different times than mainnet does --- the testnets should have hard forked successfully before mainnet hard forks!
1717
Since the testnet governance and mainnet governance are independent, the determination of the hard fork timing via on-chain governance immediately enables it to vary on different networks' chains.
1818

19+
Beyond those fundamentals, the community of Cardano developers must also decide how to implement the changes that underly a hard fork, how to organize them within the nodes' specifications and implementations [^multiple-nodes].
20+
21+
## Concrete Dynamics
22+
23+
A hard fork in Cardano proceeds in phases.
24+
25+
- *Implementation*.
26+
Cardano developers introduce some backwards-incompatible changes to the protocol and/or ledger rules in the node software [^change-decisions].
27+
- *Release*.
28+
As a decentralized network, it is impractical to rely on all Cardano node operators simultaneously updating their software.
29+
Therefore, a new release of the software implements the new rules _and also_ the old rules.
30+
That release continues to use the old rules --- even for fresh blocks --- until the community ultimately chooses to switch to the new rules by increasing the major protocol version parameter via on-chain governance [^frame-rule].
31+
- *Adoption*.
32+
It is crucial that the community does not increment the major protocol version until a vast majority of (honest) stake has upgraded their nodes to the new software.
33+
Stake pool operators should therefore not vote to increment before upgrading their nodes to the new software.
34+
35+
Because the protocol version is determined on-chain, it's perfectly plausible for divergent chains to increment the major version at different times.
36+
The Cardano node ought to handle that scenario gracefully, if only to bound degradation during atypical scenarios (eg low participation within the limits of Praos's _dynamic availability_ feature).
37+
However, branching realities are disruptive even within blockchain communities, so the current design additionally ensures that even temporarily divergent chains (aka _short forks_) will agree about when to increment the major version as long as mainnet enjoys high participation from its honest majority of stake.
38+
1939
## Eras
2040

21-
A hard fork is the result of the nodes' developers introducing backwards-incompatible changes [^change-decisions] and the community ultimately choosing to adopt them by increasing the major protocol version parameter via on-chain governance [^frame-rule].
22-
When those developers design and implement such changes, they determine whether the changes are easy to maintain as variations within the existing code.
23-
If so, then the hard fork is ultimately toggling some conditionals within the code.
41+
When Cardano developers design and implement the changes for a hard fork, they determine whether the changes are easy to maintain as variations within the existing code.
42+
If so, the hard fork is ultimately implemented by some conditionals within the code that branch on the major protocol version.
2443
If the changes are not so simple, the Cardano developers instead introduce a new _era_ within the code [^roadmap-disambiguation].
44+
(See "Which changes require a new era?" below --- this determination is done within the context of the existing implementation's architecture, not a vacuum.)
2545

26-
Each era defines some new types and rules that are independent within the code from the existing eras.
46+
In the intended usage, each era defines some new types and rules that are independent within the code from the existing eras.
2747
For example, the [Conway era introduces](https://docs.cardano.org/about-cardano/evolution/upgrades/chang) many new parts of the ledger state, transaction types, corresponding rules, etc that the preceding era does not have, and so the architects decided to explicitly separate the Conway code from the old code as a new era.
2848
The Ledger and Consensus infrastructure code is defined so that each era can flexibly reuse whichever of the older eras' features it does not supersede.
29-
Several eras coexist sequentially on the Cardano chain; a hard fork that takes one step within that sequence is called an _era transition_.
3049

31-
Every hard fork is either an era transition or an _intra-era hard fork_ [^accidentals].
50+
Several eras coexist sequentially on the Cardano chain; a hard fork that takes one step within that sequence is called an _era transition_.
51+
Every intentional hard fork is either an era transition or an _intra-era hard fork_ [^accidentals].
3252
Intra-era hard forks only introduce changes with a small effect on the code, eg a few easy-to-maintain conditionals.
3353
Some have been bugfixes that were small by chance, and others have been changes that were only small because they had been anticipated and intentionally deferred when the era was originally designed.
3454

35-
Eras are a straight-forward mechanism that enables node developers to separate the concerns arising from features that are added to Cardano over time.
55+
Eras are a straight-forward mechanism that enables node developers to separate the concerns arising from features that are added to or removed from Cardano over time.
3656
The separation amongst eras inherently simplifies the development of the new features, and it also helps ensure that the Cardano node can sync the entire historical chain [^mithril] --- as well as refuse invalid alternative histories.
3757

3858
### Which changes require a new era?
3959

4060
It's ultimately the judgment of the node developers whether some changes should be achieved with an era transition rather than an intra-era hard fork.
61+
In other words, eras are not the only to organize non-trivial backwards-incompatible changes in Cardano.
62+
However, only a single node implementation has existed for several years now, and aspects of its existing design make some backwards-incompatible changes prohibitively costly (ie redesigns) unless they are delineated by an era transition.
4163

42-
The Cardano developers have so far used very expressive static typing.
43-
It's plausible that an implementation that instead used dynamic types could more frequently use intra-era hard forks rather than era transitions.
44-
However, we strongly believe that overall development and assurance would degrade without the benefits of such precise types.
64+
The Cardano developers have so far used very expressive static typing in order to provide the safety guarantees that Cardano is known for.
65+
It's plausible that an implementation that instead used a language more suited to dynamic types could more frequently use intra-era hard forks rather than era transitions or avoid the concept of eras altogether and rely solely on logic that branches on the major protocol version.
66+
However, we strongly believe that overall development and assurance would significantly degrade without the benefits of such precise types.
4567

4668
The first era transition (from Byron to Shelley) is a notable example.
4769
It was the first era transition we experienced, and no subsequent transition changes nearly so much.
4870
The two code bases are drastically different, so it's hard to argue this should have been an intra-era hard fork.
4971
In particular, this is the only era transition that changed the duration of slots and the number of slots in an epoch.
5072
In the current codebase, any hard fork that changes those per-era constants must be an era transition, since the Consensus infrastructure was explicitly designed with that restriction as a simplifying assumption.
51-
A different design might relax that constraint, but it is has not been restrictive so far: a second change to these constants has been discussed only rarely and never actually proposed, and deferring them until whatever justifies the next era transition wouldn't obviously be prohibitively disruptive.
73+
A different design might relax that constraint, but it has not been restrictive so far: a second change to these constants has been discussed only rarely and never actually proposed, and deferring them until whatever justifies the next era transition wouldn't obviously be prohibitively disruptive.
5274

5375
### How wide-reaching are eras?
5476

@@ -64,10 +86,13 @@ Specifically, the node must be able to forecast the data necessary to validate a
6486
(See [this GitHub comment](https://github.com/IntersectMBO/ouroboros-consensus/issues/416#issuecomment-2669347315) for the details of how this lesson was learned.)
6587

6688
- Some codecs reflect Cardano's specific era structure.
67-
That's not strictly necessary, but a tagged union approach has made it trivial to combine the era-specific codecs into a full Cardano codec.
89+
That's not strictly necessary, but a tagged union approach has made it trivial to combine the era-specific codecs into a full Cardano codec.
6890
Specifically, top-level codecs fundamentally branch on a simple number located near the beginning of the bytestring and dispatch accordingly to the corresponding era's codecs.
6991

70-
- (TODO Confirm whether these tags dont affect any hashes. If they do, to what extent does it actually matter?)
92+
*Remark*.
93+
These eras tags are not present in any codecs for bytes that determine hashes used on chain.
94+
For example, suppose the only difference between some transaction's serialization in two different eras is the numeric value of the era tag.
95+
In that case --- unless the eras use different hashing functions --- both serializations would be assigned the same transaction ID, since the function that assigns transaction IDs is applied to the bytes inside of the envelope that carries the era tag.
7196

7297
## Forecasting, forewarning
7398

@@ -76,12 +101,23 @@ For this reason, hard forks must not happen less than 36 hr (on mainnet) after t
76101

77102
TODO how to argue that hard forks or era transitions needs more than that?
78103

79-
[^updatable-protocol-parameters]: *Reference*.
80-
See Section 5 "Protocol Parameters" of the "A Formal Specification of the Cardano Ledger, Deliverable SL-D5" document for more details.
81-
Its latest revision can be accessed via the hyperlink in the "Formal Specification" column of the "Shelley" row of the documentation table at the top of the [README](https://github.com/IntersectMBO/cardano-ledger/blob/master/README.md) of the [`cardano-ledger` repository](https://github.com/IntersectMBO/cardano-ledger).
104+
[^updating-protver]: *Remark*.
105+
Prior to Conway, the protocol version was just another protocol parameter; see Section 5 "Protocol Parameters" of the "A Formal Specification of the Cardano Ledger, Deliverable SL-D5" document for more details --- its latest revision can be accessed via the hyperlink in the "Formal Specification" column of the "Shelley" row of the documentation table at the top of the [README](https://github.com/IntersectMBO/cardano-ledger/blob/master/README.md) of the [`cardano-ledger` repository](https://github.com/IntersectMBO/cardano-ledger).
106+
As of Conway's [CIP-1694](https://github.com/cardano-foundation/CIPs/tree/master/CIP-1694) implementation, the protocol version has special treatment compared to other protocol parameters, since it so clearly requires a preceding software upgrade.
107+
The logic is the same at a high-level, but the details are tuned to ensure a hard fork could only ever surprise a very small amount of stake.
108+
109+
[^PVP-style]: *Remark*.
110+
The Cardano protocol version has two components, so-called major and minor.
111+
The lesser component has always been zero on mainnet.
112+
We might eventually see a use for it, but at the moment the only plausible idea we have is for both components to track backwards-incompatible changes, as in the [Haskell Package Versioning Policy](https://pvp.haskell.org/), eg.
113+
114+
[^multiple-nodes]: *Remark*.
115+
There has only been one Cardano node so far, but others are now in development.
116+
The different nodes _must_ be able to exchange messages, but it is not yet clear how the multiple teams will cooperate on decisions such as how to specify and implement some backwards-incompatible change.
117+
Cardano Improvement Proposals (aka [CIPs](https://cips.cardano.org/)) will certainly be involved in such alignment efforts but are not necessarily sufficient.
82118

83-
[^change-decisions]: *Reference*.
84-
Nowadays, these are almost always going to be (possibly indirectly) related to a Cardano Improvement Proposal (aka [CIP](https://cips.cardano.org/)).
119+
[^change-decisions]: *Remark*.
120+
At time of writing, these are almost always going to be (possibly indirectly) related to a Cardano Improvement Proposal (aka [CIP](https://cips.cardano.org/)).
85121

86122
[^frame-rule]: *Clarification*.
87123
There's no other technical reason for the community to increment the major protocol version.
@@ -92,7 +128,7 @@ TODO how to argue that hard forks or era transitions needs more than that?
92128
[CIP-0059](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0059/feature-table.md) maintains a table showing the correspondence; it lists roadmap eras in the "Phase" column.
93129

94130
[^accidentals]: *Clarification*.
95-
Accidental hard forks would necessarily be intra-era hard forks.
131+
Accidental hard forks (eg due to a bug) would necessarily arise within a single era, but they are not _intra-era hard forks_ because they weren't gated by a protocol version change.
96132

97133
[^mithril]: *Clarification*.
98134
Mechanisms such as [Mithril](https://github.com/input-output-hk/mithril) would provide alternatives to the node, but the node itself should always be able to revalidate (or merely reapply) all the blocks if needed/desired.

0 commit comments

Comments
 (0)