Skip to content

Commit

Permalink
Merge pull request #6017 from IntersectMBO/mgalazyn/test/add-stake-ad…
Browse files Browse the repository at this point in the history
…dress-registration-deregistration-test

cardano-testnet | Add stake address registration/deregistration test
  • Loading branch information
carbolymer authored Oct 28, 2024
2 parents 4184f92 + 6fa52d3 commit ee8501c
Show file tree
Hide file tree
Showing 27 changed files with 414 additions and 269 deletions.
13 changes: 7 additions & 6 deletions cardano-testnet/cardano-testnet.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -183,30 +183,31 @@ test-suite cardano-testnet-test

main-is: cardano-testnet-test.hs

other-modules: Cardano.Testnet.Test.Cli.LeadershipSchedule
Cardano.Testnet.Test.Cli.StakeSnapshot
Cardano.Testnet.Test.Cli.Transaction
Cardano.Testnet.Test.Cli.Conway.Plutus
other-modules: Cardano.Testnet.Test.Cli.Conway.Plutus
Cardano.Testnet.Test.Cli.Conway.StakeSnapshot
Cardano.Testnet.Test.Cli.KesPeriodInfo
Cardano.Testnet.Test.Cli.LeadershipSchedule
Cardano.Testnet.Test.Cli.Query
Cardano.Testnet.Test.Cli.QuerySlotNumber
Cardano.Testnet.Test.Cli.StakeSnapshot
Cardano.Testnet.Test.Cli.Transaction
Cardano.Testnet.Test.Cli.Transaction.RegisterDeregisterStakeAddress
Cardano.Testnet.Test.FoldEpochState
Cardano.Testnet.Test.Gov.CommitteeAddNew
Cardano.Testnet.Test.Gov.DRepActivity
Cardano.Testnet.Test.Gov.DRepDeposit
Cardano.Testnet.Test.Gov.DRepRetirement
Cardano.Testnet.Test.Gov.GovActionTimeout
Cardano.Testnet.Test.Gov.InfoAction
Cardano.Testnet.Test.Gov.NoConfidence
Cardano.Testnet.Test.Gov.PParamChangeFailsSPO
Cardano.Testnet.Test.Gov.PredefinedAbstainDRep
Cardano.Testnet.Test.Gov.ProposeNewConstitution
Cardano.Testnet.Test.Gov.ProposeNewConstitutionSPO
Cardano.Testnet.Test.Gov.GovActionTimeout
Cardano.Testnet.Test.Gov.TreasuryDonation
Cardano.Testnet.Test.Gov.TreasuryGrowth
Cardano.Testnet.Test.Gov.TreasuryWithdrawal
Cardano.Testnet.Test.Misc
Cardano.Testnet.Test.Gov.PredefinedAbstainDRep
Cardano.Testnet.Test.Node.Shutdown
Cardano.Testnet.Test.SanityCheck
Cardano.Testnet.Test.SubmitApi.Transaction
Expand Down
17 changes: 14 additions & 3 deletions cardano-testnet/src/Testnet/Components/Query.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module Testnet.Components.Query
, checkDRepState
, assertNewEpochState
, getGovActionLifetime
, getKeyDeposit
) where

import Cardano.Api as Api
Expand All @@ -48,7 +49,6 @@ import Cardano.Ledger.Api (ConwayGovState)
import qualified Cardano.Ledger.Api as L
import qualified Cardano.Ledger.Coin as L
import qualified Cardano.Ledger.Conway.Governance as L
import Cardano.Ledger.Conway.PParams (ConwayEraPParams)
import qualified Cardano.Ledger.Conway.PParams as L
import qualified Cardano.Ledger.Shelley.LedgerState as L
import qualified Cardano.Ledger.UTxO as L
Expand Down Expand Up @@ -571,11 +571,22 @@ assertNewEpochState epochStateView sbe maxWait lens expected = withFrozenCallSta
-- The @govActionLifetime@ or governance action maximum lifetime in epochs is
-- the number of epochs such that a governance action submitted during an epoch @e@
-- expires if it is still not ratified as of the end of epoch: @e + govActionLifetime + 1@.
getGovActionLifetime :: (ConwayEraPParams (ShelleyLedgerEra era), H.MonadAssertion m, MonadTest m, MonadIO m)
getGovActionLifetime :: (H.MonadAssertion m, MonadTest m, MonadIO m)
=> EpochStateView
-> ConwayEraOnwards era
-> m EpochInterval
getGovActionLifetime epochStateView ceo = do
getGovActionLifetime epochStateView ceo = conwayEraOnwardsConstraints ceo $ do
govState :: ConwayGovState era <- getGovState epochStateView ceo
return $ govState ^. L.cgsCurPParamsL
. L.ppGovActionLifetimeL

-- | Obtains the key registration deposit from the protocol parameters.
getKeyDeposit :: (H.MonadAssertion m, MonadTest m, MonadIO m)
=> EpochStateView
-> ConwayEraOnwards era
-> m L.Coin
getKeyDeposit epochStateView ceo = conwayEraOnwardsConstraints ceo $ do
govState :: ConwayGovState era <- getGovState epochStateView ceo
return $ govState ^. L.cgsCurPParamsL
. L.ppKeyDepositL

4 changes: 1 addition & 3 deletions cardano-testnet/src/Testnet/Defaults.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import qualified Cardano.Api.Shelley as Api
import Cardano.Ledger.Alonzo.Core (PParams (..))
import Cardano.Ledger.Alonzo.Genesis (AlonzoGenesis)
import qualified Cardano.Ledger.Alonzo.Genesis as Ledger
import qualified Cardano.Ledger.Api as L
import Cardano.Ledger.BaseTypes
import qualified Cardano.Ledger.BaseTypes as Ledger
import Cardano.Ledger.Binary.Version ()
Expand Down Expand Up @@ -388,8 +387,7 @@ defaultShelleyGenesis asbe startTime maxSupply options = do
-- TODO: find out why this actually degrates network stability - turned off for now
-- securityParam = ceiling $ fromIntegral epochLength * cardanoActiveSlotsCoeff / 10
pVer = eraToProtocolVersion asbe
-- TODO: Remove after merging https://github.com/IntersectMBO/cardano-node/pull/6017
protocolParams = Api.sgProtocolParams Api.shelleyGenesisDefaults & L.ppKeyDepositL .~ 0
protocolParams = Api.sgProtocolParams Api.shelleyGenesisDefaults
protocolParamsWithPVer = protocolParams & ppProtocolVersionL' .~ pVer
Api.shelleyGenesisDefaults
{ Api.sgActiveSlotsCoeff = unsafeBoundedRational activeSlotsCoeff
Expand Down
9 changes: 5 additions & 4 deletions cardano-testnet/src/Testnet/Process/Cli/DRep.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module Testnet.Process.Cli.DRep
) where

import Cardano.Api hiding (Certificate, TxBody)
import Cardano.Api.Experimental (Some (..))
import Cardano.Api.Ledger (EpochInterval (EpochInterval, unEpochInterval))

import Cardano.Testnet (maybeExtractGovernanceActionIndex)
Expand Down Expand Up @@ -239,7 +240,7 @@ registerDRep execConfig epochStateView ceo work prefix wallet = do
drepRegTxBody <- createCertificatePublicationTxBody execConfig epochStateView sbe baseDir "reg-cert-txbody"
drepRegCert wallet
drepSignedRegTx <- signTx execConfig cEra baseDir "signed-reg-tx"
drepRegTxBody [SomeKeyPair drepKeyPair, SomeKeyPair $ paymentKeyInfoPair wallet]
drepRegTxBody [Some drepKeyPair, Some $ paymentKeyInfoPair wallet]
submitTx execConfig cEra drepSignedRegTx

return drepKeyPair
Expand Down Expand Up @@ -286,8 +287,8 @@ delegateToDRep execConfig epochStateView sbe work prefix

-- Sign transaction
repRegSignedRegTx1 <- signTx execConfig cEra baseDir "signed-reg-tx"
repRegTxBody1 [ SomeKeyPair $ paymentKeyInfoPair payingWallet
, SomeKeyPair skeyPair]
repRegTxBody1 [ Some $ paymentKeyInfoPair payingWallet
, Some skeyPair]

-- Submit transaction
submitTx execConfig cEra repRegSignedRegTx1
Expand Down Expand Up @@ -398,7 +399,7 @@ makeActivityChangeProposal execConfig epochStateView ceo work
]

signedProposalTx <- signTx execConfig cEra baseDir "signed-proposal"
(File proposalBody) [SomeKeyPair $ paymentKeyInfoPair wallet]
(File proposalBody) [Some $ paymentKeyInfoPair wallet]

submitTx execConfig cEra signedProposalTx

Expand Down
108 changes: 54 additions & 54 deletions cardano-testnet/src/Testnet/Process/Cli/SPO.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ checkStakePoolRegistered
:: (MonadTest m, MonadCatch m, MonadIO m, HasCallStack)
=> TmpAbsolutePath
-> ExecConfig
-> FilePath -- ^ Stake pool cold verification key file
-> File (VKey StakeKey) In -- ^ Stake pool cold verification key file
-> FilePath -- ^ Output file path of stake pool info
-> m String -- ^ Stake pool ID
checkStakePoolRegistered tempAbsP execConfig poolColdVkeyFp outputFp =
checkStakePoolRegistered tempAbsP execConfig (File poolColdVkeyFp) outputFp =
GHC.withFrozenCallStack $ do
let tempAbsPath' = unTmpAbsPath tempAbsP
oFpAbs = tempAbsPath' </> outputFp
Expand Down Expand Up @@ -160,11 +160,11 @@ createStakeDelegationCertificate
:: (MonadTest m, MonadCatch m, MonadIO m, HasCallStack)
=> TmpAbsolutePath
-> ShelleyBasedEra era
-> FilePath -- ^ Delegate stake verification key file
-> File (VKey StakeKey) In -- ^ Delegate stake verification key file
-> String -- ^ Pool id
-> FilePath
-> m ()
createStakeDelegationCertificate tempAbsP sbe delegatorStakeVerKey poolId outputFp =
createStakeDelegationCertificate tempAbsP sbe (File delegatorStakeVerKey) poolId outputFp =
GHC.withFrozenCallStack $ do
let tempAbsPath' = unTmpAbsPath tempAbsP
execCli_
Expand All @@ -179,12 +179,11 @@ createStakeKeyRegistrationCertificate
:: (MonadTest m, MonadCatch m, MonadIO m, HasCallStack)
=> TmpAbsolutePath
-> AnyShelleyBasedEra
-> FilePath -- ^ Stake verification key file
-> Int -- ^ deposit amount used only in Conway
-> File (VKey StakeKey) In -- ^ Stake verification key file
-> L.Coin -- ^ deposit amount used only in Conway
-> FilePath -- ^ Output file path
-> m ()
createStakeKeyRegistrationCertificate tempAbsP asbe stakeVerKey deposit outputFp = GHC.withFrozenCallStack $ do
AnyShelleyBasedEra sbe <- return asbe
createStakeKeyRegistrationCertificate tempAbsP (AnyShelleyBasedEra sbe) (File stakeVerKey) (L.Coin deposit) outputFp = GHC.withFrozenCallStack $ do
let tempAbsPath' = unTmpAbsPath tempAbsP
extraArgs = monoidForEraInEon @ConwayEraOnwards (toCardanoEra sbe) $
const ["--key-reg-deposit-amt", show deposit]
Expand All @@ -201,10 +200,10 @@ createScriptStakeRegistrationCertificate
=> TmpAbsolutePath
-> AnyCardanoEra
-> FilePath -- ^ Script file
-> Int -- ^ Registration deposit amount used only in Conway
-> L.Coin -- ^ Registration deposit amount used only in Conway
-> FilePath -- ^ Output file path
-> m ()
createScriptStakeRegistrationCertificate tempAbsP (AnyCardanoEra cEra) scriptFile deposit outputFp =
createScriptStakeRegistrationCertificate tempAbsP (AnyCardanoEra cEra) scriptFile (L.Coin deposit) outputFp =
GHC.withFrozenCallStack $ do
let tempAbsPath' = unTmpAbsPath tempAbsP
extraArgs = monoidForEraInEon @ConwayEraOnwards cEra $
Expand All @@ -221,11 +220,11 @@ createStakeKeyDeregistrationCertificate
:: (MonadTest m, MonadCatch m, MonadIO m, HasCallStack)
=> TmpAbsolutePath
-> ShelleyBasedEra era
-> FilePath -- ^ Stake verification key file
-> Int -- ^ deposit amount used only in Conway
-> File (VKey StakeKey) In -- ^ Stake verification key file
-> L.Coin -- ^ deposit amount used only in Conway
-> FilePath -- ^ Output file path
-> m ()
createStakeKeyDeregistrationCertificate tempAbsP sbe stakeVerKey deposit outputFp =
createStakeKeyDeregistrationCertificate tempAbsP sbe (File stakeVerKey) (L.Coin deposit) outputFp =
GHC.withFrozenCallStack $ do
let tempAbsPath' = unTmpAbsPath tempAbsP
extraArgs = monoidForEraInEon @ConwayEraOnwards (toCardanoEra sbe) $
Expand All @@ -248,21 +247,18 @@ registerSingleSpo
-> SocketPath
-> EpochNo -- ^ Termination epoch
-> Int -- ^ Testnet magic
-> L.Coin -- ^ key deposit
-> ExecConfig
-> (TxIn, FilePath, String)
-> (TxIn, File (SKey PaymentKey) In, String)
-> m ( String
, FilePath
, FilePath
, FilePath
, FilePath
, KeyPair StakeKey
, KeyPair VrfKey
) -- ^ Result tuple:
-- 1. String: Registered stake pool ID
-- 2. FilePath: Stake pool cold signing key
-- 3. FilePath: Stake pool cold verification key
-- 4. FilePath: Stake pool VRF signing key
-- 5. FilePath: Stake pool VRF verification key
registerSingleSpo asbe identifier tap@(TmpAbsolutePath tempAbsPath') nodeConfigFile socketPath termEpoch testnetMag execConfig
(fundingInput, fundingSigninKey, changeAddr) = GHC.withFrozenCallStack $ do
-- 2. Stake pool cold keys
-- 3. Stake pool VRF keys
registerSingleSpo asbe identifier tap@(TmpAbsolutePath tempAbsPath') nodeConfigFile socketPath termEpoch testnetMag keyDeposit execConfig
(fundingInput, File fundingSigninKey, changeAddr) = GHC.withFrozenCallStack $ do
workDir <- H.note tempAbsPath'

-- In order to register a stake pool we need two certificates:
Expand All @@ -276,48 +272,53 @@ registerSingleSpo asbe identifier tap@(TmpAbsolutePath tempAbsPath') nodeConfigF
let spoReqDir = workDir </> "spo-"<> show identifier <> "-requirements"

H.createDirectoryIfMissing_ spoReqDir
let poolOwnerstakeVkeyFp = spoReqDir </> "pool-owner-stake.vkey"
poolOwnerstakeSKeyFp = spoReqDir </> "pool-owner-stake.skey"
let poolOwnerStakeKeys = KeyPair
{ verificationKey = File $ spoReqDir </> "pool-owner-stake.vkey"
, signingKey = File $ spoReqDir </> "pool-owner-stake.skey"
}

cliStakeAddressKeyGen
$ KeyPair (File poolOwnerstakeVkeyFp) (File poolOwnerstakeSKeyFp)
cliStakeAddressKeyGen poolOwnerStakeKeys

poolownerstakeaddr <- filter (/= '\n')
<$> execCli
[ "latest", "stake-address", "build"
, "--stake-verification-key-file", poolOwnerstakeVkeyFp
, "--stake-verification-key-file", verificationKeyFp poolOwnerStakeKeys
, "--testnet-magic", show @Int testnetMag
]

-- 2. Generate stake pool owner payment key pair
let poolOwnerPaymentVkeyFp = spoReqDir </> "pool-owner-payment.vkey"
poolOwnerPaymentSkeyFp = spoReqDir </> "pool-owner-payment.skey"
cliAddressKeyGen
$ KeyPair (File poolOwnerPaymentVkeyFp) (File poolOwnerPaymentSkeyFp)
let poolOwnerPaymentKeys = KeyPair
{ verificationKey = File $ spoReqDir </> "pool-owner-payment.vkey"
, signingKey = File $ spoReqDir </> "pool-owner-payment.skey"
}
cliAddressKeyGen poolOwnerPaymentKeys

poolowneraddresswstakecred <-
execCli [ "latest", "address", "build"
, "--payment-verification-key-file", poolOwnerPaymentVkeyFp
, "--stake-verification-key-file", poolOwnerstakeVkeyFp
, "--payment-verification-key-file", verificationKeyFp poolOwnerPaymentKeys
, "--stake-verification-key-file", verificationKeyFp poolOwnerStakeKeys
, "--testnet-magic", show @Int testnetMag
]

-- 3. Generate pool cold keys
let poolColdVkeyFp = spoReqDir </> "pool-cold.vkey"
poolColdSkeyFp = spoReqDir </> "pool-cold.skey"
let poolColdKeys = KeyPair
{ verificationKey = File $ spoReqDir </> "pool-cold.vkey"
, signingKey = File $ spoReqDir </> "pool-cold.skey"
}

execCli_
[ "latest", "node", "key-gen"
, "--cold-verification-key-file", poolColdVkeyFp
, "--cold-signing-key-file", poolColdSkeyFp
, "--cold-verification-key-file", verificationKeyFp poolColdKeys
, "--cold-signing-key-file", signingKeyFp poolColdKeys
, "--operational-certificate-issue-counter-file", spoReqDir </> "operator.counter"
]

-- 4. Generate VRF keys
let vrfVkeyFp = spoReqDir </> "pool-vrf.vkey"
vrfSkeyFp = spoReqDir </> "pool-vrf.skey"
cliNodeKeyGenVrf
$ KeyPair (File vrfVkeyFp) (File vrfSkeyFp)
let vrfKeys = KeyPair
{ verificationKey = File $ spoReqDir </> "pool-vrf.vkey"
, signingKey = File $ spoReqDir </> "pool-vrf.skey"
}
cliNodeKeyGenVrf vrfKeys

-- 5. Create registration certificate
let poolRegCertFp = spoReqDir </> "registration.cert"
Expand All @@ -330,21 +331,20 @@ registerSingleSpo asbe identifier tap@(TmpAbsolutePath tempAbsPath') nodeConfigF
, "--pool-pledge", "0"
, "--pool-cost", "0"
, "--pool-margin", "0"
, "--cold-verification-key-file", poolColdVkeyFp
, "--vrf-verification-key-file", vrfVkeyFp
, "--reward-account-verification-key-file", poolOwnerstakeVkeyFp
, "--pool-owner-stake-verification-key-file", poolOwnerstakeVkeyFp
, "--cold-verification-key-file", verificationKeyFp poolColdKeys
, "--vrf-verification-key-file", verificationKeyFp vrfKeys
, "--reward-account-verification-key-file", verificationKeyFp poolOwnerStakeKeys
, "--pool-owner-stake-verification-key-file", verificationKeyFp poolOwnerStakeKeys
, "--out-file", poolRegCertFp
]

-- Create pledge delegation certificate
-- NB: Pledger and owner can be the same

-- Create pledger registration certificate

createStakeKeyRegistrationCertificate tap asbe
poolOwnerstakeVkeyFp
0
(verificationKey poolOwnerStakeKeys)
keyDeposit
(workDir </> "pledger.regcert")

void $ execCli' execConfig
Expand All @@ -366,8 +366,8 @@ registerSingleSpo asbe identifier tap@(TmpAbsolutePath tempAbsPath') nodeConfigF
, "--tx-body-file", workDir </> "pledge-registration-cert.txbody"
, "--testnet-magic", show @Int testnetMag
, "--signing-key-file", fundingSigninKey
, "--signing-key-file", poolOwnerstakeSKeyFp
, "--signing-key-file", poolColdSkeyFp
, "--signing-key-file", signingKeyFp poolOwnerStakeKeys
, "--signing-key-file", signingKeyFp poolColdKeys
, "--out-file", pledgeAndPoolRegistrationTx
]

Expand Down Expand Up @@ -398,9 +398,9 @@ registerSingleSpo asbe identifier tap@(TmpAbsolutePath tempAbsPath') nodeConfigF
poolId <- checkStakePoolRegistered
tap
execConfig
poolColdVkeyFp
(verificationKey poolColdKeys)
currentRegistedPoolsJson
return (poolId, poolColdSkeyFp, poolColdVkeyFp, vrfSkeyFp, vrfVkeyFp)
return (poolId, poolColdKeys, vrfKeys)

-- | Generates Stake Pool Operator (SPO) voting files, using @cardano-cli@.
--
Expand Down
5 changes: 3 additions & 2 deletions cardano-testnet/src/Testnet/Process/Cli/Transaction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module Testnet.Process.Cli.Transaction
) where

import Cardano.Api hiding (Certificate, TxBody)
import Cardano.Api.Experimental (Some (..))
import Cardano.Api.Ledger (Coin (unCoin))

import Prelude
Expand Down Expand Up @@ -146,14 +147,14 @@ signTx
-> FilePath -- ^ Base directory path where the signed transaction file will be stored.
-> String -- ^ Prefix for the output signed transaction file name. The extension will be @.tx@.
-> File TxBody In -- ^ Transaction body to be signed, obtained using 'createCertificatePublicationTxBody' or similar.
-> [SomeKeyPair] -- ^ List of key pairs used for signing the transaction.
-> [Some KeyPair] -- ^ List of key pairs used for signing the transaction.
-> m (File SignedTx In)
signTx execConfig cEra work prefix txBody signatoryKeyPairs = do
let signedTx = File (work </> prefix <> ".tx")
void $ execCli' execConfig $
[ anyEraToString cEra, "transaction", "sign"
, "--tx-body-file", unFile txBody
] ++ (concat [["--signing-key-file", signingKeyFp kp] | SomeKeyPair kp <- signatoryKeyPairs]) ++
] ++ (concat [["--signing-key-file", signingKeyFp kp] | Some kp <- signatoryKeyPairs]) ++
[ "--out-file", unFile signedTx
]
return signedTx
Expand Down
Loading

0 comments on commit ee8501c

Please sign in to comment.