Skip to content

Commit eafa109

Browse files
committed
WIP
1 parent b13116a commit eafa109

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+703
-79
lines changed

cabal.project

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ repository cardano-haskell-packages
1313
-- See CONTRIBUTING for information about these, including some Nix commands
1414
-- you need to run if you change them
1515
index-state:
16-
, hackage.haskell.org 2025-06-22T20:18:27Z
17-
, cardano-haskell-packages 2025-06-20T09:11:51Z
16+
, hackage.haskell.org 2025-07-22T09:13:54Z
17+
, cardano-haskell-packages 2025-07-28T14:33:19Z
1818

1919
packages:
2020
cardano-api
@@ -205,3 +205,9 @@ if arch(wasm32)
205205
-- Do NOT add more source-repository-package stanzas here unless they are strictly
206206
-- temporary! Please read the section in CONTRIBUTING about updating dependencies.
207207

208+
allow-newer:
209+
, cardano-ledger-byron
210+
-- https://github.com/phadej/vec/issues/121
211+
, ral:QuickCheck
212+
, fin:QuickCheck
213+
, bin:QuickCheck

cardano-api/cardano-api.cabal

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,10 @@ library
128128
cardano-ledger-api >=1.11,
129129
cardano-ledger-babbage >=1.11,
130130
cardano-ledger-binary >=1.6,
131-
cardano-ledger-byron >=1.1,
131+
cardano-ledger-byron >=1.2,
132132
cardano-ledger-conway >=1.19,
133133
cardano-ledger-core:{cardano-ledger-core, testlib} >=1.17,
134+
cardano-ledger-dijkstra >= 0.1,
134135
cardano-ledger-mary >=1.8,
135136
cardano-ledger-shelley >=1.16,
136137
cardano-protocol-tpraos >=1.4,
@@ -168,7 +169,7 @@ library
168169
ouroboros-network-framework,
169170
ouroboros-network-protocols >=0.14,
170171
parsec,
171-
plutus-ledger-api:{plutus-ledger-api, plutus-ledger-api-testlib} ^>=1.45,
172+
plutus-ledger-api:{plutus-ledger-api, plutus-ledger-api-testlib} ^>=1.50,
172173
pretty-simple,
173174
prettyprinter,
174175
prettyprinter-ansi-terminal,
@@ -186,7 +187,7 @@ library
186187
time,
187188
transformers,
188189
transformers-except ^>=0.1.3,
189-
typed-protocols ^>=0.3,
190+
typed-protocols ^>= 1,
190191
vector,
191192
yaml,
192193

@@ -428,7 +429,7 @@ test-suite cardano-api-golden
428429
hedgehog >=1.1,
429430
hedgehog-extras ^>=0.8,
430431
microlens,
431-
plutus-core ^>=1.45,
432+
plutus-core ^>=1.50,
432433
plutus-ledger-api,
433434
tasty,
434435
tasty-discover,

cardano-api/src/Cardano/Api/Block.hs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ import Ouroboros.Consensus.Byron.Ledger qualified as Consensus
7272
import Ouroboros.Consensus.Cardano.Block qualified as Consensus
7373
import Ouroboros.Consensus.HardFork.Combinator qualified as Consensus
7474
import Ouroboros.Consensus.Shelley.Ledger qualified as Consensus
75-
import Ouroboros.Consensus.Shelley.Protocol.Abstract qualified as Consensus
7675
import Ouroboros.Network.Block qualified as Consensus
7776

7877
import Data.Aeson (FromJSON (..), ToJSON (..), Value (..), object, withObject, (.:), (.=))
@@ -153,6 +152,12 @@ instance Show (Block era) where
153152
( showString "ShelleyBlock ShelleyBasedEraConway "
154153
. showsPrec 11 block
155154
)
155+
showsPrec p (ShelleyBlock ShelleyBasedEraDijkstra block) =
156+
showParen
157+
(p >= 11)
158+
( showString "ShelleyBlock ShelleyBasedEraDijkstra "
159+
. showsPrec 11 block
160+
)
156161

157162
getBlockTxs :: forall era. Block era -> [Tx era]
158163
getBlockTxs = \case
@@ -167,7 +172,6 @@ getShelleyBlockTxs
167172
:: forall era ledgerera blockheader
168173
. ShelleyLedgerEra era ~ ledgerera
169174
=> Consensus.ShelleyCompatible (ConsensusProtocol era) ledgerera
170-
=> Consensus.ShelleyProtocolHeader (ConsensusProtocol era) ~ blockheader
171175
=> ShelleyBasedEra era
172176
-> Ledger.Block blockheader ledgerera
173177
-> [Tx era]
@@ -203,6 +207,7 @@ fromConsensusBlock = \case
203207
Consensus.BlockAlonzo b' -> BlockInMode cardanoEra $ ShelleyBlock ShelleyBasedEraAlonzo b'
204208
Consensus.BlockBabbage b' -> BlockInMode cardanoEra $ ShelleyBlock ShelleyBasedEraBabbage b'
205209
Consensus.BlockConway b' -> BlockInMode cardanoEra $ ShelleyBlock ShelleyBasedEraConway b'
210+
Consensus.BlockDijkstra _b' -> error "dijkstra"
206211

207212
toConsensusBlock
208213
:: ()
@@ -217,6 +222,7 @@ toConsensusBlock = \case
217222
BlockInMode _ (ShelleyBlock ShelleyBasedEraAlonzo b') -> Consensus.BlockAlonzo b'
218223
BlockInMode _ (ShelleyBlock ShelleyBasedEraBabbage b') -> Consensus.BlockBabbage b'
219224
BlockInMode _ (ShelleyBlock ShelleyBasedEraConway b') -> Consensus.BlockConway b'
225+
BlockInMode _ (ShelleyBlock ShelleyBasedEraDijkstra b') -> Consensus.BlockDijkstra b'
220226

221227
-- ----------------------------------------------------------------------------
222228
-- Block headers

cardano-api/src/Cardano/Api/Certificate/Internal.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ certificateToTxCert c =
234234
ConwayCertificate eon cert ->
235235
case eon of
236236
ConwayEraOnwardsConway -> cert
237+
ConwayEraOnwardsDijkstra -> cert
237238

238239
-- ----------------------------------------------------------------------------
239240
-- Stake pool parameters
@@ -576,6 +577,7 @@ filterUnRegCreds =
576577
Ledger.RetirePoolTxCert _ _ -> Nothing
577578
Ledger.MirTxCert _ -> Nothing
578579
Ledger.GenesisDelegTxCert{} -> Nothing
580+
_ -> error "dijkstra"
579581
ConwayCertificate cEra conwayCert -> conwayEraOnwardsConstraints cEra $
580582
case conwayCert of
581583
Ledger.RegPoolTxCert _ -> Nothing
@@ -593,6 +595,7 @@ filterUnRegCreds =
593595
Ledger.RegTxCert _ -> Nothing
594596
-- stake cred deregistration w/o deposit
595597
Ledger.UnRegTxCert cred -> Just cred
598+
_ -> error "dijkstra"
596599

597600
filterUnRegDRepCreds
598601
:: Certificate era -> Maybe (Ledger.Credential Ledger.DRepRole)
@@ -615,6 +618,7 @@ filterUnRegDRepCreds = \case
615618
Ledger.RegTxCert _ -> Nothing
616619
-- stake cred deregistration w/o deposit
617620
Ledger.UnRegTxCert _ -> Nothing
621+
_ -> error "dijkstra"
618622

619623
-- ----------------------------------------------------------------------------
620624
-- Internal conversion functions
@@ -803,6 +807,7 @@ getAnchorDataFromCertificate c =
803807
Ledger.RetirePoolTxCert _ _ -> return Nothing
804808
Ledger.GenesisDelegTxCert{} -> return Nothing
805809
Ledger.MirTxCert _ -> return Nothing
810+
_ -> error "dijkstra"
806811
ConwayCertificate ceo ccert ->
807812
conwayEraOnwardsConstraints ceo $
808813
case ccert of
@@ -819,6 +824,7 @@ getAnchorDataFromCertificate c =
819824
Ledger.UpdateDRepTxCert _ mAnchor -> return $ Ledger.strictMaybeToMaybe mAnchor
820825
Ledger.AuthCommitteeHotKeyTxCert _ _ -> return Nothing
821826
Ledger.ResignCommitteeColdTxCert _ mAnchor -> return $ Ledger.strictMaybeToMaybe mAnchor
827+
_ -> error "dijkstra"
822828
where
823829
anchorDataFromPoolMetadata
824830
:: MonadError AnchorDataFromCertificateError m

cardano-api/src/Cardano/Api/Consensus/Internal/InMode.hs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ fromConsensusGenTx = \case
100100
Consensus.HardForkGenTx (Consensus.OneEraGenTx (S (S (S (S (S (S (Z tx')))))))) ->
101101
let Consensus.ShelleyTx _txid shelleyEraTx = tx'
102102
in TxInMode ShelleyBasedEraConway (ShelleyTx ShelleyBasedEraConway shelleyEraTx)
103+
Consensus.HardForkGenTx (Consensus.OneEraGenTx (S (S (S (S (S (S (S (Z tx'))))))))) ->
104+
let Consensus.ShelleyTx _txid shelleyEraTx = tx'
105+
in TxInMode ShelleyBasedEraDijkstra (ShelleyTx ShelleyBasedEraDijkstra shelleyEraTx)
103106

104107
toConsensusGenTx
105108
:: ()
@@ -132,6 +135,10 @@ toConsensusGenTx (TxInMode ShelleyBasedEraConway (ShelleyTx _ tx)) =
132135
Consensus.HardForkGenTx (Consensus.OneEraGenTx (S (S (S (S (S (S (Z tx'))))))))
133136
where
134137
tx' = Consensus.mkShelleyTx tx
138+
toConsensusGenTx (TxInMode ShelleyBasedEraDijkstra (ShelleyTx _ tx)) =
139+
Consensus.HardForkGenTx (Consensus.OneEraGenTx (S (S (S (S (S (S (S (Z tx')))))))))
140+
where
141+
tx' = Consensus.mkShelleyTx tx
135142

136143
-- ----------------------------------------------------------------------------
137144
-- Transaction ids in the context of a consensus mode
@@ -193,6 +200,12 @@ toConsensusTxId (TxIdInMode ConwayEra txid) =
193200
where
194201
txid' :: Consensus.TxId (Consensus.GenTx Consensus.StandardConwayBlock)
195202
txid' = Consensus.ShelleyTxId $ toShelleyTxId txid
203+
toConsensusTxId (TxIdInMode DijkstraEra txid) =
204+
Consensus.HardForkGenTxId
205+
(Consensus.OneEraGenTxId (S (S (S (S (S (S (S (Z (Consensus.WrapGenTxId txid'))))))))))
206+
where
207+
txid' :: Consensus.TxId (Consensus.GenTx Consensus.StandardDijkstraBlock)
208+
txid' = Consensus.ShelleyTxId $ toShelleyTxId txid
196209

197210
-- ----------------------------------------------------------------------------
198211
-- Transaction validation errors in the context of eras and consensus modes
@@ -300,5 +313,7 @@ fromConsensusApplyTxErr = \case
300313
TxValidationErrorInCardanoMode $ ShelleyTxValidationError ShelleyBasedEraBabbage err
301314
Consensus.ApplyTxErrConway err ->
302315
TxValidationErrorInCardanoMode $ ShelleyTxValidationError ShelleyBasedEraConway err
316+
Consensus.ApplyTxErrDijkstra err ->
317+
TxValidationErrorInCardanoMode $ ShelleyTxValidationError ShelleyBasedEraDijkstra err
303318
Consensus.ApplyTxErrWrongEra err ->
304319
TxValidationEraMismatch err

cardano-api/src/Cardano/Api/Consensus/Internal/Mode.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ type family ConsensusBlockForEra era where
8383
ConsensusBlockForEra AlonzoEra = Consensus.StandardAlonzoBlock
8484
ConsensusBlockForEra BabbageEra = Consensus.StandardBabbageBlock
8585
ConsensusBlockForEra ConwayEra = Consensus.StandardConwayBlock
86+
ConsensusBlockForEra DijkstraEra = Consensus.StandardDijkstraBlock
8687

8788
type family ConsensusCryptoForBlock block where
8889
ConsensusCryptoForBlock Consensus.ByronBlockHFC = StandardCrypto
@@ -98,6 +99,7 @@ type family ConsensusProtocol era where
9899
ConsensusProtocol AlonzoEra = Consensus.TPraos StandardCrypto
99100
ConsensusProtocol BabbageEra = Consensus.Praos StandardCrypto
100101
ConsensusProtocol ConwayEra = Consensus.Praos StandardCrypto
102+
ConsensusProtocol DijkstraEra = Consensus.Praos StandardCrypto
101103

102104
type family ChainDepStateProtocol era where
103105
ChainDepStateProtocol ShelleyEra = Consensus.TPraosState
@@ -128,6 +130,9 @@ eraIndex5 = eraIndexSucc eraIndex4
128130
eraIndex6 :: Consensus.EraIndex (x6 : x5 : x4 : x3 : x2 : x1 : x0 : xs)
129131
eraIndex6 = eraIndexSucc eraIndex5
130132

133+
eraIndex7 :: Consensus.EraIndex (x7 : x6 : x5 : x4 : x3 : x2 : x1 : x0 : xs)
134+
eraIndex7 = eraIndexSucc eraIndex6
135+
131136
toConsensusEraIndex
132137
:: ()
133138
=> Consensus.CardanoBlock StandardCrypto ~ Consensus.HardForkBlock xs
@@ -141,6 +146,7 @@ toConsensusEraIndex = \case
141146
AlonzoEra -> eraIndex4
142147
BabbageEra -> eraIndex5
143148
ConwayEra -> eraIndex6
149+
DijkstraEra -> eraIndex7
144150

145151
fromConsensusEraIndex
146152
:: ()
@@ -161,3 +167,4 @@ fromConsensusEraIndex = \case
161167
AnyCardanoEra BabbageEra
162168
Consensus.EraIndex (S (S (S (S (S (S (Z (K ())))))))) ->
163169
AnyCardanoEra ConwayEra
170+
Consensus.EraIndex (S (S (S (S (S (S (S _))))))) -> error "Dijkstra"

cardano-api/src/Cardano/Api/Era/Internal/Case.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ caseByronOrShelleyBasedEra l r = \case
5252
AlonzoEra -> r ShelleyBasedEraAlonzo
5353
BabbageEra -> r ShelleyBasedEraBabbage
5454
ConwayEra -> r ShelleyBasedEraConway
55+
DijkstraEra -> r ShelleyBasedEraDijkstra
5556

5657
-- | @caseByronToAlonzoOrBabbageEraOnwards f g era@ applies @f@ to byron, shelley, allegra, mary, and alonzo;
5758
-- and @g@ to babbage and later eras.
@@ -69,6 +70,7 @@ caseByronToAlonzoOrBabbageEraOnwards l r = \case
6970
AlonzoEra -> l ByronToAlonzoEraAlonzo
7071
BabbageEra -> r BabbageEraOnwardsBabbage
7172
ConwayEra -> r BabbageEraOnwardsConway
73+
DijkstraEra -> r BabbageEraOnwardsDijkstra
7274

7375
-- | @caseShelleyEraOnlyOrAllegraEraOnwards f g era@ applies @f@ to shelley;
7476
-- and applies @g@ to allegra and later eras.
@@ -85,6 +87,7 @@ caseShelleyEraOnlyOrAllegraEraOnwards l r = \case
8587
ShelleyBasedEraAlonzo -> r AllegraEraOnwardsAlonzo
8688
ShelleyBasedEraBabbage -> r AllegraEraOnwardsBabbage
8789
ShelleyBasedEraConway -> r AllegraEraOnwardsConway
90+
ShelleyBasedEraDijkstra -> r AllegraEraOnwardsDijkstra
8891

8992
-- | @caseShelleyToAllegraOrMaryEraOnwards f g era@ applies @f@ to shelley and allegra;
9093
-- and applies @g@ to mary and later eras.
@@ -101,6 +104,7 @@ caseShelleyToAllegraOrMaryEraOnwards l r = \case
101104
ShelleyBasedEraAlonzo -> r MaryEraOnwardsAlonzo
102105
ShelleyBasedEraBabbage -> r MaryEraOnwardsBabbage
103106
ShelleyBasedEraConway -> r MaryEraOnwardsConway
107+
ShelleyBasedEraDijkstra -> r MaryEraOnwardsDijkstra
104108

105109
-- | @caseShelleyToMaryOrAlonzoEraOnwards f g era@ applies @f@ to shelley, allegra, and mary;
106110
-- and applies @g@ to alonzo and later eras.
@@ -117,6 +121,7 @@ caseShelleyToMaryOrAlonzoEraOnwards l r = \case
117121
ShelleyBasedEraAlonzo -> r AlonzoEraOnwardsAlonzo
118122
ShelleyBasedEraBabbage -> r AlonzoEraOnwardsBabbage
119123
ShelleyBasedEraConway -> r AlonzoEraOnwardsConway
124+
ShelleyBasedEraDijkstra -> r AlonzoEraOnwardsDijkstra
120125

121126
-- | @caseShelleyToAlonzoOrBabbageEraOnwards f g era@ applies @f@ to shelley, allegra, mary, and alonzo;
122127
-- and applies @g@ to babbage and later eras.
@@ -133,6 +138,7 @@ caseShelleyToAlonzoOrBabbageEraOnwards l r = \case
133138
ShelleyBasedEraAlonzo -> l ShelleyToAlonzoEraAlonzo
134139
ShelleyBasedEraBabbage -> r BabbageEraOnwardsBabbage
135140
ShelleyBasedEraConway -> r BabbageEraOnwardsConway
141+
ShelleyBasedEraDijkstra -> r BabbageEraOnwardsDijkstra
136142

137143
-- | @caseShelleyToBabbageOrConwayEraOnwards f g era@ applies @f@ to eras before conway;
138144
-- and applies @g@ to conway and later eras.
@@ -149,6 +155,7 @@ caseShelleyToBabbageOrConwayEraOnwards l r = \case
149155
ShelleyBasedEraAlonzo -> l ShelleyToBabbageEraAlonzo
150156
ShelleyBasedEraBabbage -> l ShelleyToBabbageEraBabbage
151157
ShelleyBasedEraConway -> r ConwayEraOnwardsConway
158+
ShelleyBasedEraDijkstra -> r ConwayEraOnwardsDijkstra
152159

153160
{-# DEPRECATED shelleyToAlonzoEraToShelleyToBabbageEra "Use convert instead" #-}
154161
shelleyToAlonzoEraToShelleyToBabbageEra
@@ -170,6 +177,7 @@ alonzoEraOnwardsToMaryEraOnwards = \case
170177
AlonzoEraOnwardsAlonzo -> MaryEraOnwardsAlonzo
171178
AlonzoEraOnwardsBabbage -> MaryEraOnwardsBabbage
172179
AlonzoEraOnwardsConway -> MaryEraOnwardsConway
180+
AlonzoEraOnwardsDijkstra -> MaryEraOnwardsDijkstra
173181

174182
{-# DEPRECATED babbageEraOnwardsToMaryEraOnwards "Use convert instead" #-}
175183
babbageEraOnwardsToMaryEraOnwards
@@ -179,6 +187,7 @@ babbageEraOnwardsToMaryEraOnwards
179187
babbageEraOnwardsToMaryEraOnwards = \case
180188
BabbageEraOnwardsBabbage -> MaryEraOnwardsBabbage
181189
BabbageEraOnwardsConway -> MaryEraOnwardsConway
190+
BabbageEraOnwardsDijkstra -> MaryEraOnwardsDijkstra
182191

183192
{-# DEPRECATED babbageEraOnwardsToAlonzoEraOnwards "Use convert instead" #-}
184193
babbageEraOnwardsToAlonzoEraOnwards
@@ -188,3 +197,4 @@ babbageEraOnwardsToAlonzoEraOnwards
188197
babbageEraOnwardsToAlonzoEraOnwards = \case
189198
BabbageEraOnwardsBabbage -> AlonzoEraOnwardsBabbage
190199
BabbageEraOnwardsConway -> AlonzoEraOnwardsConway
200+
BabbageEraOnwardsDijkstra -> AlonzoEraOnwardsDijkstra

cardano-api/src/Cardano/Api/Era/Internal/Core.hs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ module Cardano.Api.Era.Internal.Core
1919
, AlonzoEra
2020
, BabbageEra
2121
, ConwayEra
22+
, DijkstraEra
2223

2324
-- * CardanoEra
2425
, CardanoEra (..)
@@ -87,6 +88,9 @@ data BabbageEra
8788
-- | A type used as a tag to distinguish the Conway era.
8889
data ConwayEra
8990

91+
-- | A type used as a tag to distinguish the DijkstraEra era.
92+
data DijkstraEra
93+
9094
instance HasTypeProxy ByronEra where
9195
data AsType ByronEra = AsByronEra
9296
proxyToAsType _ = AsByronEra
@@ -115,6 +119,10 @@ instance HasTypeProxy ConwayEra where
115119
data AsType ConwayEra = AsConwayEra
116120
proxyToAsType _ = AsConwayEra
117121

122+
instance HasTypeProxy DijkstraEra where
123+
data AsType DijkstraEra = AsDijkstraEra
124+
proxyToAsType _ = AsDijkstraEra
125+
118126
-- ----------------------------------------------------------------------------
119127
-- Eon
120128

@@ -263,6 +271,7 @@ data CardanoEra era where
263271
AlonzoEra :: CardanoEra AlonzoEra
264272
BabbageEra :: CardanoEra BabbageEra
265273
ConwayEra :: CardanoEra ConwayEra
274+
DijkstraEra :: CardanoEra DijkstraEra
266275

267276
-- when you add era here, change `instance Bounded AnyCardanoEra`
268277

@@ -321,6 +330,9 @@ instance IsCardanoEra BabbageEra where
321330
instance IsCardanoEra ConwayEra where
322331
cardanoEra = ConwayEra
323332

333+
instance IsCardanoEra DijkstraEra where
334+
cardanoEra = DijkstraEra
335+
324336
type CardanoEraConstraints era =
325337
( Typeable era
326338
, IsCardanoEra era
@@ -339,6 +351,7 @@ cardanoEraConstraints = \case
339351
AlonzoEra -> id
340352
BabbageEra -> id
341353
ConwayEra -> id
354+
DijkstraEra -> id
342355

343356
data AnyCardanoEra where
344357
AnyCardanoEra
@@ -372,6 +385,7 @@ instance Enum AnyCardanoEra where
372385
AnyCardanoEra AlonzoEra -> 4
373386
AnyCardanoEra BabbageEra -> 5
374387
AnyCardanoEra ConwayEra -> 6
388+
AnyCardanoEra DijkstraEra -> 7
375389

376390
toEnum = \case
377391
0 -> AnyCardanoEra ByronEra
@@ -409,6 +423,7 @@ cardanoEraToStringLike = \case
409423
AlonzoEra -> "Alonzo"
410424
BabbageEra -> "Babbage"
411425
ConwayEra -> "Conway"
426+
DijkstraEra -> "Dijkstra"
412427

413428
anyCardanoEraFromStringLike :: (IsString a, Eq a) => a -> Either a AnyCardanoEra
414429
{-# INLINE anyCardanoEraFromStringLike #-}
@@ -433,6 +448,7 @@ anyCardanoEra = \case
433448
AlonzoEra -> AnyCardanoEra AlonzoEra
434449
BabbageEra -> AnyCardanoEra BabbageEra
435450
ConwayEra -> AnyCardanoEra ConwayEra
451+
DijkstraEra -> AnyCardanoEra DijkstraEra
436452

437453
-- | This pairs up some era-dependent type with a 'CardanoEra' value that tells
438454
-- us what era it is, but hides the era type. This is useful when the era is

0 commit comments

Comments
 (0)