Skip to content

Commit d6b2a84

Browse files
authored
Merge pull request #4815 from IntersectMBO/release/cardano-ledger-conway-1.17.4.0
Backport release `cardano-ledger-conway-1.17.4.0`
2 parents d30a7ae + df07b60 commit d6b2a84

File tree

8 files changed

+150
-14
lines changed

8 files changed

+150
-14
lines changed

eras/conway/impl/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Version history for `cardano-ledger-conway`
22

3+
## 1.17.4.0
4+
5+
* Add a check to `MEMPOOL` rule that prevents unelected CC from voting.
6+
37
## 1.17.3.0
48

59
* Fix buggy behavior of DRep delegations: #4772

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 3.0
22
name: cardano-ledger-conway
3-
version: 1.17.3.0
3+
version: 1.17.4.0
44
license: Apache-2.0
55
maintainer: operations@iohk.io
66
author: IOHK

eras/conway/impl/src/Cardano/Ledger/Conway/Governance.hs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
{-# LANGUAGE BangPatterns #-}
2+
{-# LANGUAGE DataKinds #-}
13
{-# LANGUAGE DeriveGeneric #-}
24
{-# LANGUAGE FlexibleContexts #-}
5+
{-# LANGUAGE LambdaCase #-}
36
{-# LANGUAGE NamedFieldPuns #-}
47
{-# LANGUAGE OverloadedStrings #-}
58
{-# LANGUAGE RecordWildCards #-}
@@ -23,6 +26,7 @@ module Cardano.Ledger.Conway.Governance (
2326
Committee (..),
2427
committeeMembersL,
2528
committeeThresholdL,
29+
authorizedElectedHotCommitteeCredentials,
2630
GovAction (..),
2731
GovActionState (..),
2832
GovActionIx (..),
@@ -191,20 +195,28 @@ import Cardano.Ledger.Binary.Coders (
191195
(!>),
192196
(<!),
193197
)
194-
import Cardano.Ledger.CertState (Obligations (..))
198+
import Cardano.Ledger.CertState (
199+
CommitteeAuthorization (..),
200+
Obligations (..),
201+
certVStateL,
202+
csCommitteeCreds,
203+
)
195204
import Cardano.Ledger.Coin (Coin (..))
196205
import Cardano.Ledger.Conway.Era (ConwayEra)
197206
import Cardano.Ledger.Conway.Governance.DRepPulser
198207
import Cardano.Ledger.Conway.Governance.Internal
199208
import Cardano.Ledger.Conway.Governance.Procedures
200209
import Cardano.Ledger.Conway.Governance.Proposals
201210
import Cardano.Ledger.Core
211+
import Cardano.Ledger.Credential (Credential)
202212
import Cardano.Ledger.Crypto (Crypto)
203213
import Cardano.Ledger.DRep (DRep (..))
214+
import Cardano.Ledger.Keys (KeyRole (..))
204215
import Cardano.Ledger.PoolDistr (PoolDistr (..))
205216
import Cardano.Ledger.Shelley.Governance
206217
import Cardano.Ledger.Shelley.LedgerState (
207218
EpochState (..),
219+
LedgerState,
208220
NewEpochState (..),
209221
certDState,
210222
certVState,
@@ -215,10 +227,14 @@ import Cardano.Ledger.Shelley.LedgerState (
215227
epochStateTreasuryL,
216228
esLStateL,
217229
lsCertState,
230+
lsCertStateL,
218231
lsUTxOState,
232+
lsUTxOStateL,
219233
newEpochStateGovStateL,
234+
utxosGovStateL,
220235
utxosStakeDistr,
221236
vsCommitteeState,
237+
vsCommitteeStateL,
222238
vsDReps,
223239
)
224240
import Cardano.Ledger.UMap
@@ -229,8 +245,10 @@ import Control.Monad.Trans.Reader (ReaderT, ask)
229245
import Data.Aeson (KeyValue, ToJSON (..), object, pairs, (.=))
230246
import Data.Default.Class (Default (..))
231247
import Data.Foldable (Foldable (..))
248+
import qualified Data.Foldable as F (foldl')
232249
import Data.Map.Strict (Map)
233250
import qualified Data.Map.Strict as Map
251+
import qualified Data.Set as Set
234252
import Data.Word (Word64)
235253
import GHC.Generics (Generic)
236254
import Lens.Micro
@@ -504,3 +522,21 @@ setFreshDRepPulsingState epochNo stakePoolDistr epochState = do
504522
-- point. Whenever pulser is already in computed state this will be a noop.
505523
forceDRepPulsingState :: ConwayEraGov era => NewEpochState era -> NewEpochState era
506524
forceDRepPulsingState nes = nes & newEpochStateDRepPulsingStateL %~ completeDRepPulsingState
525+
526+
authorizedElectedHotCommitteeCredentials ::
527+
ConwayEraGov era =>
528+
LedgerState era ->
529+
Set.Set (Credential 'HotCommitteeRole (EraCrypto era))
530+
authorizedElectedHotCommitteeCredentials ledgerState =
531+
case ledgerState ^. lsUTxOStateL . utxosGovStateL . committeeGovStateL of
532+
SNothing -> Set.empty
533+
SJust electedCommiteee ->
534+
collectAuthorizedHotCreds $
535+
csCommitteeCreds committeeState `Map.intersection` committeeMembers electedCommiteee
536+
where
537+
committeeState = ledgerState ^. lsCertStateL . certVStateL . vsCommitteeStateL
538+
collectAuthorizedHotCreds =
539+
let toHotCredSet !acc = \case
540+
CommitteeHotCredential hotCred -> Set.insert hotCred acc
541+
CommitteeMemberResigned {} -> acc
542+
in F.foldl' toHotCredSet Set.empty

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,8 +584,9 @@ instance
584584
wrapEvent = CertsEvent . CertEvent . DelegEvent
585585

586586
instance
587-
( EraGov era
588-
, EraTx era
587+
( EraTx era
588+
, ConwayEraGov era
589+
, ConwayEraTxBody era
589590
, EraRule "MEMPOOL" era ~ ConwayMEMPOOL era
590591
, PredicateFailure (EraRule "MEMPOOL" era) ~ ConwayMempoolPredFailure era
591592
, Event (EraRule "MEMPOOL" era) ~ ConwayMempoolEvent era

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

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE BangPatterns #-}
12
{-# LANGUAGE DataKinds #-}
23
{-# LANGUAGE DeriveGeneric #-}
34
{-# LANGUAGE DerivingStrategies #-}
@@ -23,6 +24,12 @@ import Cardano.Ledger.BaseTypes (ShelleyBase)
2324
import Cardano.Ledger.Binary (DecCBOR (..), EncCBOR (..), FromCBOR, ToCBOR)
2425
import Cardano.Ledger.Conway.Core
2526
import Cardano.Ledger.Conway.Era (ConwayEra, ConwayMEMPOOL)
27+
import Cardano.Ledger.Conway.Governance (
28+
ConwayEraGov,
29+
Voter (..),
30+
authorizedElectedHotCommitteeCredentials,
31+
unVotingProcedures,
32+
)
2633
import Cardano.Ledger.Shelley.LedgerState
2734
import Cardano.Ledger.Shelley.Rules (LedgerEnv (..))
2835
import Control.DeepSeq (NFData)
@@ -36,12 +43,17 @@ import Control.State.Transition (
3643
State,
3744
TRC (TRC),
3845
TransitionRule,
46+
failOnNonEmpty,
3947
judgmentContext,
4048
tellEvent,
4149
transitionRules,
4250
)
43-
import Data.Text (Text, pack)
51+
import qualified Data.List.NonEmpty as NE
52+
import qualified Data.Map.Strict as Map
53+
import qualified Data.Set as Set
54+
import Data.Text as T (Text, pack)
4455
import GHC.Generics (Generic)
56+
import Lens.Micro ((^.))
4557
import NoThunks.Class (NoThunks)
4658

4759
newtype ConwayMempoolPredFailure era = ConwayMempoolPredFailure Text
@@ -58,7 +70,7 @@ newtype ConwayMempoolEvent era = ConwayMempoolEvent Text
5870
type instance EraRuleEvent "MEMPOOL" (ConwayEra c) = ConwayMempoolEvent (ConwayEra c)
5971

6072
instance
61-
(EraTx era, EraGov era) =>
73+
(EraTx era, ConwayEraTxBody era, ConwayEraGov era) =>
6274
STS (ConwayMEMPOOL era)
6375
where
6476
type State (ConwayMEMPOOL era) = LedgerState era
@@ -70,11 +82,27 @@ instance
7082

7183
transitionRules = [mempoolTransition @era]
7284

73-
mempoolTransition :: EraTx era => TransitionRule (ConwayMEMPOOL era)
85+
mempoolTransition ::
86+
(EraTx era, ConwayEraTxBody era, ConwayEraGov era) => TransitionRule (ConwayMEMPOOL era)
7487
mempoolTransition = do
7588
TRC (_ledgerEnv, ledgerState, tx) <-
7689
judgmentContext
7790
-- This rule only gets invoked on transactions within the mempool.
7891
-- Add checks here that sanitize undesired transactions.
79-
tellEvent . ConwayMempoolEvent . ("Mempool rule for tx " <>) . pack . show . txIdTx $ tx
92+
tellEvent . ConwayMempoolEvent . ("Mempool rule for tx " <>) . T.pack . show $ txIdTx tx
93+
let
94+
authorizedElectedHotCreds = authorizedElectedHotCommitteeCredentials ledgerState
95+
collectUnelectedCommitteeVotes !unelectedHotCreds voter _ =
96+
case voter of
97+
CommitteeVoter hotCred
98+
| hotCred `Set.notMember` authorizedElectedHotCreds ->
99+
Set.insert hotCred unelectedHotCreds
100+
_ -> unelectedHotCreds
101+
unelectedCommitteeVoters =
102+
Map.foldlWithKey' collectUnelectedCommitteeVotes Set.empty $
103+
unVotingProcedures (tx ^. bodyTxL . votingProceduresTxBodyL)
104+
addPrefix =
105+
("Unelected committee members are not allowed to cast votes: " <>)
106+
failOnNonEmpty unelectedCommitteeVoters $
107+
ConwayMempoolPredFailure . addPrefix . T.pack . show . NE.toList
80108
pure ledgerState

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ proposalsSpec = do
559559
unregisteredRewardAccount <- freshKeyHash >>= getRewardAccountFor . KeyHashObj
560560
deposit <- getsNES $ nesEsL . curPParamsEpochStateL . ppGovActionDepositL
561561
anchor <- arbitrary
562-
let mkProposal rewardAccount =
562+
let mkProposal' rewardAccount =
563563
ProposalProcedure
564564
{ pProcDeposit = deposit
565565
, pProcReturnAddr = rewardAccount
@@ -568,12 +568,12 @@ proposalsSpec = do
568568
}
569569
if HF.bootstrapPhase protVer
570570
then do
571-
submitProposal_ $ mkProposal registeredRewardAccount
572-
submitProposal_ $ mkProposal unregisteredRewardAccount
571+
submitProposal_ $ mkProposal' registeredRewardAccount
572+
submitProposal_ $ mkProposal' unregisteredRewardAccount
573573
else do
574-
submitProposal_ $ mkProposal registeredRewardAccount
574+
submitProposal_ $ mkProposal' registeredRewardAccount
575575
submitFailingProposal
576-
(mkProposal unregisteredRewardAccount)
576+
(mkProposal' unregisteredRewardAccount)
577577
[ injectFailure $ ProposalReturnAccountDoesNotExist unregisteredRewardAccount
578578
]
579579
describe "Consistency" $ do

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

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module Test.Cardano.Ledger.Conway.Imp.LedgerSpec (spec) where
1212
import Cardano.Ledger.BaseTypes
1313
import Cardano.Ledger.Coin (Coin (..))
1414
import Cardano.Ledger.Conway.Core
15+
import Cardano.Ledger.Conway.Governance
1516
import Cardano.Ledger.Conway.Rules (
1617
ConwayLedgerEvent (..),
1718
ConwayLedgerPredFailure (..),
@@ -22,17 +23,19 @@ import Cardano.Ledger.Credential (Credential (..))
2223
import Cardano.Ledger.DRep
2324
import Cardano.Ledger.Plutus (SLanguage (..), hashPlutusScript)
2425
import Cardano.Ledger.SafeHash (originalBytesSize)
25-
import Cardano.Ledger.Shelley.API.Mempool (ApplyTx (..), mkMempoolEnv)
26+
import Cardano.Ledger.Shelley.API.Mempool (ApplyTx (..), applyTx, mkMempoolEnv)
2627
import qualified Cardano.Ledger.Shelley.HardForks as HF (bootstrapPhase)
2728
import Cardano.Ledger.Shelley.LedgerState
2829
import Cardano.Ledger.Shelley.Rules (ShelleyLedgersEnv (..), ShelleyLedgersEvent (..))
2930
import Control.State.Transition.Extended
3031
import Data.Default.Class (def)
32+
import qualified Data.Map.Strict as Map
3133
import qualified Data.Sequence as Seq
3234
import qualified Data.Set as Set
3335
import Lens.Micro ((&), (.~), (^.))
3436
import Lens.Micro.Mtl (use)
3537
import Test.Cardano.Ledger.Conway.ImpTest
38+
import Test.Cardano.Ledger.Core.Rational (IsRatio (..))
3639
import Test.Cardano.Ledger.Imp.Common
3740
import Test.Cardano.Ledger.Plutus.Examples (
3841
alwaysFailsWithDatum,
@@ -249,3 +252,42 @@ spec = do
249252
assertFailure $ "Unexpected failure while applyingTx: " <> show tx <> ": " <> show e
250253
Right (_, evs) ->
251254
length [ev | ev@(MempoolEvent (ConwayMempoolEvent _)) <- evs] `shouldBe` 1
255+
256+
it "Unelected Committee voting" $ whenPostBootstrap $ do
257+
globals <- use impGlobalsL
258+
slotNo <- use impLastTickG
259+
_ <- registerInitialCommittee
260+
ccCold <- KeyHashObj <$> freshKeyHash
261+
curEpochNo <- getsNES nesELL
262+
let action =
263+
UpdateCommittee
264+
SNothing
265+
mempty
266+
(Map.singleton ccCold (addEpochInterval curEpochNo (EpochInterval 7)))
267+
(1 %! 1)
268+
proposal <- mkProposal action
269+
submitTx_ $
270+
mkBasicTx (mkBasicTxBody & proposalProceduresTxBodyL .~ [proposal])
271+
ccHot <- registerCommitteeHotKey ccCold
272+
govActionId <- do
273+
rewardAccount <- registerRewardAccount
274+
submitTreasuryWithdrawals [(rewardAccount, Coin 1)]
275+
276+
nes <- use impNESL
277+
let ls = nes ^. nesEsL . esLStateL
278+
mempoolEnv = mkMempoolEnv nes slotNo
279+
tx <-
280+
fixupTx $
281+
mkBasicTx $
282+
mkBasicTxBody
283+
& votingProceduresTxBodyL
284+
.~ VotingProcedures
285+
( Map.singleton
286+
(CommitteeVoter ccHot)
287+
(Map.singleton govActionId (VotingProcedure VoteYes SNothing))
288+
)
289+
290+
case applyTx globals mempoolEnv ls tx of
291+
Left _ -> pure ()
292+
Right _ -> assertFailure $ "Expected failure due to an unallowed vote: " <> show tx
293+
withNoFixup $ submitTx_ tx

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ module Test.Cardano.Ledger.Conway.ImpTest (
4747
setupPoolWithStake,
4848
setupPoolWithoutStake,
4949
conwayModifyPParams,
50+
mkProposal,
5051
getProposals,
5152
getEnactState,
5253
getGovActionState,
@@ -789,6 +790,30 @@ submitAndExpireProposalToMakeReward stakingC = do
789790
passNEpochs $ 2 + fromIntegral lifetime
790791
expectMissingGovActionId gai
791792

793+
mkProposalWithRewardAccount ::
794+
(ShelleyEraImp era, ConwayEraTxBody era) =>
795+
GovAction era ->
796+
RewardAccount (EraCrypto era) ->
797+
ImpTestM era (ProposalProcedure era)
798+
mkProposalWithRewardAccount ga rewardAccount = do
799+
deposit <- getsNES $ nesEsL . curPParamsEpochStateL . ppGovActionDepositL
800+
anchor <- arbitrary
801+
pure
802+
ProposalProcedure
803+
{ pProcDeposit = deposit
804+
, pProcReturnAddr = rewardAccount
805+
, pProcGovAction = ga
806+
, pProcAnchor = anchor
807+
}
808+
809+
mkProposal ::
810+
(ShelleyEraImp era, ConwayEraTxBody era) =>
811+
GovAction era ->
812+
ImpTestM era (ProposalProcedure era)
813+
mkProposal ga = do
814+
rewardAccount <- registerRewardAccount
815+
mkProposalWithRewardAccount ga rewardAccount
816+
792817
-- | Submits a transaction that proposes the given governance action
793818
trySubmitGovActions ::
794819
(ShelleyEraImp era, ConwayEraTxBody era) =>

0 commit comments

Comments
 (0)