Adding a new Shelley-based era to consensus
This document walks through the steps required to add a new Shelley-based era to consensus and to add it as an extra era to the Cardano blockchain.
Prior art upon which this is based:
The steps are fairly straightforward. We have put things in place (in consensus and in the ledger) when adding the Allegra and Mary eras that should now make it much easier to add a new additional era.
There are two main driving changes: adding the new era to
Ouroboros.Consensus.Shelley.Eras
and including that era in
Ouroboros.Consensus.Cardano.Block
. The compiler should point the rest of the
way. It's mostly a matter of following the existing patterns by imitating the
previous Shelley-based case. Be sure to run both the Shelley
(ouroboros-consensus-shelley-test
) and the Cardano
(ouroboros-consensus-cardano-test
) tests.
For exhaustiveness, we give an overview of the changes needed. The new era we'll be adding is the Alonzo era, which comes after the Mary era.
Preparation
-
Locate the new tag in the ledger, e.g.,
AlonzoEra
. This is an empty data type that is used at the type level to indicate the era. The ledger should have an instance of theShelleyBasedEra
class (the class defined inCardano.Ledger.Shelley.API
, do not confuse it with the class with the same name in consensus) for this era. This class should provide all the instances consensus integration will rely on. -
Note that both the affected consensus libraries and test suites are parametric in the Shelley-based era or in the general era. The test suite relies on the necessary
Arbitrary
,Show
,Eq
, ... instances to be available for all of the Cardano eras. This means that a new era can only be added to the Cardano eras when the ledger provides all the necessary instances for the new era, including the instances for the test suite (e.g., the serialisation generators). Note that because the test suite is parametric/generic in the eras, it is not easy to temporarily omit a single era from the test suite until the required instances have been added. This means that we can't extend the library with the new era without extending the test suite too. In the past, this has been the main blocker: the library was ready, but the required instances in the ledger were missing for our test suite(s). -
Add the required dependencies on the ledger package (and its test package) to the
cabal.project
file. You will have to add it to some other cabal files too, let the compiler tell you which ones.
ouroboros-consensus-shelley
-
Define
StandardAlonzo
inOuroboros.Consensus.Shelley.Eras
and add any missing instances to that module, update the export list appropriately. -
In
Ouroboros.Consensus.Shelley.Node
, defineProtocolParamsAlonzo
just like the existing ones. In case the era in question needs extra parameters (e.g., a new genesis config?), they can be added here.
ouroboros-consensus-shelley-test
- In
Test.Consensus.Shelley.Examples
, define anexamplesAlonzo
similar to howexamplesMary
is defined. If necessary, i.e., when new type families have been created in the ledger (e.g.,TxOut
), theexamples
function might have to take more arguments. This is where the golden test examples are defined, but only the Shelley ones are tested as part of this test suite. The others are only tested as part of theouroboros-consensus-cardano-test
test suite.
ouroboros-consensus-cardano
-
In
Ouroboros.Consensus.Cardano.Block
, includeAlonzoEra
inCardanoShelleyEras
. Update all the pattern synonyms in the module with the new era. Don't forget to update the comments, theCOMPLETE
pragmas, and the export lists. It's easy to forget a case and the compiler will likely not warn you, you'll notice it when trying to use the pattern synonyms. -
In
Ouroboros.Consensus.Cardano.CanHardFork
, updateCardanoHardForkConstraints
, add additional translations to theCanHardFork
instance. -
In
Ouroboros.Consensus.Cardano.Node
, update theSerialiseHFC
instance by following the existing patterns. Add a newCardanoNodeToNodeVersion
andCardanoNodeToClientVersion
that enable theAlonzoEra
, update the existing ones so that they disable the new era. Be sure to include the new versions in the two methods of theSupportedNetworkProtocolVersion
instance. ExtendprotocolInfoCardano
with the new era by following the type errors and adding the missing parameters (includingProtocolParamsTransition
). Don't forget to derivemaxMajorProtVer
from the new final era. UpdateprotocolClientInfoCardano
too. -
In
Ouroboros.Consensus.Cardano
, update theProtocolCardano
type synonym, add the extra arguments needed forprotocolInfoCardano
to theProtocolCardano
constructor. UpdateprotocolInfo
accordingly.
test
-
In
Test.Consensus.Cardano.ByronCompatibility
, updatetoCardanoCodecConfig
. -
In
Test.Consensus.Cardano.Serialisation
, updatetestCodecCfg
anddictNestedHdr
. -
In
Test.Consensus.Cardano.Golden
, update theToGoldenDirectory
instances. -
Create a
Test.ThreadNet.MaryAlonzo
module similar toTest.ThreadNet.AllegraMary
, to test the transition from Mary to Alonzo. Don't forget to include it in theMain
of the test suite. You will have to create aTest.ThreadNet.TxGen.Alonzo
module similar toTest.ThreadNet.TxGen.Mary
. -
Run the golden tests (
cabal run ouroboros-consensus-cardano:cardano-test -- -p /Golden/
). Golden test results should have been created for the new Cardano versions. Don't forget to commit those files, otherwise they will be recreated on each run in CI and not compared against the previous results, rendering them useless. -
Extend
Test.ThreadNet.Cardano
with the new era.
unstable-cardano-testlib
-
In
Test.Consensus.Cardano.Generators
, updatearbitraryNodeToNode
,arbitraryNodeToClient
. Try to understand the logic of these two, you will also have to add a new case to these. It would be nice if we could write these two in a generic way so that they won't have to be updated with each era, but it's not so simple. Update the other functions/instances. Be careful, you won't get warnings for missing cases inArbitrary
instances, so go over all of them and add the missing cases. -
In
Test.Consensus.Cardano.Examples
, updateeraExamples
,combineEras
, and the rest.