Skip to content

Commit

Permalink
Add conway-specific certs to deposit/refunds (#3700)
Browse files Browse the repository at this point in the history
* Add conway-specific certs to deposit/refunds

* A cleaner way to deal with deposits/refunds cross eras

* Deprecate is(De)RegKey in favour of is(Un)RegStakeTxCert

* Update changelogs

* Revert is(De)RegKey

---------

Co-authored-by: Alexey Kuleshevich <[email protected]>
  • Loading branch information
aniketd and lehins authored Sep 6, 2023
1 parent 5d04a8c commit 16a9090
Show file tree
Hide file tree
Showing 15 changed files with 109 additions and 27 deletions.
8 changes: 8 additions & 0 deletions eras/allegra/impl/src/Cardano/Ledger/Allegra/TxCert.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wno-orphans #-}

Expand Down Expand Up @@ -28,6 +29,13 @@ instance Crypto c => EraTxCert (AllegraEra c) where
getRetirePoolTxCert (ShelleyTxCertPool (RetirePool poolId epochNo)) = Just (poolId, epochNo)
getRetirePoolTxCert _ = Nothing

lookupRegStakeTxCert = \case
RegTxCert c -> Just c
_ -> Nothing
lookupUnRegStakeTxCert = \case
UnRegTxCert c -> Just c
_ -> Nothing

instance Crypto c => ShelleyEraTxCert (AllegraEra c) where
{-# SPECIALIZE instance ShelleyEraTxCert (AllegraEra StandardCrypto) #-}

Expand Down
9 changes: 9 additions & 0 deletions eras/alonzo/impl/src/Cardano/Ledger/Alonzo/TxCert.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wno-orphans #-}

Expand Down Expand Up @@ -28,6 +30,13 @@ instance Crypto c => EraTxCert (AlonzoEra c) where
getRetirePoolTxCert (ShelleyTxCertPool (RetirePool poolId epochNo)) = Just (poolId, epochNo)
getRetirePoolTxCert _ = Nothing

lookupRegStakeTxCert = \case
RegTxCert c -> Just c
_ -> Nothing
lookupUnRegStakeTxCert = \case
UnRegTxCert c -> Just c
_ -> Nothing

instance Crypto c => ShelleyEraTxCert (AlonzoEra c) where
{-# SPECIALIZE instance ShelleyEraTxCert (AlonzoEra StandardCrypto) #-}

Expand Down
8 changes: 8 additions & 0 deletions eras/babbage/impl/src/Cardano/Ledger/Babbage/TxCert.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wno-orphans #-}

Expand Down Expand Up @@ -28,6 +29,13 @@ instance Crypto c => EraTxCert (BabbageEra c) where
getRetirePoolTxCert (ShelleyTxCertPool (RetirePool poolId epochNo)) = Just (poolId, epochNo)
getRetirePoolTxCert _ = Nothing

lookupRegStakeTxCert = \case
RegTxCert c -> Just c
_ -> Nothing
lookupUnRegStakeTxCert = \case
UnRegTxCert c -> Just c
_ -> Nothing

instance Crypto c => ShelleyEraTxCert (BabbageEra c) where
{-# SPECIALIZE instance ShelleyEraTxCert (BabbageEra StandardCrypto) #-}

Expand Down
1 change: 1 addition & 0 deletions eras/conway/impl/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

## 1.8.0.0

* Add all Conway `TxCert` to consumed/produced calculations in the `UTXO` rule. #3700
* Change `ToJSONKey` implementation of `Voter` to flat text
* Add DRep refund calculation #3688
* Add `conwayConsumedValue` as `getConsumedValue` for Conway
Expand Down
10 changes: 10 additions & 0 deletions eras/conway/impl/src/Cardano/Ledger/Conway/TxCert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ instance Crypto c => EraTxCert (ConwayEra c) where
getRetirePoolTxCert (ConwayTxCertPool (RetirePool poolId epochNo)) = Just (poolId, epochNo)
getRetirePoolTxCert _ = Nothing

lookupRegStakeTxCert = \case
RegTxCert c -> Just c
RegDepositTxCert c _ -> Just c
RegDepositDelegTxCert c _ _ -> Just c
_ -> Nothing
lookupUnRegStakeTxCert = \case
UnRegTxCert c -> Just c
UnRegDepositTxCert c _ -> Just c
_ -> Nothing

instance Crypto c => ShelleyEraTxCert (ConwayEra c) where
mkRegTxCert c = ConwayTxCertDeleg $ ConwayRegCert c SNothing

Expand Down
11 changes: 11 additions & 0 deletions eras/mary/impl/src/Cardano/Ledger/Mary/TxCert.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wno-orphans #-}

Expand All @@ -14,6 +16,8 @@ import Cardano.Ledger.Shelley.TxCert (
getScriptWitnessShelleyTxCert,
getVKeyWitnessShelleyTxCert,
upgradeShelleyTxCert,
pattern RegTxCert,
pattern UnRegTxCert,
)

instance Crypto c => EraTxCert (MaryEra c) where
Expand All @@ -37,6 +41,13 @@ instance Crypto c => EraTxCert (MaryEra c) where
getRetirePoolTxCert (ShelleyTxCertPool (RetirePool poolId epochNo)) = Just (poolId, epochNo)
getRetirePoolTxCert _ = Nothing

lookupRegStakeTxCert = \case
RegTxCert c -> Just c
_ -> Nothing
lookupUnRegStakeTxCert = \case
UnRegTxCert c -> Just c
_ -> Nothing

instance Crypto c => ShelleyEraTxCert (MaryEra c) where
{-# SPECIALIZE instance ShelleyEraTxCert (MaryEra StandardCrypto) #-}

Expand Down
1 change: 1 addition & 0 deletions eras/shelley/impl/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

## 1.6.0.0

* Deprecate `isRegKey` and `isDeRegKey` in favor of `isRegStakeTxCert` and `isUnRegStakeTxCert` #3700
* Add lenses for `UTxOEnv` #3688
* Add `getTotalTxDepositsBody` to `ShelleyEraTxBody`
* Add `obligationGovState` to `EraGov`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,6 @@ import Cardano.Ledger.Credential (StakeCredential)
import Cardano.Ledger.Keys (KeyHash (..), KeyRole (..))
import Cardano.Ledger.PoolParams (PoolParams (..))
import Cardano.Ledger.Shelley.Core (ShelleyEraTxBody (..), ShelleyEraTxCert)
import Cardano.Ledger.Shelley.TxCert (
isRegKey,
pattern RegTxCert,
pattern UnRegTxCert,
)
import Cardano.Ledger.Val ((<+>), (<×>))
import Data.Foldable (Foldable (..), foldMap', foldl')
import qualified Data.Map.Strict as Map
Expand Down Expand Up @@ -61,7 +56,7 @@ totalCertsDeposits pp isRegPool certs =
<+> numNewRegPoolCerts
<×> (pp ^. ppPoolDepositL)
where
numKeys = getSum @Int $ foldMap' (\x -> if isRegKey x then 1 else 0) certs
numKeys = getSum @Int $ foldMap' (\x -> if isRegStakeTxCert x then 1 else 0) certs
numNewRegPoolCerts = Set.size (foldl' addNewPoolIds Set.empty certs)
addNewPoolIds regPoolIds = \case
RegPoolTxCert (PoolParams {ppId})
Expand Down Expand Up @@ -118,21 +113,24 @@ keyCertsRefunds ::
keyCertsRefunds pp lookupDeposit certs = snd (foldl' accum (mempty, Coin 0) certs)
where
keyDeposit = pp ^. ppKeyDepositL
accum (!regKeys, !totalRefunds) = \case
RegTxCert k ->
-- Need to track new delegations in case that the same key is later deregistered in
-- the same transaction.
(Set.insert k regKeys, totalRefunds)
UnRegTxCert k
-- We first check if there was already a registration certificate in this
-- transaction.
| Set.member k regKeys -> (Set.delete k regKeys, totalRefunds <+> keyDeposit)
-- Check for the deposit left during registration in some previous
-- transaction. This de-registration check will be matched first, despite being
-- the last case to match, because registration is not possible without
-- de-registration.
| Just deposit <- lookupDeposit k -> (regKeys, totalRefunds <+> deposit)
_ -> (regKeys, totalRefunds)
accum (!regKeys, !totalRefunds) cert =
case lookupRegStakeTxCert cert of
Just k ->
-- Need to track new delegations in case that the same key is later deregistered in
-- the same transaction.
(Set.insert k regKeys, totalRefunds)
Nothing ->
case lookupUnRegStakeTxCert cert of
Just k
-- We first check if there was already a registration certificate in this
-- transaction.
| Set.member k regKeys -> (Set.delete k regKeys, totalRefunds <+> keyDeposit)
-- Check for the deposit left during registration in some previous
-- transaction. This de-registration check will be matched first, despite being
-- the last case to match, because registration is not possible without
-- de-registration.
| Just deposit <- lookupDeposit k -> (regKeys, totalRefunds <+> deposit)
_ -> (regKeys, totalRefunds)

keyTxRefunds ::
ShelleyEraTxBody era =>
Expand Down
11 changes: 11 additions & 0 deletions eras/shelley/impl/src/Cardano/Ledger/Shelley/TxCert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ module Cardano.Ledger.Shelley.TxCert (
Delegation (..),
PoolCert (..),
poolCWitness,
isRegStakeTxCert,
isUnRegStakeTxCert,
)
where

Expand Down Expand Up @@ -130,6 +132,13 @@ instance Crypto c => EraTxCert (ShelleyEra c) where
getRetirePoolTxCert (ShelleyTxCertPool (RetirePool poolId epochNo)) = Just (poolId, epochNo)
getRetirePoolTxCert _ = Nothing

lookupRegStakeTxCert = \case
RegTxCert c -> Just c
_ -> Nothing
lookupUnRegStakeTxCert = \case
UnRegTxCert c -> Just c
_ -> Nothing

class EraTxCert era => ShelleyEraTxCert era where
mkRegTxCert :: StakeCredential (EraCrypto era) -> TxCert era
getRegTxCert :: TxCert era -> Maybe (StakeCredential (EraCrypto era))
Expand Down Expand Up @@ -478,11 +487,13 @@ delegCWitness (ShelleyDelegCert cred _) = cred
isRegKey :: ShelleyEraTxCert era => TxCert era -> Bool
isRegKey (RegTxCert _) = True
isRegKey _ = False
{-# DEPRECATED isRegKey "Use `isRegStakeTxCert` instead" #-}

-- | Check for 'ShelleyUnRegCert' constructor
isDeRegKey :: ShelleyEraTxCert era => TxCert era -> Bool
isDeRegKey (UnRegTxCert _) = True
isDeRegKey _ = False
{-# DEPRECATED isDeRegKey "Use `isUnRegStakeTxCert` instead" #-}

-- | Check for 'ShelleyDelegCert' constructor
isDelegation :: ShelleyEraTxCert era => TxCert era -> Bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ import Cardano.Ledger.Shelley.PParams (
pattern Update,
)
import Cardano.Ledger.Shelley.TxCert (
isDeRegKey,
isDelegation,
isGenesisDelegation,
isRegKey,
isRegPool,
isReservesMIRCert,
isRetirePool,
Expand Down Expand Up @@ -146,12 +144,12 @@ relevantCasesAreCoveredForTrace tr = do
)
,
( "there is at least 1 RegKey certificate for every 10 transactions"
, length txs < 10 * length (filter isRegKey certs_)
, length txs < 10 * length (filter isRegStakeTxCert certs_)
, 60
)
,
( "there is at least 1 DeRegKey certificate for every 20 transactions"
, length txs < 20 * length (filter isDeRegKey certs_)
, length txs < 20 * length (filter isUnRegStakeTxCert certs_)
, 60
)
,
Expand Down
2 changes: 2 additions & 0 deletions libs/cardano-ledger-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* Rename:
* `GovActionsState` to `GovSnapshots`
* `cgGovActionsStateL` to `cgGovSnapshotsL`
* Add `lookupRegStakeTxCert` and `lookupUnRegStakeTxCert`
* Add `isRegStakeTxCert` and `isUnRegStakeTxCert`

## 1.5.0.0

Expand Down
8 changes: 8 additions & 0 deletions libs/cardano-ledger-api/src/Cardano/Ledger/Api/Tx/Cert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ module Cardano.Ledger.Api.Tx.Cert (
getScriptWitnessTxCert,
pattern RegPoolTxCert,
pattern RetirePoolTxCert,
lookupRegStakeTxCert,
lookupUnRegStakeTxCert,
isRegStakeTxCert,
isUnRegStakeTxCert,

-- * Shelley Era

Expand Down Expand Up @@ -79,8 +83,12 @@ import Cardano.Ledger.Core (
TxCertUpgradeError,
getScriptWitnessTxCert,
getVKeyWitnessTxCert,
lookupRegStakeTxCert,
lookupUnRegStakeTxCert,
upgradeTxCert
),
isRegStakeTxCert,
isUnRegStakeTxCert,
pattern RegPoolTxCert,
pattern RetirePoolTxCert,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import Cardano.Ledger.Compactible
import Cardano.Ledger.PoolParams
import Cardano.Ledger.Shelley.Core
import Cardano.Ledger.Shelley.TxCert (
isRegKey,
pattern RegTxCert,
pattern UnRegTxCert,
)
Expand All @@ -42,7 +41,7 @@ totalTxDeposits pp dpstate txb =
numKeys <×> pp ^. ppKeyDepositL <+> snd (foldl' accum (regpools, Coin 0) certs)
where
certs = toList (txb ^. certsTxBodyL)
numKeys = length $ filter isRegKey certs
numKeys = length $ filter isRegStakeTxCert certs
regpools = psStakePoolParams (certPState dpstate)
accum (!pools, !ans) (RegPoolTxCert poolparam) =
-- We don't pay a deposit on a pool that is already registered
Expand Down
1 change: 1 addition & 0 deletions libs/cardano-ledger-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

## 1.6.0.0

* Add `lookupRegStakeTxCert` and `lookupUnRegStakeTxCert` to `EraTxCert` typeclass #3700
* Change `ToJSONKey`/`FromJSONKey` implementation of `Credential` to flat text
* Add one more parameter to `getConsumedValue` to lookup DRep deposits #3688
* `Credential 'DRepRole (EraCrypto era) -> Maybe Coin`
Expand Down
17 changes: 17 additions & 0 deletions libs/cardano-ledger-core/src/Cardano/Ledger/Core/TxCert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ module Cardano.Ledger.Core.TxCert (
DRepAlwaysAbstain,
DRepAlwaysNoConfidence
),
isRegStakeTxCert,
isUnRegStakeTxCert,
)
where

Expand All @@ -48,6 +50,7 @@ import Cardano.Ledger.TreeDiff (ToExpr)
import Control.DeepSeq (NFData (..), rwhnf)
import Data.Aeson (ToJSON)
import Data.Kind (Type)
import Data.Maybe (isJust)
import Data.Void (Void)
import GHC.Generics (Generic)
import NoThunks.Class (NoThunks (..))
Expand Down Expand Up @@ -92,6 +95,12 @@ class
mkRetirePoolTxCert :: KeyHash 'StakePool (EraCrypto era) -> EpochNo -> TxCert era
getRetirePoolTxCert :: TxCert era -> Maybe (KeyHash 'StakePool (EraCrypto era), EpochNo)

-- | Extract staking credential from any certificate that can register such credential
lookupRegStakeTxCert :: TxCert era -> Maybe (Credential 'Staking (EraCrypto era))

-- | Extract staking credential from any certificate that can unregister such credential
lookupUnRegStakeTxCert :: TxCert era -> Maybe (Credential 'Staking (EraCrypto era))

pattern RegPoolTxCert :: EraTxCert era => PoolParams (EraCrypto era) -> TxCert era
pattern RegPoolTxCert d <- (getRegPoolTxCert -> Just d)
where
Expand Down Expand Up @@ -193,3 +202,11 @@ pattern DRepCredential c <- (dRepToCred -> Just c)
KeyHashObj kh -> DRepKeyHash kh

{-# COMPLETE DRepCredential, DRepAlwaysAbstain, DRepAlwaysNoConfidence :: DRep #-}

-- | Check if supplied TxCert is a stake registering certificate
isRegStakeTxCert :: EraTxCert era => TxCert era -> Bool
isRegStakeTxCert = isJust . lookupRegStakeTxCert

-- | Check if supplied TxCert is a stake un-registering certificate
isUnRegStakeTxCert :: EraTxCert era => TxCert era -> Bool
isUnRegStakeTxCert = isJust . lookupUnRegStakeTxCert

0 comments on commit 16a9090

Please sign in to comment.