Oct 28, 6-7 PM (14)
Oct 28, 7-8 PM (18)
Oct 28, 8-9 PM (36)
Oct 28, 9-10 PM (37)
Oct 28, 10-11 PM (26)
Oct 28, 11-12 AM (21)
Oct 29, 12-1 AM (8)
Oct 29, 1-2 AM (9)
Oct 29, 2-3 AM (17)
Oct 29, 3-4 AM (28)
Oct 29, 4-5 AM (26)
Oct 29, 5-6 AM (8)
Oct 29, 6-7 AM (20)
Oct 29, 7-8 AM (33)
Oct 29, 8-9 AM (33)
Oct 29, 9-10 AM (82)
Oct 29, 10-11 AM (85)
Oct 29, 11-12 PM (64)
Oct 29, 12-1 PM (80)
Oct 29, 1-2 PM (28)
Oct 29, 2-3 PM (50)
Oct 29, 3-4 PM (47)
Oct 29, 4-5 PM (41)
Oct 29, 5-6 PM (22)
Oct 29, 6-7 PM (12)
Oct 29, 7-8 PM (21)
Oct 29, 8-9 PM (14)
Oct 29, 9-10 PM (21)
Oct 29, 10-11 PM (28)
Oct 29, 11-12 AM (15)
Oct 30, 12-1 AM (6)
Oct 30, 1-2 AM (13)
Oct 30, 2-3 AM (9)
Oct 30, 3-4 AM (23)
Oct 30, 4-5 AM (4)
Oct 30, 5-6 AM (4)
Oct 30, 6-7 AM (2)
Oct 30, 7-8 AM (22)
Oct 30, 8-9 AM (40)
Oct 30, 9-10 AM (38)
Oct 30, 10-11 AM (42)
Oct 30, 11-12 PM (37)
Oct 30, 12-1 PM (43)
Oct 30, 1-2 PM (85)
Oct 30, 2-3 PM (73)
Oct 30, 3-4 PM (31)
Oct 30, 4-5 PM (29)
Oct 30, 5-6 PM (45)
Oct 30, 6-7 PM (10)
Oct 30, 7-8 PM (15)
Oct 30, 8-9 PM (19)
Oct 30, 9-10 PM (12)
Oct 30, 10-11 PM (31)
Oct 30, 11-12 AM (21)
Oct 31, 12-1 AM (16)
Oct 31, 1-2 AM (7)
Oct 31, 2-3 AM (6)
Oct 31, 3-4 AM (5)
Oct 31, 4-5 AM (7)
Oct 31, 5-6 AM (12)
Oct 31, 6-7 AM (8)
Oct 31, 7-8 AM (31)
Oct 31, 8-9 AM (79)
Oct 31, 9-10 AM (43)
Oct 31, 10-11 AM (61)
Oct 31, 11-12 PM (53)
Oct 31, 12-1 PM (55)
Oct 31, 1-2 PM (63)
Oct 31, 2-3 PM (73)
Oct 31, 3-4 PM (54)
Oct 31, 4-5 PM (43)
Oct 31, 5-6 PM (18)
Oct 31, 6-7 PM (17)
Oct 31, 7-8 PM (26)
Oct 31, 8-9 PM (10)
Oct 31, 9-10 PM (21)
Oct 31, 10-11 PM (34)
Oct 31, 11-12 AM (20)
Nov 01, 12-1 AM (9)
Nov 01, 1-2 AM (5)
Nov 01, 2-3 AM (7)
Nov 01, 3-4 AM (13)
Nov 01, 4-5 AM (4)
Nov 01, 5-6 AM (7)
Nov 01, 6-7 AM (24)
Nov 01, 7-8 AM (31)
Nov 01, 8-9 AM (36)
Nov 01, 9-10 AM (34)
Nov 01, 10-11 AM (31)
Nov 01, 11-12 PM (33)
Nov 01, 12-1 PM (8)
Nov 01, 1-2 PM (31)
Nov 01, 2-3 PM (38)
Nov 01, 3-4 PM (14)
Nov 01, 4-5 PM (12)
Nov 01, 5-6 PM (19)
Nov 01, 6-7 PM (14)
Nov 01, 7-8 PM (32)
Nov 01, 8-9 PM (5)
Nov 01, 9-10 PM (6)
Nov 01, 10-11 PM (59)
Nov 01, 11-12 AM (19)
Nov 02, 12-1 AM (2)
Nov 02, 1-2 AM (13)
Nov 02, 2-3 AM (43)
Nov 02, 3-4 AM (14)
Nov 02, 4-5 AM (39)
Nov 02, 5-6 AM (25)
Nov 02, 6-7 AM (0)
Nov 02, 7-8 AM (6)
Nov 02, 8-9 AM (5)
Nov 02, 9-10 AM (5)
Nov 02, 10-11 AM (12)
Nov 02, 11-12 PM (2)
Nov 02, 12-1 PM (5)
Nov 02, 1-2 PM (7)
Nov 02, 2-3 PM (2)
Nov 02, 3-4 PM (4)
Nov 02, 4-5 PM (9)
Nov 02, 5-6 PM (2)
Nov 02, 6-7 PM (2)
Nov 02, 7-8 PM (6)
Nov 02, 8-9 PM (2)
Nov 02, 9-10 PM (1)
Nov 02, 10-11 PM (24)
Nov 02, 11-12 AM (27)
Nov 03, 12-1 AM (0)
Nov 03, 1-2 AM (1)
Nov 03, 2-3 AM (2)
Nov 03, 3-4 AM (1)
Nov 03, 4-5 AM (0)
Nov 03, 5-6 AM (2)
Nov 03, 6-7 AM (0)
Nov 03, 7-8 AM (1)
Nov 03, 8-9 AM (4)
Nov 03, 9-10 AM (4)
Nov 03, 10-11 AM (2)
Nov 03, 11-12 PM (5)
Nov 03, 12-1 PM (7)
Nov 03, 1-2 PM (13)
Nov 03, 2-3 PM (5)
Nov 03, 3-4 PM (2)
Nov 03, 4-5 PM (1)
Nov 03, 5-6 PM (6)
Nov 03, 6-7 PM (2)
Nov 03, 7-8 PM (16)
Nov 03, 8-9 PM (2)
Nov 03, 9-10 PM (1)
Nov 03, 10-11 PM (24)
Nov 03, 11-12 AM (21)
Nov 04, 12-1 AM (6)
Nov 04, 1-2 AM (14)
Nov 04, 2-3 AM (9)
Nov 04, 3-4 AM (24)
Nov 04, 4-5 AM (8)
Nov 04, 5-6 AM (7)
Nov 04, 6-7 AM (44)
Nov 04, 7-8 AM (36)
Nov 04, 8-9 AM (63)
Nov 04, 9-10 AM (67)
Nov 04, 10-11 AM (57)
Nov 04, 11-12 PM (40)
Nov 04, 12-1 PM (65)
Nov 04, 1-2 PM (110)
Nov 04, 2-3 PM (89)
Nov 04, 3-4 PM (67)
Nov 04, 4-5 PM (22)
Nov 04, 5-6 PM (9)
Nov 04, 6-7 PM (4)
3,957 commits this week Oct 28, 2024 - Nov 04, 2024
chore(deps): bump github.com/blinklabs-io/gouroboros
Bumps [github.com/blinklabs-io/gouroboros](https://github.com/blinklabs-io/gouroboros) from 0.102.0 to 0.103.1.
- [Release notes](https://github.com/blinklabs-io/gouroboros/releases)
- [Commits](https://github.com/blinklabs-io/gouroboros/compare/v0.102.0...v0.103.1)

---
updated-dependencies:
- dependency-name: github.com/blinklabs-io/gouroboros
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Revert hack regarding Babbage→Conway ledger state translation (#1297)
Reverting the hacky approach of #366.

Closes #1239 by superseding it.

Addresses
https://github.com/IntersectMBO/cardano-ledger/issues/4635#issuecomment-2358022725.

# Justifying backwards-compatibility

This PR touches the Cardano ledger rules, concretely the logic for
translating a Babbage ledger state to a Conway ledger state. As the
Conway HF already happend on mainnet, it is crucial to argue why this
change retains backwards-compatibility with the historical chain.

## TL;DR

- The original reason for #366 was resolved by the refactoring in
https://github.com/IntersectMBO/cardano-ledger/pull/4253, making the
hack here in Consensus unnecessary.
- The accidental side effects of #366 around pointer addresses were made
"official" in https://github.com/IntersectMBO/cardano-ledger/pull/4647.

Therefore, it is fine to revert #366 without replacement.

## Detailed overview

### Context on HFC ledger ticking

When the HFC ticks a ledger state across an era boundary from A to B, it
does so via the "translate-then-tick" scheme:

1. First, the ledger state in A is translated into a ledger state in B.
2. Second, the ledger state is ticked to the target slot across the
epoch/era boundary, using the logic of era B.

For Cardano, the logic for these two operations lives in Ledger, or
rather, it *should* live in Ledger. However, in #366, we introduced a
temporary workaround/hack by modifying the translation logic from
Babbage to Conway to resolve
https://github.com/IntersectMBO/cardano-ledger/issues/3491. This PR
reverts the hack, such that we now again directly/transparently call
Ledger logic.

### Chronology of changes to Babbage→Conway ticking

1. Mainnet era transitions are triggered by on-chain updates to the
major ledger protocol version. The logic for updating the ledger
protocol version lives, unsurprisingly, in the Ledger, and takes place
while ticking across an epoch boundary.

For `cardano-ledger-conway < 1.14` (that's significantly before any
version used in a node that was mainnet-ready for Conway), this logic
was broken on the era transition from Babbage to Conway, resulting in
https://github.com/IntersectMBO/cardano-ledger/issues/3491, ie the
protocol version was *not* updated. Briefly[^1], the reason was that the
governance schemes of Babbage and Conway are completely different, which
caused issues because, as mentioned above, ticking across the
Babbage→Conway era/epoch boundary uses the logic of Conway, which
doesn't understand Babbage governance proposals, which were hence
discarded during the translation step.

2. The Consensus team decided[^2] to fix this issue via #366, which
updates the protocol version during the Babbage→Conway translation step
in an ad-hoc fashion, by temporarily ticking the *Babbage* ledger step
across the epoch/era boundary (yielding another Babbage ledger state),
and then setting the `GovState` (an era-specific ledger concept deep in
the ledger state, which in particular contains the current protocol
parameters, and hence the protocol version) of the unticked Babbage
ledger state to the one of the ticked Babbage ledger state, and then
proceeding as before.

Concretely, Babbage→Conway ticking now worked like this, starting with a
Babbage ledger state `l0` and a target slot `s`.

1. Tick `l0` just across the era/epoch boundary to get `l1` (a Babbage
ledger state).
2. Set the governance state of `l0` the the one of `l1` and get `l2` (a
Babbage ledger state).
     3. Translate `l2` into a Conway ledger state `l3`.
     4. Tick `l4` to `s` to get the final result.

3. A few months later, for `cardano-ledger-conway-1.14`, @lehins changed
in https://github.com/IntersectMBO/cardano-ledger/pull/4253 how the way
how protocol parameters are updated in Ledger in a way that is nicely
compatible with the "translate-then-tick" scheme, see the
[ADR](https://github.com/IntersectMBO/cardano-ledger/blob/a02dc6eae44287e8a1ac67ffafb8a1ecc492128f/docs/adr/2024-04-30_008-pparams-update.md)
added in that PR for details[^3]. In particular, this would have allowed
us to revert #366 immediately, but we didn't do so, probably because we
saw now immediate motivation. (In retrospect, we should have done that
immediately.)

4. A few months later, the Conway HF happened on mainnet. Due to
investigating an unrelated serialization bug around pointer addresses
(https://github.com/IntersectMBO/cardano-ledger/pull/4589), I realized
that not reverting #366 actually caused a slight difference in the
ledger rules, namely regarding stake delegations from pointer addresses
(also see
https://github.com/IntersectMBO/cardano-ledger/issues/4635#issuecomment-2358022725).

Concretely, Ledger wants to get rid of pointer addresses as they are
considered to be a misfeature and a potential liability for future
projects like Leios (also see [this
ADR](https://github.com/IntersectMBO/cardano-ledger/blob/master/docs/adr/2022-12-05_005-remove-ptr-addresses.md)).
In Conway, stake delegations from pointer addresses are intentionally no
longer considered. In particular, this happens during the SNAP rule
while ticking, by invoking the
[`forgoPointerAddressResolution`](https://github.com/IntersectMBO/cardano-ledger/blob/a02dc6eae44287e8a1ac67ffafb8a1ecc492128f/eras/shelley/impl/src/Cardano/Ledger/Shelley/HardForks.hs#L67)
predicate on the current protocol version, branching on whether the
current major protocol version is larger than `8` (the last Babbage
major protocol version).

- Using cardano-node 9.1 (i.e. the node that everyone was on to go to
Conway), so with #366:

When ticking the translated Conway ledger state into Conway, the current
protocol version is `9` (the first Conway major protocol version), due
to the previous ad-hoc patching of the `GovState` previously as part of
the workaround from #366. Therefore, pointer addresses are *not*
resolved while updating the stake distribution.

     - If we had reverted #366 for cardano-node 9.1:

Because we directly translate the Babbage ledger state to Conway without
doing the `GovState` patching before, the current protocol version while
ticking is `8`, so pointer addresses *are* resolved.

Altogether, the stake distribution used for the leader schedule starting
in the second Conway epoch would have differed slightly (only very
little stake, exactly 100 ADA, has been delegated via pointer
addresses).

Crucially, this difference had a chance to occur only because Ledger did
*not* blank e.g. the `ptrMap` field in `IncrementalStake` during the
Babbage→Conway translation. (This is actually what caused the
serialization bug mentioned above.)

There would have been another, less relevant difference: Because the
current protocol parameters are updated *twice* with #366 (first during
the Babbage tick, and then again during the Conway tick), the *previous*
protocol parameters during the first Conway epoch are incorrectly equal
to the *current* protocol parameters. However, the previous protocol
parameters are only used for reward calculation, and reward calculation
doesn't care whether the major protocol version is `8` or `9`. So this
difference doesn't matter.

8. In a recent Ledger PR
https://github.com/IntersectMBO/cardano-ledger/pull/4647, @lehins
modified the Babbage→Conway translation logic to blank out the pointer
addresses, e.g. `ptrMap` in `IncrementalStake`. This change landed in
Node 10.0.

Therefore, the difference described in 4. does not matter anymore, as
there no longer are any pointer addresses to resolve in Conway when
ticking (which happens *after* translating). Crucially, this enables us
to now revert #366 without replacement, because both before and after,
no pointer addresses are resolved for the stake distribution while
ticking from Babbage to Conway.

### Testing

I tested this on mainnet by starting from a Babbage ledger state and
evolving it via `db-analyser` to the first ledger state (slot
`134092810`) in the second Conway epoch using full block validation,
both with and without this PR. The resulting ledger states are
identical.

In the first Conway epoch, the ledger states differ, but only trivially
in the previous protocol parameters which has no effect as explained
above.

We *could* also write a component-level test for the pointer address
aspect, but that does not necessarily seem worth the cost/subtlety, as
this is a legacy feature already.

### Concluding thoughts

Generally, I think what we should take away from this is that we
*really* need proper specification and testing of what exactly should
happen at era boundaries, see
https://github.com/IntersectMBO/ouroboros-consensus/issues/418 and
https://github.com/IntersectMBO/cardano-ledger/issues/4635, especially
because certain esoteric parts of the ledger state (like pointer
addresses) might not exist on any testnet.

[^1]: See "Why the status quo is problematic" in #339 for the details
(but ignore the rest of the issue).
[^2]: After a long process that considered/prototyped various
alternatives, but the details are not that relevant for this PR and the
PR description is already very long.
[^3]: Briefly, the logic that updates the protocol parameters on
cross-epoch ticking is no longer era-dependent; rather, it just sets the
protocol parameters to "future" ones that were decided on earlier by
era-specific logic. The insight is that this set of future protocol
parameters can be easily/cleanly translated from Babbage to Conway, and
the Conway ticking logic can apply them despite having no idea *how*
Babbage decided that these should be the next protocol parameters.
Pull out Cardano specifics to a different module
There's a cyclic dependency issue in this commit that is fixed in the
next one. The problem is that I pulled out `ConsensusModePeerTargets`
which depend on `PeerSelectionTargets` and then the module that defines
`PeerSelectionTargets` requires `ConsensusModePeerTargets`. This is
fixed by abstracting over Cardano Node specific types such as
`ConsensusModePeerTargets`.