Skip to content

Commit d428f5b

Browse files
authored
Merge pull request #4816 from IntersectMBO/release/cardano-ledger-conway-1.18.1.0
Backport release `cardano-ledger-conway-1.18.1.0`
2 parents b7fe1c3 + 111c488 commit d428f5b

File tree

6 files changed

+117
-9
lines changed

6 files changed

+117
-9
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.18.1.0
4+
5+
* Add a check to `MEMPOOL` rule that prevents unelected CC from voting.
6+
37
## 1.18.0.0
48

59
* Remove `SlotNo` from `CertEnv` and `CertsEnv`

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.18.0.0
3+
version: 1.18.1.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: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
{-# LANGUAGE BangPatterns #-}
12
{-# LANGUAGE DataKinds #-}
23
{-# LANGUAGE DeriveGeneric #-}
34
{-# LANGUAGE FlexibleContexts #-}
5+
{-# LANGUAGE LambdaCase #-}
46
{-# LANGUAGE NamedFieldPuns #-}
57
{-# LANGUAGE OverloadedStrings #-}
68
{-# LANGUAGE RecordWildCards #-}
@@ -24,6 +26,7 @@ module Cardano.Ledger.Conway.Governance (
2426
Committee (..),
2527
committeeMembersL,
2628
committeeThresholdL,
29+
authorizedElectedHotCommitteeCredentials,
2730
GovAction (..),
2831
GovActionState (..),
2932
GovActionIx (..),
@@ -195,7 +198,12 @@ import Cardano.Ledger.Binary.Coders (
195198
(!>),
196199
(<!),
197200
)
198-
import Cardano.Ledger.CertState (Obligations (..))
201+
import Cardano.Ledger.CertState (
202+
CommitteeAuthorization (..),
203+
Obligations (..),
204+
certVStateL,
205+
csCommitteeCreds,
206+
)
199207
import Cardano.Ledger.Coin (Coin (..))
200208
import Cardano.Ledger.Conway.Era (ConwayEra)
201209
import Cardano.Ledger.Conway.Governance.DRepPulser
@@ -212,6 +220,7 @@ import Cardano.Ledger.PoolParams (PoolParams (ppRewardAccount))
212220
import Cardano.Ledger.Shelley.Governance
213221
import Cardano.Ledger.Shelley.LedgerState (
214222
EpochState (..),
223+
LedgerState,
215224
NewEpochState (..),
216225
certDState,
217226
certVState,
@@ -222,10 +231,14 @@ import Cardano.Ledger.Shelley.LedgerState (
222231
epochStateTreasuryL,
223232
esLStateL,
224233
lsCertState,
234+
lsCertStateL,
225235
lsUTxOState,
236+
lsUTxOStateL,
226237
newEpochStateGovStateL,
238+
utxosGovStateL,
227239
utxosStakeDistr,
228240
vsCommitteeState,
241+
vsCommitteeStateL,
229242
vsDReps,
230243
)
231244
import Cardano.Ledger.UMap
@@ -236,8 +249,10 @@ import Control.Monad.Trans.Reader (ReaderT, ask)
236249
import Data.Aeson (KeyValue, ToJSON (..), object, pairs, (.=))
237250
import Data.Default (Default (..))
238251
import Data.Foldable (Foldable (..))
252+
import qualified Data.Foldable as F (foldl')
239253
import Data.Map.Strict (Map)
240254
import qualified Data.Map.Strict as Map
255+
import qualified Data.Set as Set
241256
import Data.Word (Word64)
242257
import GHC.Generics (Generic)
243258
import Lens.Micro
@@ -541,3 +556,21 @@ defaultStakePoolVote poolId poolParams dRepDelegations =
541556
toDefaultVote (Just DRepAlwaysAbstain) = DefaultAbstain
542557
toDefaultVote (Just DRepAlwaysNoConfidence) = DefaultNoConfidence
543558
toDefaultVote _ = DefaultNo
559+
560+
authorizedElectedHotCommitteeCredentials ::
561+
ConwayEraGov era =>
562+
LedgerState era ->
563+
Set.Set (Credential 'HotCommitteeRole (EraCrypto era))
564+
authorizedElectedHotCommitteeCredentials ledgerState =
565+
case ledgerState ^. lsUTxOStateL . utxosGovStateL . committeeGovStateL of
566+
SNothing -> Set.empty
567+
SJust electedCommiteee ->
568+
collectAuthorizedHotCreds $
569+
csCommitteeCreds committeeState `Map.intersection` committeeMembers electedCommiteee
570+
where
571+
committeeState = ledgerState ^. lsCertStateL . certVStateL . vsCommitteeStateL
572+
collectAuthorizedHotCreds =
573+
let toHotCredSet !acc = \case
574+
CommitteeHotCredential hotCred -> Set.insert hotCred acc
575+
CommitteeMemberResigned {} -> acc
576+
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
@@ -592,8 +592,9 @@ instance
592592
wrapEvent = CertsEvent . CertEvent . DelegEvent
593593

594594
instance
595-
( EraGov era
596-
, EraTx era
595+
( EraTx era
596+
, ConwayEraGov era
597+
, ConwayEraTxBody era
597598
, EraRule "MEMPOOL" era ~ ConwayMEMPOOL era
598599
, PredicateFailure (EraRule "MEMPOOL" era) ~ ConwayMempoolPredFailure era
599600
, 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/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,16 +23,18 @@ 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
31+
import qualified Data.Map.Strict as Map
3032
import qualified Data.Sequence as Seq
3133
import qualified Data.Set as Set
3234
import Lens.Micro ((&), (.~), (^.))
3335
import Lens.Micro.Mtl (use)
3436
import Test.Cardano.Ledger.Conway.ImpTest
37+
import Test.Cardano.Ledger.Core.Rational (IsRatio (..))
3538
import Test.Cardano.Ledger.Imp.Common
3639
import Test.Cardano.Ledger.Plutus.Examples (
3740
alwaysFailsWithDatum,
@@ -255,3 +258,42 @@ spec = do
255258
assertFailure $ "Unexpected failure while applyingTx: " <> show tx <> ": " <> show e
256259
Right (_, evs) ->
257260
length [ev | ev@(MempoolEvent (ConwayMempoolEvent _)) <- evs] `shouldBe` 1
261+
262+
it "Unelected Committee voting" $ whenPostBootstrap $ do
263+
globals <- use impGlobalsL
264+
slotNo <- use impLastTickG
265+
_ <- registerInitialCommittee
266+
ccCold <- KeyHashObj <$> freshKeyHash
267+
curEpochNo <- getsNES nesELL
268+
let action =
269+
UpdateCommittee
270+
SNothing
271+
mempty
272+
(Map.singleton ccCold (addEpochInterval curEpochNo (EpochInterval 7)))
273+
(1 %! 1)
274+
proposal <- mkProposal action
275+
submitTx_ $
276+
mkBasicTx (mkBasicTxBody & proposalProceduresTxBodyL .~ [proposal])
277+
ccHot <- registerCommitteeHotKey ccCold
278+
govActionId <- do
279+
rewardAccount <- registerRewardAccount
280+
submitTreasuryWithdrawals [(rewardAccount, Coin 1)]
281+
282+
nes <- use impNESL
283+
let ls = nes ^. nesEsL . esLStateL
284+
mempoolEnv = mkMempoolEnv nes slotNo
285+
tx <-
286+
fixupTx $
287+
mkBasicTx $
288+
mkBasicTxBody
289+
& votingProceduresTxBodyL
290+
.~ VotingProcedures
291+
( Map.singleton
292+
(CommitteeVoter ccHot)
293+
(Map.singleton govActionId (VotingProcedure VoteYes SNothing))
294+
)
295+
296+
case applyTx globals mempoolEnv ls tx of
297+
Left _ -> pure ()
298+
Right _ -> assertFailure $ "Expected failure due to an unallowed vote: " <> show tx
299+
withNoFixup $ submitTx_ tx

0 commit comments

Comments
 (0)