Skip to content

Commit 294247f

Browse files
authored
Merge pull request #5411 from IntersectMBO/f-f/fix-5387
Switch to using `TypeData` extension
2 parents d120d96 + ade88fb commit 294247f

File tree

216 files changed

+1441
-1433
lines changed

Some content is hidden

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

216 files changed

+1441
-1433
lines changed

docs/reward-calculation/HowRewardCalculationWorks.md

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ Rewards are paid at each epoch boundary. An epoch is roughly 5 days, so rewards
2727
What data must be available to compute rewards.
2828

2929
1. The UTxO. Each `UTxO` entry records
30-
- The entry owner. This is a Haskell datatype (Credential 'Staking), which is a cryptographic hash of the owner's identity
30+
- The entry owner. This is a Haskell datatype (Credential Staking), which is a cryptographic hash of the owner's identity
3131
- The amount of the entry in Coin. This is always non-zero and positive.
3232
- Staking information about which Pool (if any) the UTxO entry is delegated to. This may be deliberately left blank, or it is
3333
a Haskell datatype (KeyHash 'Pool), which is another cryptographic hash, this time of the Pool owner's identity
3434
- Other information not related to the Reward calculation
3535

3636
2. Information about which staking credentials are registered to participate in staking, and which Pool they delegate to.
37-
This is a Haskell Datatype (Map (Credential 'Staking) (KeyHash StakePool)), which we will call the `stakeDelegationMap`.
37+
This is a Haskell Datatype (Map (Credential Staking) (KeyHash StakePool)), which we will call the `stakeDelegationMap`.
3838
Only registered credentials will receive rewards.
3939

4040
3. Information about which pool operators are currently registered to operate pools, and the parameters under which the pools operate.
@@ -50,14 +50,14 @@ how it might be computed in the ShelleyEra. Other eras would be very similar, bu
5050
fields than just the Addr and Coin.
5151

5252

53-
1. Aggregate the total `Coin` in the `UTxO` for each (Credential 'Staking) that appears somewhere in the UTxO, resulting in
54-
a (Map (Credential 'Staking) Coin). This only requires the UTxO. At this point we do not care if the Credential is registered
53+
1. Aggregate the total `Coin` in the `UTxO` for each (Credential Staking) that appears somewhere in the UTxO, resulting in
54+
a (Map (Credential Staking) Coin). This only requires the UTxO. At this point we do not care if the Credential is registered
5555
in the `stakeDelegationMap` . We call this the `aggregateStakeMap` .
5656

5757
```
5858
-- | Loop through all the TxOut in the UTxO, if the Addr in the TxOut has a `StakeRefBase` credential
5959
-- then add the (cred,coin) pair to the answer map.
60-
aggregateStakeMap :: UTxO ShelleyEra -> Map (Credential 'Staking) Coin
60+
aggregateStakeMap :: UTxO ShelleyEra -> Map (Credential Staking) Coin
6161
aggregateStakeMap (UTxO utxoMap) = loop (Map.toList utxoMap) Map.empty
6262
where loop ((_,ShelleyTxOut @ShelleyEra (Addr _network _payCred stakeRef) coin):more) aggrAns =
6363
case stakeRef of
@@ -68,16 +68,16 @@ aggregateStakeMap (UTxO utxoMap) = loop (Map.toList utxoMap) Map.empty
6868

6969

7070
2. For each pool operator compute the set of Credentials that delegate stake to that pool, resulting in
71-
a (Map (KeyHash 'StakePool) (Set (Credential 'Staking))). This requires the UTxO and the stakeDelegationMap.
71+
a (Map (KeyHash StakePool) (Set (Credential Staking))). This requires the UTxO and the stakeDelegationMap.
7272
At this point we don't care if the pool is registered in the `poolParamsNap`. This is called the `whoPaysMap`.
7373

7474
```
7575
-- | Loop through all the TxOut in the UTxO, if the Addr in the TxOut has a `StakeRefBase` credential
7676
-- then lookup if that credential delegates to some Pool, if it does, add the credential
7777
-- to the answer map for that Pool.
7878
whoPaysMap :: UTxO ShelleyEra ->
79-
Map (Credential 'Staking) (KeyHash StakePool) ->
80-
Map (KeyHash 'StakePool) (Set (Credential 'Staking))
79+
Map (Credential Staking) (KeyHash StakePool) ->
80+
Map (KeyHash StakePool) (Set (Credential Staking))
8181
whoPaysMap (UTxO utxoMap) stakeDelegationMap = loop (Map.toList utxoMap) Map.empty
8282
where loop ((_,ShelleyTxOut @ShelleyEra (Addr _network _payCred stakeRef) coin):more) aggrAns =
8383
case stakeRef of
@@ -89,13 +89,13 @@ whoPaysMap (UTxO utxoMap) stakeDelegationMap = loop (Map.toList utxoMap) Map.emp
8989
```
9090

9191
3. Aggregate the total Coin delegated by registered credentials to each registered Pool, resulting in
92-
(Map (KeyHash 'StakePool) Coin). This requires the results from steps 1 and 2. This is called the `stakeDistributionMap`.
92+
(Map (KeyHash StakePool) Coin). This requires the results from steps 1 and 2. This is called the `stakeDistributionMap`.
9393
This will not be used in the rest of the Reward calculation, but will be used to compute the ercentage of stake controlled by each pool, to choose Pools to make blocks in a following epoch.
9494

9595
```
96-
stakeDistrMap :: Map (KeyHash 'StakePool) (Set (Credential 'Staking)) ->
97-
Map (Credential 'Staking) Coin ->
98-
Map (KeyHash 'StakePool) Coin
96+
stakeDistrMap :: Map (KeyHash StakePool) (Set (Credential Staking)) ->
97+
Map (Credential Staking) Coin ->
98+
Map (KeyHash StakePool) Coin
9999
stakeDistrMap whoPaysMap aggregateStakeMap = Map.map setCredToCoin whoPaysMap
100100
where setCredToCoin :: Set (Credential Staking) -> Coin
101101
setCredToCoin set = loop (Set.toList set) (Coin 0)
@@ -108,7 +108,7 @@ stakeDistrMap whoPaysMap aggregateStakeMap = Map.map setCredToCoin whoPaysMap
108108

109109
4. For each Pool in the domain of `whoPaysMap`, and each Credential in the range, compute a Reward owed to that Credential by that Pool,
110110
resulting in (Set Reward). This requires the `whoPaysMap` the `poolParamMap`, the `stakeDelegationMap`, and the `aggregateStakeMap`, because the amount in the reward depends on the PoolParameters of the Pool and the Coin amount delegated by that Credential to that Pool. We must also check
111-
that each (Credential 'Staking) and (KeyHash 'StakePool) are currently registered, to make a valid Reward.
111+
that each (Credential Staking) and (KeyHash StakePool) are currently registered, to make a valid Reward.
112112
[Source code for computing a Reward from Coin and PoolParam values.](https://github.com/IntersectMBO/cardano-ledger/blob/a7fb33a2b2922933eb6dd7e2420363291f6d4903/eras/shelley/impl/src/Cardano/Ledger/Shelley/Rewards.hs#L260)
113113
[Source code for `rewardStakePoolMember`](https://github.com/IntersectMBO/cardano-ledger/blob/a7fb33a2b2922933eb6dd7e2420363291f6d4903/eras/shelley/impl/src/Cardano/Ledger/Shelley/RewardUpdate.hs#L251)
114114

@@ -159,27 +159,27 @@ the amount of money in a bank deposit. Here are the basic data structures that e
159159
mkBasicTxOut :: Addr -> Value era -> TxOut era
160160
161161
data StakeReference
162-
= StakeRefBase !(Credential 'Staking)
162+
= StakeRefBase !(Credential Staking)
163163
| StakeRefPtr !Ptr -- Ptr are no longer allowed in the Conway and later Eras
164164
| StakeRefNull
165165
166166
167167
data Addr
168-
= Addr Network (Credential 'Payment) StakeReference
168+
= Addr Network (Credential Payment) StakeReference
169169
| AddrBootstrap BootstrapAddress
170170
-- `AddrBootstrap` has an implicit `StakeRefNull` StakeReference
171171
-- No (Credential `Staking) are delegated in a AddrBootstrap
172172
173173
data RewardAccount = RewardAccount
174174
{ raNetwork :: !Network
175-
, raCredential :: !(Credential 'Staking)
175+
, raCredential :: !(Credential Staking)
176176
}
177177
178178
```
179179

180-
In order for rewards to be paid, the (Credential 'Staking) must be associated with two things
180+
In order for rewards to be paid, the (Credential Staking) must be associated with two things
181181

182-
1. A `(KeyHash 'StakePool)`. The hash of the entity that will pay the reward
182+
1. A `(KeyHash StakePool)`. The hash of the entity that will pay the reward
183183
2. A `RewardAccount`. Information about where to store the reward
184184

185185
The `StakePool` must also be associated with a Pool operator for rewards to be paid.
@@ -191,9 +191,9 @@ The actual values are stored in internal maps found in the type family `CertStat
191191

192192
```
193193
194-
Map (Credential 'Staking) (StrictMaybe (KeyHash 'StakePool)) -- The User registration map
195-
Map (Credential 'Staking) Coin -- The User Rewards map
196-
Map (KeyHash 'StakePool) PoolParams -- The StakePool registration map
194+
Map (Credential Staking) (StrictMaybe (KeyHash StakePool)) -- The User registration map
195+
Map (Credential Staking) Coin -- The User Rewards map
196+
Map (KeyHash StakePool) PoolParams -- The StakePool registration map
197197
```
198198

199199
A `Reward` contains information about a computed reward, that has yet to be applied to the internal Rewards map.
@@ -204,7 +204,7 @@ data RewardType = MemberReward -- A User
204204
205205
data Reward = Reward
206206
{ rewardType :: !RewardType -- to be paid to a User or a StakePool operator
207-
, rewardPool :: !(KeyHash 'StakePool) -- which Stakepool operator will pay this reward
207+
, rewardPool :: !(KeyHash StakePool) -- which Stakepool operator will pay this reward
208208
, rewardAmount :: !Coin -- the amount of the reward.
209209
}
210210
```
@@ -214,24 +214,24 @@ The Reward calculation has several parts
214214
1. Sum the total `Coin` for each unique `StakeReference` in the `UTxO`
215215

216216
```
217-
UTxO era -> Map (Credential 'Staking) Coin
217+
UTxO era -> Map (Credential Staking) Coin
218218
```
219219
220220
2. For each `StakePool` compute the set of `StakeReference` that delegate stake to that pool.
221221
222222
```
223-
Map (KeyHash 'StakePool) (Set (Credential 'Staking))
223+
Map (KeyHash StakePool) (Set (Credential Staking))
224224
```
225225
226226
3. For each pool and each stake reference to that pool, compute a `Reward` for that reference
227227
228228
```
229-
Map (Credential 'Staking) (Set Reward)
229+
Map (Credential Staking) (Set Reward)
230230
231231
4. Pay the rewards for every pool and stake reference
232232
233233
```
234-
Map (Credential 'Staking) (Set Reward) -> EpochState era -> EpochState era
234+
Map (Credential Staking) (Set Reward) -> EpochState era -> EpochState era
235235
````
236236
237237
## What makes it complicated and hard
@@ -250,7 +250,7 @@ In order to address this problem the reward calculation uses several strategies.
250250
1. Use incremental computation to compute the changes to the UTxO and total coin for each StakeReference
251251
in lock step, so step one is not necessary. We call this the "InstantStake" calculation, as it computes
252252
two different things (both stored in the UTxOState) simultaneously
253-
- The InstantStake `(Map (Credential 'Staking) Coin)
253+
- The InstantStake `(Map (Credential Staking) Coin)
254254
- The UTxO
255255
256256
There are strong invariants that must be maintained between these two maps.
@@ -272,7 +272,7 @@ We look closely at each of these strategies in turn, studying the data structure
272272
273273
## The InstantStake strategy.
274274
275-
This strategy computes the InstantStake `(Map (Credential 'Staking) Coin)` and the `UTxO` simultaneously.
275+
This strategy computes the InstantStake `(Map (Credential Staking) Coin)` and the `UTxO` simultaneously.
276276
It is an instance of incremental computation, as the InstantStake is a pure function of the `UTxO`.
277277
It works by observing every change to the `UTxO`, and if that change could alter the `InstantStake`, it makes
278278
corresponding changes to the InstantStake that keep the two in lockstep. The `UTxO` and the `InstantStake` are
@@ -362,7 +362,7 @@ later, when we know what the address the `Ptr` points to.
362362
363363
```
364364
data ShelleyInstantStake era = ShelleyInstantStake
365-
{ sisCredentialStake :: !(Map.Map (Credential 'Staking) (CompactForm Coin))
365+
{ sisCredentialStake :: !(Map.Map (Credential Staking) (CompactForm Coin))
366366
, sisPtrStake :: !(Map.Map Ptr (CompactForm Coin))
367367
}
368368
```
@@ -436,7 +436,7 @@ is simpler, since it does not need the Map of `Ptrs` that need to be resolved.
436436
437437
```
438438
newtype ConwayInstantStake era = ConwayInstantStake
439-
{ cisCredentialStake :: Map.Map (Credential 'Staking) (CompactForm Coin)
439+
{ cisCredentialStake :: Map.Map (Credential Staking) (CompactForm Coin)
440440
}
441441
```
442442
@@ -533,12 +533,12 @@ is `RewardAns` which has two maps as components
533533
534534
535535
```
536-
type RewardEvent = Map (Credential 'Staking) (Set Reward)
536+
type RewardEvent = Map (Credential Staking) (Set Reward)
537537

538538
-- | The result of reward calculation is a pair of aggregate Maps.
539539
-- One for the accumulated answer, and one for the answer since the last pulse
540540
data RewardAns = RewardAns
541-
{ accumRewardAns :: !(Map (Credential 'Staking) Reward)
541+
{ accumRewardAns :: !(Map (Credential Staking) Reward)
542542
, recentRewardAns :: !RewardEvent
543543
}
544544
```
@@ -560,7 +560,7 @@ data RewardPulser (m :: Type -> Type) ans where
560560
(ans ~ RewardAns, m ~ ShelleyBase) =>
561561
!Int ->
562562
!FreeVars ->
563-
!(VMap.VMap VMap.VB VMap.VP (Credential 'Staking) (CompactForm Coin)) ->
563+
!(VMap.VMap VMap.VB VMap.VP (Credential Staking) (CompactForm Coin)) ->
564564
!ans ->
565565
RewardPulser m ans
566566

@@ -701,4 +701,4 @@ rupdTransition = do
701701
tellRupd "Completing too late" (RupdEvent (succ e) event)
702702
pure (SJust reward)
703703
complete@(SJust (Complete _)) -> pure complete
704-
```
704+
```

eras/allegra/impl/src/Cardano/Ledger/Allegra/Rules/Utxo.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ data AllegraUtxoPredFailure era
7373
| OutsideValidityIntervalUTxO
7474
ValidityInterval -- transaction's validity interval
7575
SlotNo -- current slot
76-
| MaxTxSizeUTxO (Mismatch 'RelLTEQ Word32)
76+
| MaxTxSizeUTxO (Mismatch RelLTEQ Word32)
7777
| InputSetEmptyUTxO
78-
| FeeTooSmallUTxO (Mismatch 'RelGTEQ Coin)
79-
| ValueNotConservedUTxO (Mismatch 'RelEQ (Value era)) -- Consumed, then produced
78+
| FeeTooSmallUTxO (Mismatch RelGTEQ Coin)
79+
| ValueNotConservedUTxO (Mismatch RelEQ (Value era)) -- Consumed, then produced
8080
| WrongNetwork
8181
Network -- the expected network id
8282
(Set Addr) -- the set of addresses with incorrect network IDs

eras/allegra/impl/src/Cardano/Ledger/Allegra/Scripts.hs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,13 @@ invalidBeforeL = lens invalidBefore (\vi before -> vi {invalidBefore = before})
130130
invalidHereAfterL :: Lens' ValidityInterval (StrictMaybe SlotNo)
131131
invalidHereAfterL = lens invalidHereafter (\vi hereAfter -> vi {invalidHereafter = hereAfter})
132132

133-
encodeVI :: ValidityInterval -> Encode ('Closed 'Dense) ValidityInterval
133+
encodeVI :: ValidityInterval -> Encode (Closed Dense) ValidityInterval
134134
encodeVI (ValidityInterval f t) = Rec ValidityInterval !> To f !> To t
135135

136136
instance EncCBOR ValidityInterval where
137137
encCBOR vi = encode (encodeVI vi)
138138

139-
decodeVI :: Decode ('Closed 'Dense) ValidityInterval
139+
decodeVI :: Decode (Closed Dense) ValidityInterval
140140
decodeVI = RecD ValidityInterval <! From <! From
141141

142142
instance DecCBOR ValidityInterval where
@@ -155,7 +155,7 @@ instance ToJSON ValidityInterval where
155155
-- ==================================================================
156156

157157
data TimelockRaw era
158-
= TimelockSignature !(KeyHash 'Witness)
158+
= TimelockSignature !(KeyHash Witness)
159159
| TimelockAllOf !(StrictSeq (Timelock era)) -- NOTE that Timelock and
160160
| TimelockAnyOf !(StrictSeq (Timelock era)) -- TimelockRaw are mutually recursive.
161161
| TimelockMOf !Int !(StrictSeq (Timelock era))
@@ -213,7 +213,7 @@ instance Era era => EncCBOR (TimelockRaw era) where
213213
instance Era era => DecCBOR (Annotator (TimelockRaw era)) where
214214
decCBOR = decode (Summands "TimelockRaw" decRaw)
215215
where
216-
decRaw :: Word -> Decode 'Open (Annotator (TimelockRaw era))
216+
decRaw :: Word -> Decode Open (Annotator (TimelockRaw era))
217217
decRaw 0 = Ann (SumD TimelockSignature <! From)
218218
decRaw 1 = Ann (SumD TimelockAllOf) <*! D (sequence <$> decCBOR)
219219
decRaw 2 = Ann (SumD TimelockAnyOf) <*! D (sequence <$> decCBOR)
@@ -355,10 +355,10 @@ pattern RequireTimeStart mslot <- (getTimeStart -> Just mslot)
355355
ConwayEra
356356
#-}
357357

358-
mkRequireSignatureTimelock :: forall era. Era era => KeyHash 'Witness -> Timelock era
358+
mkRequireSignatureTimelock :: forall era. Era era => KeyHash Witness -> Timelock era
359359
mkRequireSignatureTimelock = mkMemoizedEra @era . TimelockSignature
360360

361-
getRequireSignatureTimelock :: Timelock era -> Maybe (KeyHash 'Witness)
361+
getRequireSignatureTimelock :: Timelock era -> Maybe (KeyHash Witness)
362362
getRequireSignatureTimelock (MkTimelock (Memo (TimelockSignature kh) _)) = Just kh
363363
getRequireSignatureTimelock _ = Nothing
364364

@@ -412,7 +412,7 @@ ltePosInfty (SJust i) j = i <= j
412412

413413
evalTimelock ::
414414
(AllegraEraScript era, NativeScript era ~ Timelock era) =>
415-
Set.Set (KeyHash 'Witness) ->
415+
Set.Set (KeyHash Witness) ->
416416
ValidityInterval ->
417417
NativeScript era ->
418418
Bool

eras/allegra/impl/testlib/Test/Cardano/Ledger/Allegra/ImpTest.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import qualified Data.Set as Set
3232
import Lens.Micro ((^.))
3333
import Test.Cardano.Ledger.Allegra.Era ()
3434
import Test.Cardano.Ledger.Allegra.TreeDiff ()
35-
import Test.Cardano.Ledger.Imp.Common
35+
import Test.Cardano.Ledger.Imp.Common (KeyPair (..), choose, frequency)
3636
import Test.Cardano.Ledger.Shelley.ImpTest
3737

3838
instance ShelleyEraImp AllegraEra where
@@ -51,10 +51,10 @@ impAllegraSatisfyNativeScript ::
5151
, AllegraEraTxBody era
5252
, NativeScript era ~ Timelock era
5353
) =>
54-
Set.Set (KeyHash 'Witness) ->
54+
Set.Set (KeyHash Witness) ->
5555
TxBody l era ->
5656
NativeScript era ->
57-
ImpTestM era (Maybe (Map.Map (KeyHash 'Witness) (KeyPair 'Witness)))
57+
ImpTestM era (Maybe (Map.Map (KeyHash Witness) (KeyPair Witness)))
5858
impAllegraSatisfyNativeScript providedVKeyHashes txBody script = do
5959
let vi = txBody ^. vldtTxBodyL
6060
case script of

eras/alonzo/impl/src/Cardano/Ledger/Alonzo/Rules/Bbody.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ import NoThunks.Class (NoThunks (..))
8080

8181
data AlonzoBbodyPredFailure era
8282
= ShelleyInAlonzoBbodyPredFailure (ShelleyBbodyPredFailure era)
83-
| TooManyExUnits (Mismatch 'RelLTEQ ExUnits)
83+
| TooManyExUnits (Mismatch RelLTEQ ExUnits)
8484
deriving (Generic)
8585

8686
newtype AlonzoBbodyEvent era

eras/alonzo/impl/src/Cardano/Ledger/Alonzo/Rules/Utxo.hs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ data AlonzoUtxoPredFailure era
126126
ValidityInterval
127127
-- | current slot
128128
SlotNo
129-
| MaxTxSizeUTxO (Mismatch 'RelLTEQ Word32)
129+
| MaxTxSizeUTxO (Mismatch RelLTEQ Word32)
130130
| InputSetEmptyUTxO
131-
| FeeTooSmallUTxO (Mismatch 'RelGTEQ Coin)
132-
| ValueNotConservedUTxO (Mismatch 'RelEQ (Value era))
131+
| FeeTooSmallUTxO (Mismatch RelGTEQ Coin)
132+
| ValueNotConservedUTxO (Mismatch RelEQ (Value era))
133133
| -- | the set of addresses with incorrect network IDs
134134
WrongNetwork
135135
-- | the expected network id
@@ -160,16 +160,16 @@ data AlonzoUtxoPredFailure era
160160
| -- | The UTxO entries which have the wrong kind of script
161161
ScriptsNotPaidUTxO
162162
(UTxO era)
163-
| ExUnitsTooBigUTxO (Mismatch 'RelLTEQ ExUnits)
163+
| ExUnitsTooBigUTxO (Mismatch RelLTEQ ExUnits)
164164
| -- | The inputs marked for use as fees contain non-ADA tokens
165165
CollateralContainsNonADA (Value era)
166166
| -- | Wrong Network ID in body
167-
WrongNetworkInTxBody (Mismatch 'RelEQ Network)
167+
WrongNetworkInTxBody (Mismatch RelEQ Network)
168168
| -- | slot number outside consensus forecast range
169169
OutsideForecast
170170
SlotNo
171171
| -- | There are too many collateral inputs
172-
TooManyCollateralInputs (Mismatch 'RelLTEQ Natural)
172+
TooManyCollateralInputs (Mismatch RelLTEQ Natural)
173173
| NoCollateralInputs
174174
deriving (Generic)
175175

@@ -621,7 +621,7 @@ encFail ::
621621
, EncCBOR (PredicateFailure (EraRule "UTXOS" era))
622622
) =>
623623
AlonzoUtxoPredFailure era ->
624-
Encode 'Open (AlonzoUtxoPredFailure era)
624+
Encode Open (AlonzoUtxoPredFailure era)
625625
encFail (BadInputsUTxO ins) =
626626
Sum (BadInputsUTxO @era) 0 !> To ins
627627
encFail (OutsideValidityIntervalUTxO a b) =
@@ -670,7 +670,7 @@ decFail ::
670670
, DecCBOR (PredicateFailure (EraRule "UTXOS" era))
671671
) =>
672672
Word ->
673-
Decode 'Open (AlonzoUtxoPredFailure era)
673+
Decode Open (AlonzoUtxoPredFailure era)
674674
decFail 0 = SumD BadInputsUTxO <! From
675675
decFail 1 = SumD OutsideValidityIntervalUTxO <! From <! From
676676
decFail 2 = SumD MaxTxSizeUTxO <! From

0 commit comments

Comments
 (0)