Skip to content

Commit 6abeb7f

Browse files
committed
Implement Predefined No Confidence DRep test except for last check
1 parent e65c797 commit 6abeb7f

File tree

2 files changed

+253
-20
lines changed

2 files changed

+253
-20
lines changed

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/LedgerEvents/Gov/PredefinedAbstainDRep.hs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77

88
module Cardano.Testnet.Test.LedgerEvents.Gov.PredefinedAbstainDRep
99
( hprop_check_predefined_abstain_drep
10+
, delegateToAutomaticDRep
11+
, desiredPoolNumberProposalTest
12+
, getDesiredPoolNumberValue
13+
, voteChangeProposal
1014
) where
1115

1216
import Cardano.Api as Api
@@ -124,8 +128,25 @@ delegateToAlwaysAbstain
124128
-> PaymentKeyInfo
125129
-> StakingKeyPair
126130
-> m ()
127-
delegateToAlwaysAbstain execConfig epochStateView configurationFile socketPath sbe work prefix
128-
payingWallet skeyPair@(StakingKeyPair vKeyFile _sKeyFile) = do
131+
delegateToAlwaysAbstain execConfig epochStateView configurationFile socketPath sbe work prefix =
132+
delegateToAutomaticDRep execConfig epochStateView configurationFile socketPath sbe work prefix
133+
"--always-abstain"
134+
135+
delegateToAutomaticDRep
136+
:: (MonadTest m, MonadIO m, H.MonadAssertion m, MonadCatch m)
137+
=> H.ExecConfig
138+
-> EpochStateView
139+
-> FilePath
140+
-> FilePath
141+
-> ShelleyBasedEra ConwayEra
142+
-> FilePath
143+
-> String
144+
-> String
145+
-> PaymentKeyInfo
146+
-> StakingKeyPair
147+
-> m ()
148+
delegateToAutomaticDRep execConfig epochStateView configurationFile socketPath sbe work prefix
149+
flag payingWallet skeyPair@(StakingKeyPair vKeyFile _sKeyFile) = do
129150

130151
let era = toCardanoEra sbe
131152
cEra = AnyCardanoEra era
@@ -136,7 +157,7 @@ delegateToAlwaysAbstain execConfig epochStateView configurationFile socketPath s
136157
let voteDelegationCertificatePath = baseDir </> "delegation-certificate.delegcert"
137158
void $ H.execCli' execConfig
138159
[ "conway", "stake-address", "vote-delegation-certificate"
139-
, "--always-abstain"
160+
, flag
140161
, "--stake-verification-key-file", vKeyFile
141162
, "--out-file", voteDelegationCertificatePath
142163
]

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/LedgerEvents/Gov/PredefinedNoConfidenceDRep.hs

Lines changed: 229 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,42 @@
1+
{-# LANGUAGE BangPatterns #-}
12
{-# LANGUAGE DataKinds #-}
23
{-# LANGUAGE NamedFieldPuns #-}
34
{-# LANGUAGE OverloadedStrings #-}
45
{-# LANGUAGE ScopedTypeVariables #-}
6+
{-# LANGUAGE TypeApplications #-}
57

68
module Cardano.Testnet.Test.LedgerEvents.Gov.PredefinedNoConfidenceDRep
79
( hprop_check_predefined_no_confidence_drep
810
) where
911

1012
import Cardano.Api as Api
13+
import Cardano.Api.Error (displayError)
1114

1215
import Cardano.Testnet
16+
import Cardano.Testnet.Test.LedgerEvents.Gov.PredefinedAbstainDRep
17+
(delegateToAutomaticDRep, desiredPoolNumberProposalTest,
18+
getDesiredPoolNumberValue, voteChangeProposal)
1319

1420
import Prelude
1521

22+
import Control.Monad (void)
23+
import Control.Monad.Catch (MonadCatch)
24+
import qualified Data.Aeson as Aeson
25+
import qualified Data.Aeson.Lens as AL
26+
import qualified Data.ByteString.Lazy.Char8 as LBS
27+
import Data.String (fromString)
28+
import Data.Text (Text)
29+
import qualified Data.Text as Text
30+
import Data.Word (Word32)
31+
import GHC.Stack (callStack)
32+
import Lens.Micro ((^?))
1633
import System.FilePath ((</>))
1734

18-
import Testnet.Components.Query (getEpochStateView)
35+
import Testnet.Components.DReps (retrieveTransactionId, signTx, submitTx)
36+
import Testnet.Components.Query (EpochStateView, findLargestUtxoForPaymentKey,
37+
getCurrentEpochNo, getEpochStateView, getMinDRepDeposit)
38+
import Testnet.Defaults (defaultDelegatorStakeKeyPair)
39+
import qualified Testnet.Process.Cli as P
1940
import qualified Testnet.Process.Run as H
2041
import qualified Testnet.Property.Utils as H
2142
import Testnet.Runtime
@@ -36,7 +57,8 @@ hprop_check_predefined_no_confidence_drep = H.integrationWorkspace "test-activit
3657
work <- H.createDirectoryIfMissing $ tempAbsPath' </> "work"
3758

3859
-- Create default testnet with 3 DReps and 3 stake holders delegated, one to each DRep.
39-
let sbe = ShelleyBasedEraConway
60+
let ceo = ConwayEraOnwardsConway
61+
sbe = conwayEraOnwardsToShelleyBasedEra ceo
4062
era = toCardanoEra sbe
4163
cEra = AnyCardanoEra era
4264
fastTestnetOptions = cardanoDefaultTestnetOptions
@@ -48,20 +70,20 @@ hprop_check_predefined_no_confidence_drep = H.integrationWorkspace "test-activit
4870
testnetRuntime@TestnetRuntime
4971
{ testnetMagic
5072
, poolNodes
51-
, wallets=_wallet0:_wallet1:_wallet2:_
73+
, wallets=wallet0:wallet1:wallet2:_
5274
, configurationFile
5375
}
5476
<- cardanoTestnetDefault fastTestnetOptions conf
5577

5678
poolNode1 <- H.headM poolNodes
5779
poolSprocket1 <- H.noteShow $ nodeSprocket $ poolRuntime poolNode1
58-
_execConfig <- H.mkExecConfig tempBaseAbsPath poolSprocket1 testnetMagic
80+
execConfig <- H.mkExecConfig tempBaseAbsPath poolSprocket1 testnetMagic
5981

6082
let socketName' = IO.sprocketName poolSprocket1
6183
socketBase = IO.sprocketBase poolSprocket1 -- /tmp
6284
socketPath = socketBase </> socketName'
6385

64-
_epochStateView <- getEpochStateView (File configurationFile) (File socketPath)
86+
epochStateView <- getEpochStateView (File configurationFile) (File socketPath)
6587

6688
startLedgerNewEpochStateLogging testnetRuntime tempAbsPath'
6789

@@ -70,17 +92,207 @@ hprop_check_predefined_no_confidence_drep = H.integrationWorkspace "test-activit
7092
H.note_ $ "Socketpath: " <> socketPath
7193
H.note_ $ "Foldblocks config file: " <> configurationFile
7294

73-
_gov <- H.createDirectoryIfMissing $ work </> "governance"
95+
gov <- H.createDirectoryIfMissing $ work </> "governance"
7496

75-
-- ToDo: Do some proposal and vote yes with all the DReps.
76-
-- ToDo: ASSERT: that proposal passes.
77-
-- ToDo: Take the last two stake delegators and delegate them to "No Confidence".
78-
-- ToDo: This can be done using cardano-cli conway stake-address vote-delegation-certificate --always-no-confidence
79-
-- ToDo: Do some other proposal and vote yes with all the DReps.
80-
-- ToDo: ASSERT: the new proposal does NOT pass.
81-
-- ToDo: Create a no confidence proposal.
82-
-- ToDo: This can be done using cardano-cli conway governance action create-no-confidence
83-
-- ToDo: Vote no to the no confidence proposal with all DReps.
84-
-- ToDo: ASSERT: the no confidence proposal passes.
97+
-- Do some proposal and vote yes with all the DReps
98+
-- and assert that proposal passes.
99+
initialDesiredNumberOfPools <- getDesiredPoolNumberValue execConfig
85100

86-
success
101+
let newNumberOfDesiredPools = fromIntegral (initialDesiredNumberOfPools + 1)
102+
103+
firstProposalInfo <- desiredPoolNumberProposalTest execConfig epochStateView configurationFile socketPath ceo gov "firstProposal"
104+
wallet0 Nothing [(3, "yes")] newNumberOfDesiredPools newNumberOfDesiredPools 3
105+
106+
-- Take the last two stake delegators and delegate them to "No Confidence".
107+
delegateToAlwaysNoConfidence execConfig epochStateView configurationFile socketPath sbe gov "delegateToAbstain1"
108+
wallet1 (defaultDelegatorStakeKeyPair 2)
109+
delegateToAlwaysNoConfidence execConfig epochStateView configurationFile socketPath sbe gov "delegateToAbstain2"
110+
wallet1 (defaultDelegatorStakeKeyPair 3)
111+
112+
-- Do some other proposal and vote yes with all the DReps
113+
-- and assert the new proposal does NOT pass
114+
let newNumberOfDesiredPools2 = fromIntegral (newNumberOfDesiredPools + 1)
115+
116+
void $ desiredPoolNumberProposalTest execConfig epochStateView configurationFile socketPath ceo gov "secondProposal"
117+
wallet2 (Just firstProposalInfo) [(3, "yes")] newNumberOfDesiredPools2 newNumberOfDesiredPools 3
118+
119+
-- Create a no confidence proposal and vote "no" to the proposal with all DReps.
120+
-- Assert the no confidence proposal passes.
121+
void $ testNoConfidenceProposal execConfig epochStateView configurationFile socketPath ceo work "noConfidenceProposal"
122+
wallet0 firstProposalInfo [(3, "no")] 3
123+
124+
delegateToAlwaysNoConfidence
125+
:: (MonadTest m, MonadIO m, H.MonadAssertion m, MonadCatch m)
126+
=> H.ExecConfig
127+
-> EpochStateView
128+
-> FilePath
129+
-> FilePath
130+
-> ShelleyBasedEra ConwayEra
131+
-> FilePath
132+
-> String
133+
-> PaymentKeyInfo
134+
-> StakingKeyPair
135+
-> m ()
136+
delegateToAlwaysNoConfidence execConfig epochStateView configurationFile socketPath sbe work prefix =
137+
delegateToAutomaticDRep execConfig epochStateView configurationFile socketPath sbe work prefix
138+
"--always-no-confidence"
139+
140+
testNoConfidenceProposal
141+
:: (MonadTest m, MonadIO m, H.MonadAssertion m, MonadCatch m, Foldable t)
142+
=> H.ExecConfig
143+
-> EpochStateView
144+
-> FilePath
145+
-> FilePath
146+
-> ConwayEraOnwards ConwayEra
147+
-> FilePath
148+
-> FilePath
149+
-> PaymentKeyInfo
150+
-> (String, Word32)
151+
-> t (Int, String)
152+
-> Integer
153+
-> m (String, Word32)
154+
testNoConfidenceProposal execConfig epochStateView configurationFile socketPath ceo work prefix
155+
wallet previousProposalInfo votes epochsToWait = do
156+
157+
let sbe = conwayEraOnwardsToShelleyBasedEra ceo
158+
baseDir <- H.createDirectoryIfMissing $ work </> prefix
159+
160+
let propVotes :: [(String, Int)]
161+
propVotes = zip (concatMap (uncurry replicate) votes) [1..]
162+
annotateShow propVotes
163+
164+
thisProposal@(governanceActionTxId, governanceActionIndex) <-
165+
makeNoConfidenceProposal execConfig epochStateView (File configurationFile) (File socketPath)
166+
ceo baseDir "proposal" previousProposalInfo wallet
167+
168+
voteChangeProposal execConfig epochStateView sbe baseDir "vote"
169+
governanceActionTxId governanceActionIndex propVotes wallet
170+
171+
-- Wait two epochs
172+
(EpochNo epochAfterProp) <- getCurrentEpochNo epochStateView
173+
H.note_ $ "Epoch after \"" <> prefix <> "\" prop: " <> show epochAfterProp
174+
void $ waitUntilEpoch (File configurationFile) (File socketPath) (EpochNo (epochAfterProp + fromIntegral epochsToWait))
175+
176+
-- We check that no confidence proposal passes
177+
obtainedProposalId <- getLastEnactedCommitteeActionId execConfig
178+
obtainedProposalId === thisProposal
179+
180+
return thisProposal
181+
182+
getLastEnactedCommitteeActionId :: (MonadTest m, MonadCatch m, MonadIO m) => H.ExecConfig -> m (String, Word32)
183+
getLastEnactedCommitteeActionId execConfig = do
184+
govStateString <- H.execCli' execConfig
185+
[ "conway", "query", "gov-state"
186+
, "--volatile-tip"
187+
]
188+
189+
govStateJSON <- H.nothingFail (Aeson.decode (LBS.pack govStateString) :: Maybe Aeson.Value)
190+
191+
let mLastCommitteeAction :: Maybe Aeson.Value
192+
mLastCommitteeAction = govStateJSON
193+
^? AL.key "nextRatifyState"
194+
. AL.key "nextEnactState"
195+
. AL.key "prevGovActionIds"
196+
. AL.key "Committee"
197+
198+
lastCommitteeAction <- evalMaybe mLastCommitteeAction
199+
200+
let mLastCommitteeActionIx :: Maybe Integer
201+
mLastCommitteeActionIx = lastCommitteeAction ^? AL.key "govActionIx"
202+
. AL._Integer
203+
204+
lastCommitteeActionIx <- fromIntegral <$> evalMaybe mLastCommitteeActionIx
205+
206+
let mLastCommitteeActionTxId :: Maybe Text
207+
mLastCommitteeActionTxId = lastCommitteeAction ^? AL.key "txId"
208+
. AL._String
209+
210+
lastCommitteeActionTxId <- Text.unpack <$> evalMaybe mLastCommitteeActionTxId
211+
212+
return (lastCommitteeActionTxId, lastCommitteeActionIx)
213+
214+
makeNoConfidenceProposal
215+
:: (H.MonadAssertion m, MonadTest m, MonadCatch m, MonadIO m)
216+
=> H.ExecConfig
217+
-> EpochStateView
218+
-> NodeConfigFile 'In
219+
-> SocketPath
220+
-> ConwayEraOnwards ConwayEra
221+
-> FilePath
222+
-> String
223+
-> (String, Word32)
224+
-> PaymentKeyInfo
225+
-> m (String, Word32)
226+
makeNoConfidenceProposal execConfig epochStateView configurationFile socketPath
227+
ceo work prefix (prevGovernanceActionTxId, prevGovernanceActionIndex) wallet = do
228+
229+
let sbe = conwayEraOnwardsToShelleyBasedEra ceo
230+
era = toCardanoEra sbe
231+
cEra = AnyCardanoEra era
232+
233+
baseDir <- H.createDirectoryIfMissing $ work </> prefix
234+
235+
let stakeVkeyFp = baseDir </> "stake.vkey"
236+
stakeSKeyFp = baseDir </> "stake.skey"
237+
238+
_ <- P.cliStakeAddressKeyGen baseDir
239+
$ P.KeyNames { P.verificationKeyFile = stakeVkeyFp
240+
, P.signingKeyFile = stakeSKeyFp
241+
}
242+
243+
proposalAnchorFile <- H.note $ baseDir </> "sample-proposal-anchor"
244+
H.writeFile proposalAnchorFile "dummy anchor data"
245+
246+
proposalAnchorDataHash <- H.execCli' execConfig
247+
[ "conway", "governance"
248+
, "hash", "anchor-data", "--file-text", proposalAnchorFile
249+
]
250+
251+
minDRepDeposit <- getMinDRepDeposit epochStateView ceo
252+
253+
proposalFile <- H.note $ baseDir </> "sample-proposal-file"
254+
255+
void $ H.execCli' execConfig $
256+
[ "conway", "governance", "action", "create-no-confidence"
257+
, "--testnet"
258+
, "--governance-action-deposit", show @Integer minDRepDeposit
259+
, "--deposit-return-stake-verification-key-file", stakeVkeyFp
260+
, "--prev-governance-action-tx-id", prevGovernanceActionTxId
261+
, "--prev-governance-action-index", show prevGovernanceActionIndex
262+
, "--anchor-url", "https://tinyurl.com/3wrwb2as"
263+
, "--anchor-data-hash", proposalAnchorDataHash
264+
, "--out-file", proposalFile
265+
]
266+
267+
proposalBody <- H.note $ baseDir </> "tx.body"
268+
txIn <- findLargestUtxoForPaymentKey epochStateView sbe wallet
269+
270+
void $ H.execCli' execConfig
271+
[ "conway", "transaction", "build"
272+
, "--change-address", Text.unpack $ paymentKeyInfoAddr wallet
273+
, "--tx-in", Text.unpack $ renderTxIn txIn
274+
, "--proposal-file", proposalFile
275+
, "--out-file", proposalBody
276+
]
277+
278+
signedProposalTx <- signTx execConfig cEra baseDir "signed-proposal"
279+
(File proposalBody) [paymentKeyInfoPair wallet]
280+
281+
submitTx execConfig cEra signedProposalTx
282+
283+
governanceActionTxId <- retrieveTransactionId execConfig signedProposalTx
284+
285+
!propSubmittedResult <- findCondition (maybeExtractGovernanceActionIndex sbe (fromString governanceActionTxId))
286+
(unFile configurationFile)
287+
(unFile socketPath)
288+
(EpochNo 30)
289+
290+
governanceActionIndex <- case propSubmittedResult of
291+
Left e ->
292+
H.failMessage callStack
293+
$ "findCondition failed with: " <> displayError e
294+
Right Nothing ->
295+
H.failMessage callStack "Couldn't find proposal."
296+
Right (Just a) -> return a
297+
298+
return (governanceActionTxId, governanceActionIndex)

0 commit comments

Comments
 (0)