Skip to content

Commit 02212d8

Browse files
authored
Merge pull request #5229 from IntersectMBO/td/no-duplicate-vrf-keys
Disallow duplicate VRF keys for pool registration
2 parents 6da8621 + a5543c1 commit 02212d8

File tree

27 files changed

+644
-65
lines changed

27 files changed

+644
-65
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
module Test.Cardano.Ledger.Allegra.Imp (spec) where
99

1010
import Cardano.Ledger.Core
11-
import Cardano.Ledger.Shelley.Rules (ShelleyUtxoPredFailure, ShelleyUtxowPredFailure)
11+
import Cardano.Ledger.Shelley.Rules (
12+
ShelleyPoolPredFailure,
13+
ShelleyUtxoPredFailure,
14+
ShelleyUtxowPredFailure,
15+
)
1216
import qualified Test.Cardano.Ledger.Allegra.Imp.UtxowSpec as UtxowSpec
1317
import Test.Cardano.Ledger.Imp.Common
1418
import qualified Test.Cardano.Ledger.Shelley.Imp as ShelleyImp
@@ -17,6 +21,7 @@ import Test.Cardano.Ledger.Shelley.ImpTest
1721
spec ::
1822
forall era.
1923
( ShelleyEraImp era
24+
, InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era
2025
, InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era
2126
, InjectRuleFailure "LEDGER" ShelleyUtxowPredFailure era
2227
) =>

eras/alonzo/impl/testlib/Test/Cardano/Ledger/Alonzo/Imp.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Cardano.Ledger.Alonzo.Rules (
1515
)
1616
import Cardano.Ledger.Shelley.Rules (
1717
ShelleyDelegPredFailure,
18+
ShelleyPoolPredFailure,
1819
ShelleyUtxoPredFailure,
1920
ShelleyUtxowPredFailure,
2021
)
@@ -29,6 +30,7 @@ spec ::
2930
forall era.
3031
( AlonzoEraImp era
3132
, InjectRuleFailure "LEDGER" ShelleyDelegPredFailure era
33+
, InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era
3234
, InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era
3335
, InjectRuleFailure "LEDGER" ShelleyUtxowPredFailure era
3436
, InjectRuleFailure "LEDGER" AlonzoUtxoPredFailure era

eras/babbage/impl/testlib/Test/Cardano/Ledger/Babbage/Imp.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import Cardano.Ledger.Babbage.TxInfo (BabbageContextError)
1919
import Cardano.Ledger.BaseTypes (Inject)
2020
import Cardano.Ledger.Shelley.Rules (
2121
ShelleyDelegPredFailure,
22+
ShelleyPoolPredFailure,
2223
ShelleyUtxoPredFailure,
2324
ShelleyUtxowPredFailure,
2425
)
@@ -34,6 +35,7 @@ spec ::
3435
( AlonzoEraImp era
3536
, BabbageEraTxBody era
3637
, InjectRuleFailure "LEDGER" ShelleyDelegPredFailure era
38+
, InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era
3739
, InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era
3840
, InjectRuleFailure "LEDGER" AlonzoUtxoPredFailure era
3941
, InjectRuleFailure "LEDGER" AlonzoUtxosPredFailure era

eras/conway/impl/cardano-ledger-conway.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ library testlib
146146
Test.Cardano.Ledger.Conway.Imp.EpochSpec
147147
Test.Cardano.Ledger.Conway.Imp.GovCertSpec
148148
Test.Cardano.Ledger.Conway.Imp.GovSpec
149+
Test.Cardano.Ledger.Conway.Imp.HardForkSpec
149150
Test.Cardano.Ledger.Conway.Imp.LedgerSpec
150151
Test.Cardano.Ledger.Conway.Imp.RatifySpec
151152
Test.Cardano.Ledger.Conway.Imp.UtxoSpec

eras/conway/impl/src/Cardano/Ledger/Conway/Rules/HardFork.hs

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -67,31 +67,43 @@ hardforkTransition = do
6767
TRC (_, epochState, newPv) <-
6868
judgmentContext
6969
tellEvent $ ConwayHardForkEvent newPv
70-
if pvMajor newPv == natVersion @10
71-
then
72-
pure $
73-
epochState
74-
& esLStateL . lsCertStateL %~ \certState ->
75-
let accountsMap = certState ^. certDStateL . accountsL . accountsMapL
76-
dReps =
77-
-- Reset all delegations in order to remove any inconsistencies
78-
-- Delegations will be reset accordingly below.
79-
Map.map (\dRepState -> dRepState {drepDelegs = Set.empty}) $
80-
certState ^. certVStateL . vsDRepsL
81-
(dRepsWithDelegations, accountsWithoutUnknownDRepDelegations) =
82-
Map.mapAccumWithKey adjustDelegations dReps accountsMap
83-
adjustDelegations ds stakeCred accountState =
84-
case accountState ^. dRepDelegationAccountStateL of
85-
Just (DRepCredential dRep) ->
86-
let addDelegation _ dRepState =
87-
Just $ dRepState {drepDelegs = Set.insert stakeCred (drepDelegs dRepState)}
88-
in case Map.updateLookupWithKey addDelegation dRep ds of
89-
(Nothing, _) -> (ds, accountState & dRepDelegationAccountStateL .~ Nothing)
90-
(Just _, ds') -> (ds', accountState)
91-
_ -> (ds, accountState)
92-
in certState
93-
-- Remove dangling delegations to non-existent DReps:
94-
& certDStateL . accountsL . accountsMapL .~ accountsWithoutUnknownDRepDelegations
95-
-- Populate DRep delegations with delegatees
96-
& certVStateL . vsDRepsL .~ dRepsWithDelegations
97-
else pure epochState
70+
let update
71+
| pvMajor newPv == natVersion @10 =
72+
esLStateL . lsCertStateL %~ updateDRepDelegations
73+
| pvMajor newPv == natVersion @11 =
74+
esLStateL . lsCertStateL . certPStateL %~ populateVRFKeyHashes
75+
| otherwise = id
76+
pure $ update epochState
77+
78+
updateDRepDelegations :: ConwayEraCertState era => CertState era -> CertState era
79+
updateDRepDelegations certState =
80+
let accountsMap = certState ^. certDStateL . accountsL . accountsMapL
81+
dReps =
82+
-- Reset all delegations in order to remove any inconsistencies
83+
-- Delegations will be reset accordingly below.
84+
Map.map (\dRepState -> dRepState {drepDelegs = Set.empty}) $
85+
certState ^. certVStateL . vsDRepsL
86+
(dRepsWithDelegations, accountsWithoutUnknownDRepDelegations) =
87+
Map.mapAccumWithKey adjustDelegations dReps accountsMap
88+
adjustDelegations ds stakeCred accountState =
89+
case accountState ^. dRepDelegationAccountStateL of
90+
Just (DRepCredential dRep) ->
91+
let addDelegation _ dRepState =
92+
Just $ dRepState {drepDelegs = Set.insert stakeCred (drepDelegs dRepState)}
93+
in case Map.updateLookupWithKey addDelegation dRep ds of
94+
(Nothing, _) -> (ds, accountState & dRepDelegationAccountStateL .~ Nothing)
95+
(Just _, ds') -> (ds', accountState)
96+
_ -> (ds, accountState)
97+
in certState
98+
-- Remove dangling delegations to non-existent DReps:
99+
& certDStateL . accountsL . accountsMapL .~ accountsWithoutUnknownDRepDelegations
100+
-- Populate DRep delegations with delegatees
101+
& certVStateL . vsDRepsL .~ dRepsWithDelegations
102+
103+
populateVRFKeyHashes :: PState era -> PState era
104+
populateVRFKeyHashes pState =
105+
let allVRFKeyHashes =
106+
spsVrf
107+
<$> Map.elems (pState ^. psStakePoolsL)
108+
<> Map.elems (pState ^. psFutureStakePoolsL)
109+
in pState & psVRFKeyHashesL .~ Set.fromList allVRFKeyHashes

eras/conway/impl/testlib/Test/Cardano/Ledger/Conway/Imp.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import Cardano.Ledger.Plutus (Language (..))
3939
import Cardano.Ledger.Shelley.API.Mempool (ApplyTx (..))
4040
import Cardano.Ledger.Shelley.Rules (
4141
ShelleyDelegPredFailure,
42+
ShelleyPoolPredFailure,
4243
ShelleyUtxoPredFailure,
4344
ShelleyUtxowPredFailure,
4445
)
@@ -52,6 +53,7 @@ import qualified Test.Cardano.Ledger.Conway.Imp.EnactSpec as Enact
5253
import qualified Test.Cardano.Ledger.Conway.Imp.EpochSpec as Epoch
5354
import qualified Test.Cardano.Ledger.Conway.Imp.GovCertSpec as GovCert
5455
import qualified Test.Cardano.Ledger.Conway.Imp.GovSpec as Gov
56+
import qualified Test.Cardano.Ledger.Conway.Imp.HardForkSpec as HardFork
5557
import qualified Test.Cardano.Ledger.Conway.Imp.LedgerSpec as Ledger
5658
import qualified Test.Cardano.Ledger.Conway.Imp.RatifySpec as Ratify
5759
import qualified Test.Cardano.Ledger.Conway.Imp.UtxoSpec as Utxo
@@ -75,6 +77,7 @@ spec ::
7577
, InjectRuleFailure "LEDGER" ShelleyDelegPredFailure era
7678
, InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era
7779
, InjectRuleFailure "LEDGER" ShelleyUtxowPredFailure era
80+
, InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era
7881
, InjectRuleFailure "LEDGER" ConwayDelegPredFailure era
7982
, InjectRuleFailure "LEDGER" ConwayGovCertPredFailure era
8083
, InjectRuleFailure "LEDGER" ConwayLedgerPredFailure era
@@ -137,6 +140,7 @@ conwaySpec = do
137140
describe "GOV" Gov.spec
138141
describe "GOVCERT" GovCert.spec
139142
describe "LEDGER" Ledger.spec
143+
describe "HARDFORK" HardFork.spec
140144
describe "RATIFY" Ratify.spec
141145
describe "UTXO" Utxo.spec
142146
describe "UTXOS" Utxos.spec
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{-# LANGUAGE BangPatterns #-}
2+
{-# LANGUAGE DataKinds #-}
3+
{-# LANGUAGE FlexibleContexts #-}
4+
{-# LANGUAGE OverloadedLists #-}
5+
{-# LANGUAGE ScopedTypeVariables #-}
6+
{-# LANGUAGE TypeApplications #-}
7+
{-# LANGUAGE TypeFamilies #-}
8+
9+
module Test.Cardano.Ledger.Conway.Imp.HardForkSpec (spec) where
10+
11+
import Cardano.Ledger.BaseTypes
12+
import Cardano.Ledger.Conway.Core
13+
import Cardano.Ledger.Conway.Governance
14+
import Cardano.Ledger.Conway.PParams
15+
import Cardano.Ledger.Conway.State
16+
import Cardano.Ledger.Shelley.LedgerState
17+
import qualified Data.Set as Set
18+
import Lens.Micro
19+
import Test.Cardano.Ledger.Conway.ImpTest
20+
import Test.Cardano.Ledger.Core.Rational
21+
import Test.Cardano.Ledger.Imp.Common
22+
23+
spec ::
24+
forall era.
25+
ConwayEraImp era => SpecWith (ImpInit (LedgerSpec era))
26+
spec = do
27+
it "VRF Keyhashes get populated at v11 HardFork" $ do
28+
-- Since we're testing the HardFork to 11, the test only makes sense for protocol version 10
29+
whenMajorVersion @10 $ do
30+
(kh1, vrf1) <- (,) <$> freshKeyHash <*> freshKeyHashVRF
31+
registerStakePool kh1 vrf1
32+
(kh2, vrf2) <- (,) <$> freshKeyHash <*> freshKeyHashVRF
33+
registerStakePool kh2 vrf2
34+
vrf3 <- freshKeyHashVRF
35+
-- re-register with a new key, so vrf1 should not be present after the hard fork
36+
registerStakePool kh1 vrf3
37+
-- register a new pool with an existing vrf
38+
kh3 <- freshKeyHash
39+
registerStakePool kh3 vrf2
40+
-- register and retire a pool before the hard fork, so vrf4 should not be present after the hard fork
41+
(kh4, vrf4) <- (,) <$> freshKeyHash <*> freshKeyHashVRF
42+
registerStakePool kh4 vrf4
43+
retireStakePool kh4 (EpochInterval 1)
44+
-- register and schedule retirement for after the hard fork, so vrf5 should be present after the hard fork
45+
(kh5, vrf5) <- (,) <$> freshKeyHash <*> freshKeyHashVRF
46+
registerStakePool kh5 vrf5
47+
retireStakePool kh5 (EpochInterval 5)
48+
49+
expectVRFs [] -- VRF keyhashes in PState is not yet populated
50+
enactHardForkV11
51+
expectVRFs [vrf2, vrf3, vrf5]
52+
where
53+
enactHardForkV11 = do
54+
modifyPParams $ \pp ->
55+
pp
56+
& ppDRepVotingThresholdsL . dvtHardForkInitiationL .~ 0 %! 1
57+
& ppPoolVotingThresholdsL . pvtHardForkInitiationL .~ 0 %! 1
58+
let pv11 = ProtVer (natVersion @11) 0
59+
committee <- registerInitialCommittee
60+
govActionId <- submitGovAction $ HardForkInitiation SNothing pv11
61+
submitYesVoteCCs_ committee govActionId
62+
passNEpochs 2
63+
getProtVer `shouldReturn` pv11
64+
registerStakePool kh vrf = do
65+
pps <- registerRewardAccount >>= freshPoolParams kh
66+
submitTx_ $
67+
mkBasicTx mkBasicTxBody
68+
& bodyTxL . certsTxBodyL .~ [RegPoolTxCert $ pps & ppVrfL .~ vrf]
69+
retireStakePool kh retirementInterval = do
70+
curEpochNo <- getsNES nesELL
71+
let retirement = addEpochInterval curEpochNo retirementInterval
72+
submitTx_ $
73+
mkBasicTx mkBasicTxBody
74+
& bodyTxL . certsTxBodyL .~ [RetirePoolTxCert kh retirement]
75+
expectVRFs vrfs =
76+
psVRFKeyHashes <$> getPState `shouldReturn` Set.fromList vrfs
77+
getPState = getsNES @era $ nesEsL . esLStateL . lsCertStateL . certPStateL

eras/conway/impl/testlib/Test/Cardano/Ledger/Conway/Spec.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import Cardano.Ledger.Shelley.API (ApplyTx)
5151
import Cardano.Ledger.Shelley.LedgerState (StashedAVVMAddresses)
5252
import Cardano.Ledger.Shelley.Rules (
5353
ShelleyDelegPredFailure,
54+
ShelleyPoolPredFailure,
5455
ShelleyUtxoPredFailure,
5556
ShelleyUtxowPredFailure,
5657
)
@@ -102,6 +103,7 @@ spec ::
102103
, InjectRuleFailure "LEDGER" ShelleyDelegPredFailure era
103104
, InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era
104105
, InjectRuleFailure "LEDGER" ShelleyUtxowPredFailure era
106+
, InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era
105107
, InjectRuleFailure "LEDGER" ConwayDelegPredFailure era
106108
, InjectRuleFailure "LEDGER" ConwayGovCertPredFailure era
107109
, InjectRuleFailure "LEDGER" ConwayLedgerPredFailure era

eras/mary/impl/testlib/Test/Cardano/Ledger/Mary/Imp.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
module Test.Cardano.Ledger.Mary.Imp (spec) where
99

1010
import Cardano.Ledger.Mary.Core
11-
import Cardano.Ledger.Shelley.Rules (ShelleyUtxoPredFailure, ShelleyUtxowPredFailure)
11+
import Cardano.Ledger.Shelley.Rules (
12+
ShelleyPoolPredFailure,
13+
ShelleyUtxoPredFailure,
14+
ShelleyUtxowPredFailure,
15+
)
1216
import qualified Test.Cardano.Ledger.Allegra.Imp as AllegraImp
1317
import Test.Cardano.Ledger.Imp.Common
1418
import qualified Test.Cardano.Ledger.Mary.Imp.UtxoSpec as Utxo
@@ -19,6 +23,7 @@ spec ::
1923
( MaryEraImp era
2024
, InjectRuleFailure "LEDGER" ShelleyUtxoPredFailure era
2125
, InjectRuleFailure "LEDGER" ShelleyUtxowPredFailure era
26+
, InjectRuleFailure "LEDGER" ShelleyPoolPredFailure era
2227
) =>
2328
Spec
2429
spec = do

eras/shelley/impl/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## 1.17.0.0
44

5+
* Add `hardforkConwayDisallowDuplicatedVRFKeys`
6+
* Add `VRFKeyHashAlreadyRegistered` to `ShelleyPoolPredFailure` type
57
* Add `NFData` for `NominalDiffTimeMicro`, `ShelleyGenesisStaking` and `ShelleyGenesis`
68
* Deprecate `PoolParams` in favor of `StakePoolState`. #5196
79
* Deprecate the API `getPoolParameters` in favor of `getStakePools`.

0 commit comments

Comments
 (0)