diff --git a/eras/conway/impl/src/Cardano/Ledger/Conway/Rules/Gov.hs b/eras/conway/impl/src/Cardano/Ledger/Conway/Rules/Gov.hs index 3b16b93ec95..75771ab7f38 100644 --- a/eras/conway/impl/src/Cardano/Ledger/Conway/Rules/Gov.hs +++ b/eras/conway/impl/src/Cardano/Ledger/Conway/Rules/Gov.hs @@ -103,6 +103,7 @@ import qualified Cardano.Ledger.Shelley.HardForks as HF (bootstrapPhase) import Cardano.Ledger.Shelley.PParams (pvCanFollow) import Cardano.Ledger.TxIn (TxId (..)) import Control.DeepSeq (NFData) +import Control.Monad (unless) import Control.Monad.Trans.Reader (asks) import Control.State.Transition.Extended ( STS (..), @@ -467,8 +468,9 @@ govTransition = do -- Policy check runTest $ checkPolicy @era constitutionPolicy proposalPolicy - -- The sum of all withdrawals must be positive - F.fold wdrls /= mempty ?! ZeroTreasuryWithdrawals pProcGovAction + unless (HF.bootstrapPhase (pp ^. ppProtocolVersionL)) $ + -- The sum of all withdrawals must be positive + F.fold wdrls /= mempty ?! ZeroTreasuryWithdrawals pProcGovAction UpdateCommittee _mPrevGovActionId membersToRemove membersToAdd _qrm -> do checkConflictingUpdate checkExpirationEpoch diff --git a/eras/conway/impl/testlib/Test/Cardano/Ledger/Conway/Imp/GovSpec.hs b/eras/conway/impl/testlib/Test/Cardano/Ledger/Conway/Imp/GovSpec.hs index 7c47ba2ee5b..234da5dd61a 100644 --- a/eras/conway/impl/testlib/Test/Cardano/Ledger/Conway/Imp/GovSpec.hs +++ b/eras/conway/impl/testlib/Test/Cardano/Ledger/Conway/Imp/GovSpec.hs @@ -59,7 +59,6 @@ spec = do proposalsWithVotingSpec votingSpec policySpec - withdrawalsSpec predicateFailuresSpec unknownCostModelsSpec @@ -70,6 +69,7 @@ relevantDuringBootstrapSpec :: ) => SpecWith (ImpTestState era) relevantDuringBootstrapSpec = do + withdrawalsSpec hardForkSpec pparamUpdateSpec proposalsSpec @@ -1154,55 +1154,53 @@ withdrawalsSpec :: withdrawalsSpec = describe "Withdrawals" $ do it "Fails with invalid network ID in withdrawal addresses" $ do - rewardAccount <- registerRewardAccount rewardCredential <- KeyHashObj <$> freshKeyHash let badRewardAccount = RewardAccount { raNetwork = Mainnet -- Our network is Testnet , raCredential = rewardCredential } - propDeposit <- getsNES $ nesEsL . curPParamsEpochStateL . ppGovActionDepositL - submitFailingProposal - ProposalProcedure - { pProcReturnAddr = rewardAccount - , pProcGovAction = - TreasuryWithdrawals - (Map.singleton badRewardAccount $ Coin 100_000_000) - SNothing - , pProcDeposit = propDeposit - , pProcAnchor = def - } - [ injectFailure $ - TreasuryWithdrawalsNetworkIdMismatch - (Set.singleton badRewardAccount) - Testnet - ] + wdrls = TreasuryWithdrawals (Map.singleton badRewardAccount $ Coin 100_000_000) SNothing + idMismatch = TreasuryWithdrawalsNetworkIdMismatch (Set.singleton badRewardAccount) Testnet + expectPredFailures [idMismatch] [idMismatch] wdrls it "Fails for empty withdrawals" $ do rwdAccount1 <- freshKeyHash >>= getRewardAccountFor . KeyHashObj rwdAccount2 <- freshKeyHash >>= getRewardAccountFor . KeyHashObj - let wdrl = TreasuryWithdrawals Map.empty SNothing - in submitFailingGovAction - wdrl - [injectFailure $ ZeroTreasuryWithdrawals wdrl] + let wdrls = TreasuryWithdrawals Map.empty SNothing + in expectPredFailures [ZeroTreasuryWithdrawals wdrls] [] wdrls - let wdrl = TreasuryWithdrawals [(rwdAccount1, zero)] SNothing - in submitFailingGovAction - wdrl - [injectFailure $ ZeroTreasuryWithdrawals wdrl] + let wdrls = TreasuryWithdrawals [(rwdAccount1, zero)] SNothing + in expectPredFailures [ZeroTreasuryWithdrawals wdrls] [] wdrls - let wdrl = TreasuryWithdrawals [(rwdAccount1, zero), (rwdAccount2, zero)] SNothing - in submitFailingGovAction - wdrl - [injectFailure $ ZeroTreasuryWithdrawals wdrl] + let wdrls = TreasuryWithdrawals [(rwdAccount1, zero), (rwdAccount2, zero)] SNothing + in expectPredFailures [ZeroTreasuryWithdrawals wdrls] [] wdrls rwdAccountRegistered <- registerRewardAccount - let wdrl = TreasuryWithdrawals [(rwdAccountRegistered, zero)] SNothing - in submitFailingGovAction - wdrl - [injectFailure $ ZeroTreasuryWithdrawals wdrl] + let wdrls = TreasuryWithdrawals [(rwdAccountRegistered, zero)] SNothing + in expectPredFailures [ZeroTreasuryWithdrawals wdrls] [] wdrls - void $ submitTreasuryWithdrawals [(rwdAccount1, zero), (rwdAccount2, Coin 100000)] + curProtVer <- getProtVer + let wdrls = [(rwdAccount1, zero), (rwdAccount2, Coin 100000)] + ga = TreasuryWithdrawals (Map.fromList wdrls) SNothing + in if HF.bootstrapPhase curProtVer + then do + expectPredFailures [] [] ga + else void $ submitTreasuryWithdrawals wdrls + where + expectPredFailures :: + [ConwayGovPredFailure era] -> [ConwayGovPredFailure era] -> GovAction era -> ImpTestM era () + expectPredFailures predFailures bootstrapPredFailures wdrl = do + curProtVer <- getProtVer + propP <- proposalWithRewardAccount wdrl + submitFailingProposal + propP + ( injectFailure + <$> ( if HF.bootstrapPhase curProtVer + then DisallowedProposalDuringBootstrap propP NE.:| bootstrapPredFailures + else NE.fromList predFailures + ) + ) proposalWithRewardAccount :: forall era.