From b8d12a53be963fd1ab767219c27394e700d715fe Mon Sep 17 00:00:00 2001 From: Sean D Gillespie Date: Wed, 13 Nov 2024 16:58:55 -0500 Subject: [PATCH 1/6] test: Add a new committee member rollback test --- .../test/Test/Cardano/Db/Mock/Unit/Conway.hs | 1 + .../Cardano/Db/Mock/Unit/Conway/Governance.hs | 123 +++++++++++++----- .../fingerprint/conwayRollbackNewCommittee | 1 + 3 files changed, 95 insertions(+), 30 deletions(-) create mode 100644 cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs index 40f87ae88..2d9a3d993 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs @@ -246,6 +246,7 @@ unitTests iom knownMigrations = , test "parameter change" Governance.parameterChange , test "hard fork" Governance.hardFork , test "info action" Governance.infoAction + , test "rollback new committee member" Governance.rollbackNewCommittee ] ] where diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs index 455b06aea..3eab6d56e 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs @@ -16,6 +16,7 @@ module Test.Cardano.Db.Mock.Unit.Conway.Governance ( parameterChange, hardFork, infoAction, + rollbackNewCommittee, ) where import qualified Cardano.Db as Db @@ -29,8 +30,8 @@ import Cardano.Ledger.Core (txIdTx) import Cardano.Ledger.Credential (Credential (..)) import Cardano.Ledger.Keys (KeyHash (..)) import Cardano.Ledger.SafeHash (SafeToHash (..)) -import Cardano.Mock.ChainSync.Server (IOManager) -import Cardano.Mock.Forging.Interpreter (getCurrentEpoch) +import Cardano.Mock.ChainSync.Server (IOManager, ServerHandle) +import Cardano.Mock.Forging.Interpreter (Interpreter, getCurrentEpoch) import qualified Cardano.Mock.Forging.Tx.Conway as Conway import qualified Cardano.Mock.Forging.Tx.Generic as Forging import Cardano.Mock.Forging.Types @@ -39,11 +40,13 @@ import Cardano.Prelude import Cardano.Slotting.Slot (EpochNo (..)) import qualified Data.Map as Map import Data.Maybe (fromJust) +import Data.Maybe.Strict (StrictMaybe (..)) import qualified Ouroboros.Consensus.Shelley.Eras as Consensus +import Ouroboros.Network.Block (blockPoint) import Test.Cardano.Db.Mock.Config import qualified Test.Cardano.Db.Mock.UnifiedApi as Api import Test.Cardano.Db.Mock.Validate -import Test.Tasty.HUnit (Assertion) +import Test.Tasty.HUnit (Assertion, assertFailure) import qualified Prelude drepDistr :: IOManager -> [(Text, Text)] -> Assertion @@ -80,48 +83,108 @@ newCommittee = -- Add stake void (Api.registerAllStakeCreds interpreter server) - -- Register a DRep and delegate votes to it void (Api.registerDRepsAndDelegateVotes interpreter server) - -- Create and vote for gov action - let committeeHash = "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541" - committeeCred = KeyHashObj (KeyHash committeeHash) + -- Propose, ratify, and enact a new committee member + epochs <- enactNewCommittee interpreter server - void $ - Api.withConwayFindLeaderAndSubmit interpreter server $ \ledger -> do - let - -- Create gov action tx - addCcTx = Conway.mkAddCommitteeTx committeeCred - -- Create votes for all stake pools. We start in the Conway bootstrap phase, so - -- DRep votes are not yet required. - addVoteTx = - Conway.mkGovVoteYesTx - govActionId - (Forging.drepVoters ++ Forging.resolveStakePoolVoters ledger) - govActionId = - GovActionId - { gaidTxId = txIdTx addCcTx - , gaidGovActionIx = GovActionIx 0 - } + -- Wait for it to sync + assertBlockNoBackoff dbSync (length epochs + 2) + -- Should now have a committee member + assertEqQuery + dbSync + Query.queryGovActionCounts + (1, 1, 0, 0) + "Unexpected governance action counts" + where + testLabel = "conwayNewCommittee" - -- Create votes - pure [addCcTx, addVoteTx] +rollbackNewCommittee :: IOManager -> [(Text, Text)] -> Assertion +rollbackNewCommittee = + withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do + startDBSync dbSync - -- It takes 2 epochs to enact a proposal--ratification will happen on the next - -- epoch and enacted on the following. - epochs <- Api.fillEpochs interpreter server 2 + -- Add stake + void (Api.registerAllStakeCreds interpreter server) + -- Register a DRep and delegate votes to it + void (Api.registerDRepsAndDelegateVotes interpreter server) + -- Propose, ratify, and enact a new committee member + epoch2 <- enactNewCommittee interpreter server -- Wait for it to sync - assertBlockNoBackoff dbSync (length epochs + 3) + assertBlockNoBackoff dbSync (length epoch2 + 2) -- Should now have a committee member assertEqQuery dbSync Query.queryGovActionCounts (1, 1, 0, 0) "Unexpected governance action counts" + + -- Rollback the last 2 blocks + epoch1' <- rollbackBlocks interpreter server 2 epoch2 + -- Wait for it to sync + assertBlockNoBackoff dbSync (length epoch1' + 4) + -- Should not have a new committee member + assertEqQuery + dbSync + Query.queryGovActionCounts + (1, 0, 0, 0) + "Unexpected governance action counts" where - testLabel = "conwayNewCommittee" + testLabel = "conwayRollbackNewCommittee" + +enactNewCommittee :: Interpreter -> ServerHandle IO CardanoBlock -> IO [CardanoBlock] +enactNewCommittee interpreter server = do + -- Create and vote for gov action + let committeeHash = "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541" + committeeCred = KeyHashObj (KeyHash committeeHash) + + blk <- + Api.withConwayFindLeaderAndSubmit interpreter server $ \ledger -> do + let + -- Create gov action tx + addCcTx = Conway.mkAddCommitteeTx committeeCred + -- Create votes for all stake pools. We start in the Conway bootstrap phase, so + -- DRep votes are not yet required. + addVoteTx = + Conway.mkGovVoteYesTx + govActionId + (Forging.drepVoters ++ Forging.resolveStakePoolVoters ledger) + govActionId = + GovActionId + { gaidTxId = txIdTx addCcTx + , gaidGovActionIx = GovActionIx 0 + } + + -- Create votes + pure [addCcTx, addVoteTx] + + -- It takes 2 epochs to enact a proposal--ratification will happen on the next + -- epoch and enacted on the following. + epochs <- Api.fillEpochs interpreter server 2 + pure (blk : epochs) + +rollbackBlocks :: + Interpreter -> + ServerHandle IO CardanoBlock -> + Int -> + [CardanoBlock] -> + IO [CardanoBlock] +rollbackBlocks interpreter server n blocks = do + (rollbackPoint, blocks') <- + case drop n (reverse blocks) of + (blk : blks) -> pure (blockPoint blk, blks) + [] -> assertFailure "Expected at least 3 blocks" + + -- Rollback to the previous epoch + Api.rollbackTo interpreter server rollbackPoint + -- Create a fork + newBlock <- + Api.withConwayFindLeaderAndSubmitTx interpreter server $ + Conway.mkSimpleDCertTx [(StakeIndexNew 1, Conway.mkRegTxCert SNothing)] + + pure (blocks' ++ [newBlock]) updateConstitution :: IOManager -> [(Text, Text)] -> Assertion updateConstitution = diff --git a/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee new file mode 100644 index 000000000..df2c8fb68 --- /dev/null +++ b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee @@ -0,0 +1 @@ +[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524,538,541,544,546,550,567,573,576,577,579,580,586,589,595,597,603,605,609,616,618,619,623,624,634,636,643,644,659,664,665,672,678,692,705,711,712,719,726,730,739,740,743,747,749,751,754,759,762,763,765,767,773,777,786,788,789,794,801,806,807,829,830,832,849,851,853,869,871,874,875,878,882,888,893,895,896,898,899,903,906,908,911,912,913,922,930,932,938,941,944,950,960,963,966,968,972,977,985,986,988,990,991,994,997,1001,997] \ No newline at end of file From b7e2f4e112bda462874103bccdcdf8a3123895d3 Mon Sep 17 00:00:00 2001 From: Sean D Gillespie Date: Tue, 19 Nov 2024 09:09:13 -0500 Subject: [PATCH 2/6] test: Add another check to new committee rollback --- cardano-chain-gen/src/Cardano/Mock/Query.hs | 13 +++++++++++++ .../Test/Cardano/Db/Mock/Unit/Conway/Governance.hs | 14 +++++++++++--- .../fingerprint/conwayRollbackNewCommittee | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/cardano-chain-gen/src/Cardano/Mock/Query.hs b/cardano-chain-gen/src/Cardano/Mock/Query.hs index a9ae27cde..77b3c7607 100644 --- a/cardano-chain-gen/src/Cardano/Mock/Query.hs +++ b/cardano-chain-gen/src/Cardano/Mock/Query.hs @@ -14,6 +14,7 @@ module Cardano.Mock.Query ( queryRewardRests, queryTreasuryDonations, queryVoteCounts, + queryEpochStateCount, ) where import qualified Cardano.Db as Db @@ -201,3 +202,15 @@ queryVoteCounts txHash idx = do &&. vote ^. Db.VotingProcedureIndex ==. val idx pure countRows pure (maybe 0 unValue res) + +queryEpochStateCount :: + MonadIO io => + Word64 -> + ReaderT SqlBackend io Word64 +queryEpochStateCount epochNo = do + res <- selectOne $ do + epochState <- from (table @Db.EpochState) + where_ (epochState ^. Db.EpochStateEpochNo ==. val epochNo) + pure countRows + + pure (maybe 0 unValue res) diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs index 3eab6d56e..eda4020b0 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs @@ -56,10 +56,8 @@ drepDistr = -- Add stake void (Api.registerAllStakeCreds interpreter server) - -- Register DRep and delegate votes to it void (Api.registerDRepsAndDelegateVotes interpreter server) - -- DRep distribution is calculated at end of the current epoch epoch1 <- Api.fillUntilNextEpoch interpreter server @@ -124,13 +122,23 @@ rollbackNewCommittee = -- Rollback the last 2 blocks epoch1' <- rollbackBlocks interpreter server 2 epoch2 -- Wait for it to sync - assertBlockNoBackoff dbSync (length epoch1' + 4) + assertBlockNoBackoff dbSync (length epoch1' + 3) -- Should not have a new committee member assertEqQuery dbSync Query.queryGovActionCounts (1, 0, 0, 0) "Unexpected governance action counts" + + -- Fast forward to next epoch + epoch2' <- Api.fillUntilNextEpoch interpreter server + assertBlockNoBackoff dbSync (length (epoch1' <> epoch2') + 3) + -- Should now have 2 identical committees + assertEqQuery + dbSync + (Query.queryEpochStateCount 2) + 2 + "Unexpected epoch state count for epoch 2" where testLabel = "conwayRollbackNewCommittee" diff --git a/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee index df2c8fb68..885914dce 100644 --- a/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee +++ b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee @@ -1 +1 @@ -[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524,538,541,544,546,550,567,573,576,577,579,580,586,589,595,597,603,605,609,616,618,619,623,624,634,636,643,644,659,664,665,672,678,692,705,711,712,719,726,730,739,740,743,747,749,751,754,759,762,763,765,767,773,777,786,788,789,794,801,806,807,829,830,832,849,851,853,869,871,874,875,878,882,888,893,895,896,898,899,903,906,908,911,912,913,922,930,932,938,941,944,950,960,963,966,968,972,977,985,986,988,990,991,994,997,1001,997] \ No newline at end of file +[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524,538,541,544,546,550,567,573,576,577,579,580,586,589,595,597,603,605,609,616,618,619,623,624,634,636,643,644,659,664,665,672,678,692,705,711,712,719,726,730,739,740,743,747,749,751,754,759,762,763,765,767,773,777,786,788,789,794,801,806,807,829,830,832,849,851,853,869,871,874,875,878,882,888,893,895,896,898,899,903,906,908,911,912,913,922,930,932,938,941,944,950,960,963,966,968,972,977,985,986,988,990,991,994,997,1001,997,1001] \ No newline at end of file From 1d8a84a84d8e642e5337867688517e42aa0cb3d0 Mon Sep 17 00:00:00 2001 From: Sean D Gillespie Date: Tue, 19 Nov 2024 14:24:22 -0500 Subject: [PATCH 3/6] test: Add a rollback new committee proposal --- cardano-chain-gen/src/Cardano/Mock/Query.hs | 23 +++++++ .../test/Test/Cardano/Db/Mock/Unit/Conway.hs | 1 + .../Cardano/Db/Mock/Unit/Conway/Governance.hs | 60 +++++++++++++++++-- .../test/Test/Cardano/Db/Mock/Validate.hs | 1 + .../conwayRollbackNewCommitteeProposal | 1 + 5 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommitteeProposal diff --git a/cardano-chain-gen/src/Cardano/Mock/Query.hs b/cardano-chain-gen/src/Cardano/Mock/Query.hs index 77b3c7607..d6830389f 100644 --- a/cardano-chain-gen/src/Cardano/Mock/Query.hs +++ b/cardano-chain-gen/src/Cardano/Mock/Query.hs @@ -15,6 +15,7 @@ module Cardano.Mock.Query ( queryTreasuryDonations, queryVoteCounts, queryEpochStateCount, + queryCommitteeByTxHash, ) where import qualified Cardano.Db as Db @@ -214,3 +215,25 @@ queryEpochStateCount epochNo = do pure countRows pure (maybe 0 unValue res) + +queryCommitteeByTxHash :: + MonadIO io => + ByteString -> + ReaderT SqlBackend io (Maybe Db.Committee) +queryCommitteeByTxHash txHash = do + res <- selectOne $ do + (committee :& _ :& tx) <- + from + $ table @Db.Committee + `innerJoin` table @Db.GovActionProposal + `on` ( \(committee :& govAction) -> + committee ^. Db.CommitteeGovActionProposalId ==. just (govAction ^. Db.GovActionProposalId) + ) + `innerJoin` table @Db.Tx + `on` ( \(_ :& govAction :& tx) -> + govAction ^. Db.GovActionProposalTxId ==. tx ^. Db.TxId + ) + where_ (tx ^. Db.TxHash ==. val txHash) + pure committee + + pure (entityVal <$> res) diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs index 2d9a3d993..40d4ab46f 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs @@ -247,6 +247,7 @@ unitTests iom knownMigrations = , test "hard fork" Governance.hardFork , test "info action" Governance.infoAction , test "rollback new committee member" Governance.rollbackNewCommittee + , test "rollback new committee member proposal" Governance.rollbackNewCommitteeProposal ] ] where diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs index eda4020b0..352d63c9a 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs @@ -17,11 +17,13 @@ module Test.Cardano.Db.Mock.Unit.Conway.Governance ( hardFork, infoAction, rollbackNewCommittee, + rollbackNewCommitteeProposal, ) where import qualified Cardano.Db as Db import Cardano.DbSync.Era.Shelley.Generic.Util (unCredentialHash, unTxHash) import Cardano.Ledger.Address (RewardAccount (..)) +import Cardano.Ledger.Alonzo.Tx (AlonzoTx) import Cardano.Ledger.BaseTypes (AnchorData (..), Network (..), hashAnchorData, textToUrl) import Cardano.Ledger.Coin (Coin (..)) import Cardano.Ledger.Conway.Governance (GovActionId (..), GovActionIx (..)) @@ -142,17 +144,56 @@ rollbackNewCommittee = where testLabel = "conwayRollbackNewCommittee" +rollbackNewCommitteeProposal :: IOManager -> [(Text, Text)] -> Assertion +rollbackNewCommitteeProposal = + withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do + startDBSync dbSync + + blks <- + sequence + [ -- Add stake + Api.registerAllStakeCreds interpreter server + , -- Register a DRep and delegate votes to it + Api.registerDRepsAndDelegateVotes interpreter server + ] + + -- Propose a new committee member + let proposal = proposeNewCommittee + proposalTxHash = unTxHash (txIdTx proposal) + void $ Api.withConwayFindLeaderAndSubmit interpreter server $ \_ -> + Right [proposal] + + -- Wait for it to sync + assertBlockNoBackoff dbSync (length blks + 1) + -- Should have a new committee + assertBackoff + dbSync + (Query.queryCommitteeByTxHash proposalTxHash) + defaultDelays + isJust + (const "Expected at least one new committee") + + -- Rollback one block + blks' <- rollbackBlocks interpreter server 1 blks + -- Wait for it to sync + assertBlockNoBackoff dbSync (length blks' + 1) + -- Should NOT have a new committee + assertBackoff + dbSync + (Query.queryCommitteeByTxHash proposalTxHash) + defaultDelays + isNothing + (const "Unexpected new committee") + where + testLabel = "conwayRollbackNewCommitteeProposal" + enactNewCommittee :: Interpreter -> ServerHandle IO CardanoBlock -> IO [CardanoBlock] enactNewCommittee interpreter server = do - -- Create and vote for gov action - let committeeHash = "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541" - committeeCred = KeyHashObj (KeyHash committeeHash) - blk <- Api.withConwayFindLeaderAndSubmit interpreter server $ \ledger -> do let -- Create gov action tx - addCcTx = Conway.mkAddCommitteeTx committeeCred + addCcTx = proposeNewCommittee -- Create votes for all stake pools. We start in the Conway bootstrap phase, so -- DRep votes are not yet required. addVoteTx = @@ -173,6 +214,13 @@ enactNewCommittee interpreter server = do epochs <- Api.fillEpochs interpreter server 2 pure (blk : epochs) +proposeNewCommittee :: AlonzoTx Consensus.StandardConway +proposeNewCommittee = + Conway.mkAddCommitteeTx committeeCred + where + committeeHash = "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541" + committeeCred = KeyHashObj (KeyHash committeeHash) + rollbackBlocks :: Interpreter -> ServerHandle IO CardanoBlock -> @@ -183,7 +231,7 @@ rollbackBlocks interpreter server n blocks = do (rollbackPoint, blocks') <- case drop n (reverse blocks) of (blk : blks) -> pure (blockPoint blk, blks) - [] -> assertFailure "Expected at least 3 blocks" + [] -> assertFailure $ "Expected at least " <> show n <> " blocks" -- Rollback to the previous epoch Api.rollbackTo interpreter server rollbackPoint diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Validate.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Validate.hs index fbe62f7e9..0cf96ff0a 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Validate.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Validate.hs @@ -40,6 +40,7 @@ module Test.Cardano.Db.Mock.Validate ( assertPoolCounters, poolCountersQuery, checkStillRuns, + defaultDelays, ) where import Cardano.Db diff --git a/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommitteeProposal b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommitteeProposal new file mode 100644 index 000000000..697c51f8a --- /dev/null +++ b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommitteeProposal @@ -0,0 +1 @@ +[12,16,18,16] \ No newline at end of file From 39f2df66d33597eaa90e3b32e79d1fb4b1c7981c Mon Sep 17 00:00:00 2001 From: Sean D Gillespie Date: Wed, 20 Nov 2024 14:24:12 -0500 Subject: [PATCH 4/6] test: Add a hard fork rollback test --- .../test/Test/Cardano/Db/Mock/Unit/Conway.hs | 1 + .../Cardano/Db/Mock/Unit/Conway/Governance.hs | 259 ++++++++++-------- .../testfiles/fingerprint/conwayDrepDistr | 2 +- .../testfiles/fingerprint/conwayNewCommittee | 2 +- .../fingerprint/conwayRollbackHardFork | 1 + .../fingerprint/conwayRollbackNewCommittee | 2 +- .../conwayRollbackNewCommitteeProposal | 2 +- 7 files changed, 147 insertions(+), 122 deletions(-) create mode 100644 cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackHardFork diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs index 40d4ab46f..1d91659f6 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs @@ -248,6 +248,7 @@ unitTests iom knownMigrations = , test "info action" Governance.infoAction , test "rollback new committee member" Governance.rollbackNewCommittee , test "rollback new committee member proposal" Governance.rollbackNewCommitteeProposal + , test "rollback hardfork" Governance.rollbackHardFork ] ] where diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs index 352d63c9a..85d124739 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs @@ -18,6 +18,7 @@ module Test.Cardano.Db.Mock.Unit.Conway.Governance ( infoAction, rollbackNewCommittee, rollbackNewCommitteeProposal, + rollbackHardFork, ) where import qualified Cardano.Db as Db @@ -56,15 +57,11 @@ drepDistr = withFullConfigAndDropDB conwayConfigDir testLabel $ \interpreter server dbSync -> do startDBSync dbSync - -- Add stake - void (Api.registerAllStakeCreds interpreter server) - -- Register DRep and delegate votes to it - void (Api.registerDRepsAndDelegateVotes interpreter server) - -- DRep distribution is calculated at end of the current epoch - epoch1 <- Api.fillUntilNextEpoch interpreter server + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server -- Wait for it to sync - assertBlockNoBackoff dbSync (length epoch1 + 2) + assertBlockNoBackoff dbSync (length epoch1) -- Should now have a DRep distribution let drepId = Prelude.head Forging.unregisteredDRepIds @@ -76,21 +73,31 @@ drepDistr = where testLabel = "conwayDrepDistr" +initGovernance :: Interpreter -> ServerHandle IO CardanoBlock -> IO [CardanoBlock] +initGovernance interpreter server = do + -- Add stake + blk1 <- Api.registerAllStakeCreds interpreter server + -- Register a DRep and delegate votes to it + blk2 <- Api.registerDRepsAndDelegateVotes interpreter server + -- DRep distribution is calculated at end of the current epoch + epoch0 <- Api.fillUntilNextEpoch interpreter server + -- Register committee hot credentials + blk3 <- Api.registerCommitteeCreds interpreter server + + pure $ (blk1 : blk2 : epoch0) ++ [blk3] + newCommittee :: IOManager -> [(Text, Text)] -> Assertion newCommittee = withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do startDBSync dbSync - -- Add stake - void (Api.registerAllStakeCreds interpreter server) - -- Register a DRep and delegate votes to it - void (Api.registerDRepsAndDelegateVotes interpreter server) - + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server -- Propose, ratify, and enact a new committee member - epochs <- enactNewCommittee interpreter server + epoch3 <- enactNewCommittee interpreter server -- Wait for it to sync - assertBlockNoBackoff dbSync (length epochs + 2) + assertBlockNoBackoff dbSync (length $ epoch1 <> epoch3) -- Should now have a committee member assertEqQuery dbSync @@ -105,15 +112,12 @@ rollbackNewCommittee = withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do startDBSync dbSync - -- Add stake - void (Api.registerAllStakeCreds interpreter server) - -- Register a DRep and delegate votes to it - void (Api.registerDRepsAndDelegateVotes interpreter server) - + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server -- Propose, ratify, and enact a new committee member - epoch2 <- enactNewCommittee interpreter server + epoch3 <- enactNewCommittee interpreter server -- Wait for it to sync - assertBlockNoBackoff dbSync (length epoch2 + 2) + assertBlockNoBackoff dbSync (length $ epoch1 <> epoch3) -- Should now have a committee member assertEqQuery dbSync @@ -122,9 +126,9 @@ rollbackNewCommittee = "Unexpected governance action counts" -- Rollback the last 2 blocks - epoch1' <- rollbackBlocks interpreter server 2 epoch2 + epoch1' <- rollbackBlocks interpreter server 2 epoch3 -- Wait for it to sync - assertBlockNoBackoff dbSync (length epoch1' + 3) + assertBlockNoBackoff dbSync (length $ epoch1 <> epoch1') -- Should not have a new committee member assertEqQuery dbSync @@ -134,13 +138,13 @@ rollbackNewCommittee = -- Fast forward to next epoch epoch2' <- Api.fillUntilNextEpoch interpreter server - assertBlockNoBackoff dbSync (length (epoch1' <> epoch2') + 3) + assertBlockNoBackoff dbSync (length $ epoch1 <> epoch1' <> epoch2') -- Should now have 2 identical committees assertEqQuery dbSync - (Query.queryEpochStateCount 2) + (Query.queryEpochStateCount 3) 2 - "Unexpected epoch state count for epoch 2" + "Unexpected epoch state count for epoch 3" where testLabel = "conwayRollbackNewCommittee" @@ -149,13 +153,8 @@ rollbackNewCommitteeProposal = withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do startDBSync dbSync - blks <- - sequence - [ -- Add stake - Api.registerAllStakeCreds interpreter server - , -- Register a DRep and delegate votes to it - Api.registerDRepsAndDelegateVotes interpreter server - ] + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server -- Propose a new committee member let proposal = proposeNewCommittee @@ -164,7 +163,7 @@ rollbackNewCommitteeProposal = Right [proposal] -- Wait for it to sync - assertBlockNoBackoff dbSync (length blks + 1) + assertBlockNoBackoff dbSync (length epoch1 + 1) -- Should have a new committee assertBackoff dbSync @@ -174,9 +173,9 @@ rollbackNewCommitteeProposal = (const "Expected at least one new committee") -- Rollback one block - blks' <- rollbackBlocks interpreter server 1 blks + epoch1' <- rollbackBlocks interpreter server 1 epoch1 -- Wait for it to sync - assertBlockNoBackoff dbSync (length blks' + 1) + assertBlockNoBackoff dbSync (length epoch1') -- Should NOT have a new committee assertBackoff dbSync @@ -230,7 +229,7 @@ rollbackBlocks :: rollbackBlocks interpreter server n blocks = do (rollbackPoint, blocks') <- case drop n (reverse blocks) of - (blk : blks) -> pure (blockPoint blk, blks) + (blk : blks) -> pure (blockPoint blk, blk : blks) [] -> assertFailure $ "Expected at least " <> show n <> " blocks" -- Rollback to the previous epoch @@ -240,24 +239,15 @@ rollbackBlocks interpreter server n blocks = do Api.withConwayFindLeaderAndSubmitTx interpreter server $ Conway.mkSimpleDCertTx [(StakeIndexNew 1, Conway.mkRegTxCert SNothing)] - pure (blocks' ++ [newBlock]) + pure $ reverse (newBlock : blocks') updateConstitution :: IOManager -> [(Text, Text)] -> Assertion updateConstitution = withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do startDBSync dbSync - -- Add stake - void (Api.registerAllStakeCreds interpreter server) - - -- Register a DRep and delegate votes to it - void (Api.registerDRepsAndDelegateVotes interpreter server) - - -- DRep distribution is calculated at end of the current epoch - epoch0 <- Api.fillUntilNextEpoch interpreter server - - -- Register committee hot credentials - void (Api.registerCommitteeCreds interpreter server) + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server let newUrl = fromJust (textToUrl 64 "constitution.new") dataHash = hashAnchorData @Consensus.StandardCrypto (AnchorData "constitution content") @@ -285,10 +275,10 @@ updateConstitution = -- It takes 2 epochs to enact a proposal--ratification will happen on the next -- epoch and enacted on the following. - epoch1 <- Api.fillEpochs interpreter server 2 + epoch3 <- Api.fillEpochs interpreter server 2 -- Wait for it to sync - assertBlockNoBackoff dbSync (length (epoch0 <> epoch1) + 4) + assertBlockNoBackoff dbSync (length (epoch1 <> epoch3) + 1) -- Constitution should now be updated (EpochNo epochNo) <- getCurrentEpoch interpreter @@ -305,17 +295,8 @@ treasuryWithdrawal = withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do startDBSync dbSync - -- Add stake - void (Api.registerAllStakeCreds interpreter server) - - -- Register a DRep and delegate votes to it - void (Api.registerDRepsAndDelegateVotes interpreter server) - - -- DRep distribution is calculated at end of the current epoch - epoch0 <- Api.fillUntilNextEpoch interpreter server - - -- Register committee hot credentials - void (Api.registerCommitteeCreds interpreter server) + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server -- Make sure we have treasury to spend void $ @@ -349,10 +330,10 @@ treasuryWithdrawal = -- It takes 2 epochs to enact a proposal--ratification will happen on the next -- epoch and enacted on the following. - epoch1 <- Api.fillEpochs interpreter server 2 + epoch3 <- Api.fillEpochs interpreter server 2 -- Wait for it to sync - assertBlockNoBackoff dbSync (length (epoch0 <> epoch1) + 5) + assertBlockNoBackoff dbSync (length (epoch1 <> epoch3) + 2) -- Should now have a treasury reward assertEqQuery @@ -368,14 +349,8 @@ parameterChange = withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do startDBSync dbSync - -- Add stake - void (Api.registerAllStakeCreds interpreter server) - -- Register a DRep and delegate votes to it - void (Api.registerDRepsAndDelegateVotes interpreter server) - -- DRep distribution is calculated at end of the current epoch - epoch0 <- Api.fillUntilNextEpoch interpreter server - -- Register committee hot credentials - void (Api.registerCommitteeCreds interpreter server) + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server -- Create and vote for gov action void $ @@ -403,10 +378,10 @@ parameterChange = -- It takes 2 epochs to enact a proposal--ratification will happen on the next -- epoch and enacted on the following. - epochs <- Api.fillEpochs interpreter server 2 + epoch3 <- Api.fillEpochs interpreter server 2 -- Wait for it to sync - assertBlockNoBackoff dbSync (length (epoch0 <> epochs) + 4) + assertBlockNoBackoff dbSync (length (epoch1 <> epoch3) + 1) -- Should now have a ratified/enacted governance action assertEqQuery dbSync @@ -432,44 +407,41 @@ hardFork = withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do startDBSync dbSync - -- Add stake - void (Api.registerAllStakeCreds interpreter server) - -- Register a DRep and delegate votes to it - void (Api.registerDRepsAndDelegateVotes interpreter server) - -- DRep distribution is calculated at end of the current epoch - epoch0 <- Api.fillUntilNextEpoch interpreter server - -- Register committee hot credentials - void (Api.registerCommitteeCreds interpreter server) + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server + -- Propose, ratify, and enact a hard fork + epoch3 <- enactHardFork interpreter server - -- Create and vote for gov action - void $ - Api.withConwayFindLeaderAndSubmit interpreter server $ \ledger -> do - let - -- Create gov action tx - govActionTx = Conway.mkHardForkInitTx - -- Crate vote tx - addVoteTx = - Conway.mkGovVoteYesTx - govActionId - ( Forging.drepVoters - ++ Forging.committeeVoters - ++ Forging.resolveStakePoolVoters ledger - ) - govActionId = - GovActionId - { gaidTxId = txIdTx govActionTx - , gaidGovActionIx = GovActionIx 0 - } + -- Wait for it to sync + assertBlockNoBackoff dbSync (length $ epoch1 <> epoch3) + -- Should now have a ratified/enacted governance action + assertEqQuery + dbSync + Query.queryGovActionCounts + (1, 1, 0, 0) + "Unexpected governance action counts" + -- Should have a new major protocol version + assertEqQuery + dbSync + (Query.queryVersionMajorFromEpoch =<< getEpochNo interpreter) + (Just 11) + "Unexpected governance action counts" + where + testLabel = "conwayGovernanceHardFork" + getEpochNo = fmap unEpochNo . liftIO . getCurrentEpoch - -- Create votes - pure [govActionTx, addVoteTx] +rollbackHardFork :: IOManager -> [(Text, Text)] -> Assertion +rollbackHardFork = + withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do + startDBSync dbSync - -- It takes 2 epochs to enact a proposal--ratification will happen on the next - -- epoch and enacted on the following. - epochs <- Api.fillEpochs interpreter server 2 + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server + -- Propose, ratify, and enact a hard fork + epoch3 <- enactHardFork interpreter server -- Wait for it to sync - assertBlockNoBackoff dbSync (length (epoch0 <> epochs) + 4) + assertBlockNoBackoff dbSync (length $ epoch1 <> epoch3) -- Should now have a ratified/enacted governance action assertEqQuery dbSync @@ -482,23 +454,74 @@ hardFork = (Query.queryVersionMajorFromEpoch =<< getEpochNo interpreter) (Just 11) "Unexpected governance action counts" + + -- Rollback the last 2 blocks + epoch2 <- rollbackBlocks interpreter server 2 epoch3 + -- Wait for it to sync + assertBlockNoBackoff dbSync (length $ epoch1 <> epoch2) + -- Should not have a new committee member + assertEqQuery + dbSync + Query.queryGovActionCounts + (1, 0, 0, 0) + "Unexpected governance action counts" + -- Should have the old major protocol version + assertEqQuery + dbSync + (Query.queryVersionMajorFromEpoch =<< getEpochNo interpreter) + (Just 10) + "Unexpected governance action counts" + + -- Fast forward to next epoch + epoch3' <- Api.fillUntilNextEpoch interpreter server + assertBlockNoBackoff dbSync (length $ epoch1 <> epoch2 <> epoch3') + -- Should once again have a new major protocol version + assertEqQuery + dbSync + (Query.queryVersionMajorFromEpoch =<< getEpochNo interpreter) + (Just 11) + "Unexpected governance action counts" where - testLabel = "conwayGovernanceHardFork" + testLabel = "conwayRollbackHardFork" getEpochNo = fmap unEpochNo . liftIO . getCurrentEpoch +enactHardFork :: Interpreter -> ServerHandle IO CardanoBlock -> IO [CardanoBlock] +enactHardFork interpreter server = do + blk <- + Api.withConwayFindLeaderAndSubmit interpreter server $ \ledger -> do + let + -- Create gov action tx + govActionTx = Conway.mkHardForkInitTx + -- Crate vote tx + addVoteTx = + Conway.mkGovVoteYesTx + govActionId + ( Forging.drepVoters + ++ Forging.committeeVoters + ++ Forging.resolveStakePoolVoters ledger + ) + govActionId = + GovActionId + { gaidTxId = txIdTx govActionTx + , gaidGovActionIx = GovActionIx 0 + } + + -- Create votes + pure [govActionTx, addVoteTx] + + -- It takes 2 epochs to enact a proposal--ratification will happen on the next + -- epoch and enacted on the following. + epoch2 <- Api.fillEpochs interpreter server 2 + + pure (blk : epoch2) + infoAction :: IOManager -> [(Text, Text)] -> Assertion infoAction = withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do startDBSync dbSync - -- Add stake - void (Api.registerAllStakeCreds interpreter server) - -- Register a DRep and delegate votes to it - void (Api.registerDRepsAndDelegateVotes interpreter server) - -- DRep distribution is calculated at end of the current epoch - epoch0 <- Api.fillUntilNextEpoch interpreter server - -- Register committee hot credentials - void (Api.registerCommitteeCreds interpreter server) + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server let -- Create gov action tx @@ -536,10 +559,10 @@ infoAction = pure [govActionTx, addVoteTx] -- There is no ratification/enactment for info actions, so let it expire - epochs <- Api.fillEpochs interpreter server 10 + epoch11 <- Api.fillEpochs interpreter server 10 -- Wait for it to sync - assertBlockNoBackoff dbSync (length (epoch0 <> epochs) + 4) + assertBlockNoBackoff dbSync (length (epoch1 <> epoch11) + 1) -- Should now be expired and dropped assertEqQuery dbSync diff --git a/cardano-chain-gen/test/testfiles/fingerprint/conwayDrepDistr b/cardano-chain-gen/test/testfiles/fingerprint/conwayDrepDistr index 1c8cb8caa..0845d76d4 100644 --- a/cardano-chain-gen/test/testfiles/fingerprint/conwayDrepDistr +++ b/cardano-chain-gen/test/testfiles/fingerprint/conwayDrepDistr @@ -1 +1 @@ -[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507] \ No newline at end of file +[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516] \ No newline at end of file diff --git a/cardano-chain-gen/test/testfiles/fingerprint/conwayNewCommittee b/cardano-chain-gen/test/testfiles/fingerprint/conwayNewCommittee index 79da17351..ebc1151d0 100644 --- a/cardano-chain-gen/test/testfiles/fingerprint/conwayNewCommittee +++ b/cardano-chain-gen/test/testfiles/fingerprint/conwayNewCommittee @@ -1 +1 @@ -[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524,538,541,544,546,550,567,573,576,577,579,580,586,589,595,597,603,605,609,616,618,619,623,624,634,636,643,644,659,664,665,672,678,692,705,711,712,719,726,730,739,740,743,747,749,751,754,759,762,763,765,767,773,777,786,788,789,794,801,806,807,829,830,832,849,851,853,869,871,874,875,878,882,888,893,895,896,898,899,903,906,908,911,912,913,922,930,932,938,941,944,950,960,963,966,968,972,977,985,986,988,990,991,994,997,1001] \ No newline at end of file +[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524,538,541,544,546,550,567,573,576,577,579,580,586,589,595,597,603,605,609,616,618,619,623,624,634,636,643,644,659,664,665,672,678,692,705,711,712,719,726,730,739,740,743,747,749,751,754,759,762,763,765,767,773,777,786,788,789,794,801,806,807,829,830,832,849,851,853,869,871,874,875,878,882,888,893,895,896,898,899,903,906,908,911,912,913,922,930,932,938,941,944,950,960,963,966,968,972,977,985,986,988,990,991,994,997,1001,1005,1008,1014,1019,1020,1021,1026,1027,1031,1032,1033,1036,1037,1049,1050,1053,1057,1062,1067,1068,1070,1074,1083,1102,1104,1107,1111,1115,1117,1118,1120,1125,1127,1137,1149,1151,1155,1161,1164,1167,1174,1187,1200,1201,1206,1213,1218,1221,1237,1242,1248,1258,1263,1266,1272,1277,1286,1299,1300,1304,1309,1313,1317,1336,1338,1343,1356,1363,1366,1376,1377,1379,1390,1397,1401,1408,1409,1410,1418,1423,1424,1429,1432,1435,1438,1439,1442,1444,1449,1453,1454,1461,1462,1470,1473,1474,1481,1484,1486,1504] \ No newline at end of file diff --git a/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackHardFork b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackHardFork new file mode 100644 index 000000000..c9e9d37d2 --- /dev/null +++ b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackHardFork @@ -0,0 +1 @@ +[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524,538,541,544,546,550,567,573,576,577,579,580,586,589,595,597,603,605,609,616,618,619,623,624,634,636,643,644,659,664,665,672,678,692,705,711,712,719,726,730,739,740,743,747,749,751,754,759,762,763,765,767,773,777,786,788,789,794,801,806,807,829,830,832,849,851,853,869,871,874,875,878,882,888,893,895,896,898,899,903,906,908,911,912,913,922,930,932,938,941,944,950,960,963,966,968,972,977,985,986,988,990,991,994,997,1001,1005,1008,1014,1019,1020,1021,1026,1027,1031,1032,1033,1036,1037,1049,1050,1053,1057,1062,1067,1068,1070,1074,1083,1102,1104,1107,1111,1115,1117,1118,1120,1125,1127,1137,1149,1151,1155,1161,1164,1167,1174,1187,1200,1201,1206,1213,1218,1221,1237,1242,1248,1258,1263,1266,1272,1277,1286,1299,1300,1304,1309,1313,1317,1336,1338,1343,1356,1363,1366,1376,1377,1379,1390,1397,1401,1408,1409,1410,1418,1423,1424,1429,1432,1435,1438,1439,1442,1444,1449,1453,1454,1461,1462,1470,1473,1474,1481,1484,1486,1501,1486,1501] \ No newline at end of file diff --git a/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee index 885914dce..b591dd372 100644 --- a/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee +++ b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommittee @@ -1 +1 @@ -[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524,538,541,544,546,550,567,573,576,577,579,580,586,589,595,597,603,605,609,616,618,619,623,624,634,636,643,644,659,664,665,672,678,692,705,711,712,719,726,730,739,740,743,747,749,751,754,759,762,763,765,767,773,777,786,788,789,794,801,806,807,829,830,832,849,851,853,869,871,874,875,878,882,888,893,895,896,898,899,903,906,908,911,912,913,922,930,932,938,941,944,950,960,963,966,968,972,977,985,986,988,990,991,994,997,1001,997,1001] \ No newline at end of file +[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524,538,541,544,546,550,567,573,576,577,579,580,586,589,595,597,603,605,609,616,618,619,623,624,634,636,643,644,659,664,665,672,678,692,705,711,712,719,726,730,739,740,743,747,749,751,754,759,762,763,765,767,773,777,786,788,789,794,801,806,807,829,830,832,849,851,853,869,871,874,875,878,882,888,893,895,896,898,899,903,906,908,911,912,913,922,930,932,938,941,944,950,960,963,966,968,972,977,985,986,988,990,991,994,997,1001,1005,1008,1014,1019,1020,1021,1026,1027,1031,1032,1033,1036,1037,1049,1050,1053,1057,1062,1067,1068,1070,1074,1083,1102,1104,1107,1111,1115,1117,1118,1120,1125,1127,1137,1149,1151,1155,1161,1164,1167,1174,1187,1200,1201,1206,1213,1218,1221,1237,1242,1248,1258,1263,1266,1272,1277,1286,1299,1300,1304,1309,1313,1317,1336,1338,1343,1356,1363,1366,1376,1377,1379,1390,1397,1401,1408,1409,1410,1418,1423,1424,1429,1432,1435,1438,1439,1442,1444,1449,1453,1454,1461,1462,1470,1473,1474,1481,1484,1486,1504,1486,1504] \ No newline at end of file diff --git a/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommitteeProposal b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommitteeProposal index 697c51f8a..26c5e85a8 100644 --- a/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommitteeProposal +++ b/cardano-chain-gen/test/testfiles/fingerprint/conwayRollbackNewCommitteeProposal @@ -1 +1 @@ -[12,16,18,16] \ No newline at end of file +[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524,516] \ No newline at end of file From 1b6a411514f06a91812f9cc6a316b1e61785e830 Mon Sep 17 00:00:00 2001 From: Sean D Gillespie Date: Thu, 21 Nov 2024 16:16:16 -0500 Subject: [PATCH 5/6] test: Add another new committee test --- .../src/Cardano/Mock/Forging/Tx/Conway.hs | 6 +- cardano-chain-gen/src/Cardano/Mock/Query.hs | 35 ++++++++++- .../test/Test/Cardano/Db/Mock/Unit/Conway.hs | 7 ++- .../Cardano/Db/Mock/Unit/Conway/Governance.hs | 59 +++++++++++++++++-- .../fingerprint/conwayChainedNewCommittee | 1 + 5 files changed, 98 insertions(+), 10 deletions(-) create mode 100644 cardano-chain-gen/test/testfiles/fingerprint/conwayChainedNewCommittee diff --git a/cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Conway.hs b/cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Conway.hs index 92595988c..3e08eaba0 100644 --- a/cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Conway.hs +++ b/cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Conway.hs @@ -542,11 +542,13 @@ mkTxDelegCert :: mkTxDelegCert f = ConwayTxCertDeleg . f mkAddCommitteeTx :: + Maybe (Governance.GovPurposeId 'Governance.CommitteePurpose StandardConway) -> Credential 'ColdCommitteeRole StandardCrypto -> AlonzoTx StandardConway -mkAddCommitteeTx cred = mkGovActionProposalTx govAction +mkAddCommitteeTx prevGovAction cred = mkGovActionProposalTx govAction where - govAction = Governance.UpdateCommittee SNothing mempty newMembers threshold + govAction = Governance.UpdateCommittee prevGovAction' mempty newMembers threshold + prevGovAction' = maybeToStrictMaybe prevGovAction newMembers = Map.singleton cred (EpochNo 20) threshold = fromJust $ boundRational (1 % 1) diff --git a/cardano-chain-gen/src/Cardano/Mock/Query.hs b/cardano-chain-gen/src/Cardano/Mock/Query.hs index d6830389f..46c645408 100644 --- a/cardano-chain-gen/src/Cardano/Mock/Query.hs +++ b/cardano-chain-gen/src/Cardano/Mock/Query.hs @@ -16,10 +16,11 @@ module Cardano.Mock.Query ( queryVoteCounts, queryEpochStateCount, queryCommitteeByTxHash, + queryCommitteeMemberCountByTxHash, ) where import qualified Cardano.Db as Db -import Cardano.Prelude hiding (from, on) +import Cardano.Prelude hiding (from, isNothing, on) import Database.Esqueleto.Experimental import Prelude () @@ -237,3 +238,35 @@ queryCommitteeByTxHash txHash = do pure committee pure (entityVal <$> res) + +queryCommitteeMemberCountByTxHash :: + MonadIO io => + Maybe ByteString -> + ReaderT SqlBackend io Word64 +queryCommitteeMemberCountByTxHash txHash = do + res <- selectOne $ do + (_ :& committee :& _ :& tx) <- + from + $ table @Db.CommitteeMember + `innerJoin` table @Db.Committee + `on` ( \(member :& committee) -> + member ^. Db.CommitteeMemberCommitteeId ==. committee ^. Db.CommitteeId + ) + `leftJoin` table @Db.GovActionProposal + `on` ( \(_ :& committee :& govAction) -> + committee ^. Db.CommitteeGovActionProposalId ==. govAction ?. Db.GovActionProposalId + ) + `leftJoin` table @Db.Tx + `on` ( \(_ :& _ :& govAction :& tx) -> + govAction ?. Db.GovActionProposalTxId ==. tx ?. Db.TxId + ) + + where_ $ + case txHash of + -- Search by Tx hash, if specified + Just _ -> tx ?. Db.TxHash ==. val txHash + -- Otherwise, get the initial committee + Nothing -> isNothing (committee ^. Db.CommitteeGovActionProposalId) + pure countRows + + pure (maybe 0 unValue res) diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs index 1d91659f6..96fb45ec8 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway.hs @@ -241,14 +241,15 @@ unitTests iom knownMigrations = "Governance" [ test "drep distribution" Governance.drepDistr , test "new committee member" Governance.newCommittee + , test "chained committee proposals" Governance.chainedNewCommittee + , test "rollback new committee member" Governance.rollbackNewCommittee + , test "rollback new committee member proposal" Governance.rollbackNewCommitteeProposal , test "update constitution" Governance.updateConstitution , test "treasury withdrawal" Governance.treasuryWithdrawal , test "parameter change" Governance.parameterChange , test "hard fork" Governance.hardFork - , test "info action" Governance.infoAction - , test "rollback new committee member" Governance.rollbackNewCommittee - , test "rollback new committee member proposal" Governance.rollbackNewCommitteeProposal , test "rollback hardfork" Governance.rollbackHardFork + , test "info action" Governance.infoAction ] ] where diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs index 85d124739..f8b8bb116 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs @@ -11,14 +11,15 @@ module Test.Cardano.Db.Mock.Unit.Conway.Governance ( drepDistr, newCommittee, + rollbackNewCommittee, + rollbackNewCommitteeProposal, updateConstitution, treasuryWithdrawal, parameterChange, + chainedNewCommittee, hardFork, - infoAction, - rollbackNewCommittee, - rollbackNewCommitteeProposal, rollbackHardFork, + infoAction, ) where import qualified Cardano.Db as Db @@ -148,6 +149,56 @@ rollbackNewCommittee = where testLabel = "conwayRollbackNewCommittee" +chainedNewCommittee :: IOManager -> [(Text, Text)] -> Assertion +chainedNewCommittee = + withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do + startDBSync dbSync + + -- Register SPOs, DReps, and committee to vote + epoch1 <- initGovernance interpreter server + + -- Wait for it to sync + assertBlockNoBackoff dbSync (length epoch1) + -- Should start with 4 committee members + assertEqQuery + dbSync + (Query.queryCommitteeMemberCountByTxHash Nothing) + 4 + "Unexpected committee member count" + + let + -- Propose a new committee member + committee1Hash = "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541" + committee1Cred = KeyHashObj (KeyHash committee1Hash) + proposal1 = Conway.mkAddCommitteeTx Nothing committee1Cred + + -- Propose another, using proposal1 as the prev governance action + committee2Hash = "f15d3cfda3ac52c86d2d98925419795588e74f4e270a3c17beabeaff" + committee2Cred = KeyHashObj (KeyHash committee2Hash) + proposal2 = Conway.mkAddCommitteeTx (Just prevGovActionId) committee2Cred + proposal2TxHash = unTxHash (txIdTx proposal2) + + prevGovActionId = + Governance.GovPurposeId $ + Governance.GovActionId + { gaidTxId = txIdTx proposal1 + , gaidGovActionIx = GovActionIx 0 + } + + void $ Api.withConwayFindLeaderAndSubmit interpreter server $ \_ -> + Right [proposal1, proposal2] + + -- Wait for it to sync + assertBlockNoBackoff dbSync (length epoch1 + 1) + -- Should now have 6 members + assertEqQuery + dbSync + (Query.queryCommitteeMemberCountByTxHash $ Just proposal2TxHash) + 6 + "Unexpected committee member count" + where + testLabel = "conwayChainedNewCommittee" + rollbackNewCommitteeProposal :: IOManager -> [(Text, Text)] -> Assertion rollbackNewCommitteeProposal = withFullConfig conwayConfigDir testLabel $ \interpreter server dbSync -> do @@ -215,7 +266,7 @@ enactNewCommittee interpreter server = do proposeNewCommittee :: AlonzoTx Consensus.StandardConway proposeNewCommittee = - Conway.mkAddCommitteeTx committeeCred + Conway.mkAddCommitteeTx Nothing committeeCred where committeeHash = "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541" committeeCred = KeyHashObj (KeyHash committeeHash) diff --git a/cardano-chain-gen/test/testfiles/fingerprint/conwayChainedNewCommittee b/cardano-chain-gen/test/testfiles/fingerprint/conwayChainedNewCommittee new file mode 100644 index 000000000..1795377c3 --- /dev/null +++ b/cardano-chain-gen/test/testfiles/fingerprint/conwayChainedNewCommittee @@ -0,0 +1 @@ +[12,16,18,21,24,30,31,32,33,40,41,42,43,47,52,60,62,70,80,84,86,92,98,100,106,109,110,111,112,127,134,138,146,149,154,166,168,178,183,188,193,194,198,200,202,220,222,223,224,225,231,239,242,247,261,282,283,288,289,301,302,303,308,313,315,316,320,331,334,344,345,363,364,368,369,375,377,381,389,394,407,418,422,425,430,437,438,439,440,447,450,453,454,456,458,461,467,492,499,507,516,524] \ No newline at end of file From 5fc533912bcf9bb33a3b68d29ce329c596e8c5e7 Mon Sep 17 00:00:00 2001 From: Sean D Gillespie Date: Thu, 5 Dec 2024 11:55:26 -0500 Subject: [PATCH 6/6] refactor: Remove test duplication Move out new committee credentials to Forging module --- .../src/Cardano/Mock/Forging/Tx/Generic.hs | 7 +++++++ .../Test/Cardano/Db/Mock/Unit/Conway/Governance.hs | 11 +++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Generic.hs b/cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Generic.hs index 74ce75e12..ffab4b4ea 100644 --- a/cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Generic.hs +++ b/cardano-chain-gen/src/Cardano/Mock/Forging/Tx/Generic.hs @@ -25,6 +25,7 @@ module Cardano.Mock.Forging.Tx.Generic ( registeredByronGenesisKeys, registeredShelleyGenesisKeys, bootstrapCommitteeCreds, + unregisteredCommitteeCreds, unregisteredDRepIds, consPoolParams, getPoolStakeCreds, @@ -292,6 +293,12 @@ bootstrapCommitteeCreds = ) ] +unregisteredCommitteeCreds :: [Credential 'ColdCommitteeRole StandardCrypto] +unregisteredCommitteeCreds = + [ KeyHashObj $ KeyHash "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541" + , KeyHashObj $ KeyHash "f15d3cfda3ac52c86d2d98925419795588e74f4e270a3c17beabeaff" + ] + unregisteredDRepIds :: [Credential 'DRepRole StandardCrypto] unregisteredDRepIds = [KeyHashObj $ KeyHash "0d94e174732ef9aae73f395ab44507bfa983d65023c11a951f0c32e4"] diff --git a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs index f8b8bb116..f813c6727 100644 --- a/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs +++ b/cardano-chain-gen/test/Test/Cardano/Db/Mock/Unit/Conway/Governance.hs @@ -31,8 +31,6 @@ import Cardano.Ledger.Coin (Coin (..)) import Cardano.Ledger.Conway.Governance (GovActionId (..), GovActionIx (..)) import qualified Cardano.Ledger.Conway.Governance as Governance import Cardano.Ledger.Core (txIdTx) -import Cardano.Ledger.Credential (Credential (..)) -import Cardano.Ledger.Keys (KeyHash (..)) import Cardano.Ledger.SafeHash (SafeToHash (..)) import Cardano.Mock.ChainSync.Server (IOManager, ServerHandle) import Cardano.Mock.Forging.Interpreter (Interpreter, getCurrentEpoch) @@ -168,13 +166,11 @@ chainedNewCommittee = let -- Propose a new committee member - committee1Hash = "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541" - committee1Cred = KeyHashObj (KeyHash committee1Hash) + committee1Cred = Prelude.head Forging.unregisteredCommitteeCreds proposal1 = Conway.mkAddCommitteeTx Nothing committee1Cred -- Propose another, using proposal1 as the prev governance action - committee2Hash = "f15d3cfda3ac52c86d2d98925419795588e74f4e270a3c17beabeaff" - committee2Cred = KeyHashObj (KeyHash committee2Hash) + committee2Cred = Forging.unregisteredCommitteeCreds Prelude.!! 1 proposal2 = Conway.mkAddCommitteeTx (Just prevGovActionId) committee2Cred proposal2TxHash = unTxHash (txIdTx proposal2) @@ -268,8 +264,7 @@ proposeNewCommittee :: AlonzoTx Consensus.StandardConway proposeNewCommittee = Conway.mkAddCommitteeTx Nothing committeeCred where - committeeHash = "e0a714319812c3f773ba04ec5d6b3ffcd5aad85006805b047b082541" - committeeCred = KeyHashObj (KeyHash committeeHash) + committeeCred = Prelude.head Forging.unregisteredCommitteeCreds rollbackBlocks :: Interpreter ->