From b34d6b294dd190cb1e15ea78dfc269b289dc1a29 Mon Sep 17 00:00:00 2001 From: fanghr Date: Thu, 19 May 2022 20:12:24 +0800 Subject: [PATCH] refactor tests of the effect * test both the effect and governor in the spec * test that the effect and governor will fail when try setting the governor state to a invalid one --- .../Sample/Effect/GovernorMutation.hs | 111 +++++++++++------- agora-sample/Sample/Governor.hs | 2 +- agora-test/Spec/Effect/GovernorMutation.hs | 75 +++++++++--- 3 files changed, 125 insertions(+), 63 deletions(-) diff --git a/agora-sample/Sample/Effect/GovernorMutation.hs b/agora-sample/Sample/Effect/GovernorMutation.hs index b71457f..bbaf698 100644 --- a/agora-sample/Sample/Effect/GovernorMutation.hs +++ b/agora-sample/Sample/Effect/GovernorMutation.hs @@ -1,9 +1,14 @@ module Sample.Effect.GovernorMutation ( - validContext, + mkEffectTransaction, effectValidator, effectValidatorAddress, effectValidatorHash, atAssetClass, + govRef, + effectRef, + invalidNewGovernorDatum, + validNewGovernorDatum, + mkEffectDatum, ) where import Agora.Effect.GovernorMutation ( @@ -11,14 +16,13 @@ import Agora.Effect.GovernorMutation ( mutateGovernorValidator, ) import Agora.Governor (GovernorDatum (..)) -import Agora.Proposal (ProposalId (..)) +import Agora.Proposal (ProposalId (..), ProposalThresholds (..)) import Plutarch.Api.V1 (mkValidator, validatorHash) +import Plutarch.SafeMoney (Tagged (Tagged)) import Plutus.V1.Ledger.Address (scriptHashAddress) import Plutus.V1.Ledger.Api ( Address, Datum (..), - ScriptContext (..), - ScriptPurpose (Spending), ToData (..), TokenName (..), TxInInfo (..), @@ -42,15 +46,19 @@ import Sample.Shared ( ) import Test.Util (datumPair, toDatumHash) +-- | The effect validator instance. effectValidator :: Validator effectValidator = mkValidator $ mutateGovernorValidator governor +-- | The hash of the validator instance. effectValidatorHash :: ValidatorHash effectValidatorHash = validatorHash effectValidator +-- | The address of the validator. effectValidatorAddress :: Address effectValidatorAddress = scriptHashAddress effectValidatorHash +-- | The assetclass of the authority token. atAssetClass :: AssetClass atAssetClass = assetClass authorityTokenSymbol tokenName where @@ -58,20 +66,36 @@ atAssetClass = assetClass authorityTokenSymbol tokenName ValidatorHash bs = effectValidatorHash tokenName = TokenName bs -validContext :: ScriptContext -validContext = +-- | The mock reference of the governor state UTXO. +govRef :: TxOutRef +govRef = TxOutRef "614481d2159bfb72350222d61fce17e548e0fc00e5a1f841ff1837c431346ce7" 1 + +-- | The mock reference of the effect UTXO. +effectRef :: TxOutRef +effectRef = TxOutRef "c31164dc11835de7eb6187f67d0e1a19c1dfc0786a456923eef5043189cdb578" 1 + +-- | The input effect datum in 'mkEffectTransaction'. +mkEffectDatum :: GovernorDatum -> MutateGovernorDatum +mkEffectDatum newGovDatum = + MutateGovernorDatum + { governorRef = govRef + , newDatum = newGovDatum + } + +{- | Given the new governor state, create an effect to update the governor's state. + + Note that the transaction is valid only if the given new datum is valid. +-} +mkEffectTransaction :: GovernorDatum -> TxInfo +mkEffectTransaction newGovDatum = let gst = Value.assetClassValue govAssetClass 1 at = Value.assetClassValue atAssetClass 1 + -- One authority token is burnt in the process. burnt = Value.assetClassValue atAssetClass (-1) -- - governorInputRef :: TxOutRef - governorInputRef = TxOutRef "614481d2159bfb72350222d61fce17e548e0fc00e5a1f841ff1837c431346ce7" 1 - - -- - governorInputDatum' :: GovernorDatum governorInputDatum' = GovernorDatum @@ -92,21 +116,14 @@ validContext = -- The effect should update 'nextProposalId' effectInputDatum' :: MutateGovernorDatum - effectInputDatum' = - MutateGovernorDatum - { governorRef = governorInputRef - , newDatum = - governorInputDatum' - { nextProposalId = ProposalId 42 - } - } + effectInputDatum' = mkEffectDatum newGovDatum effectInputDatum :: Datum effectInputDatum = Datum $ toBuiltinData effectInputDatum' effectInput :: TxOut effectInput = TxOut { txOutAddress = effectValidatorAddress - , txOutValue = at + , txOutValue = at -- The effect carry an authotity token. , txOutDatumHash = Just $ toDatumHash effectInputDatum } @@ -123,27 +140,35 @@ validContext = , txOutValue = mconcat [gst, minAda] , txOutDatumHash = Just $ toDatumHash governorOutputDatum } - - -- - - ownInputRef :: TxOutRef - ownInputRef = TxOutRef "c31164dc11835de7eb6187f67d0e1a19c1dfc0786a456923eef5043189cdb578" 1 - in ScriptContext - { scriptContextPurpose = Spending ownInputRef - , scriptContextTxInfo = - TxInfo - { txInfoInputs = - [ TxInInfo ownInputRef effectInput - , TxInInfo governorInputRef governorInput - ] - , txInfoOutputs = [governorOutput] - , txInfoFee = Value.singleton "" "" 2 - , txInfoMint = burnt - , txInfoDCert = [] - , txInfoWdrl = [] - , txInfoValidRange = Interval.always - , txInfoSignatories = [signer] - , txInfoData = datumPair <$> [governorInputDatum, governorOutputDatum, effectInputDatum] - , txInfoId = "4dae3806cc69615b721d52ed09b758f43f25a8f39b7934d6b28514caf71f5f7b" - } + in TxInfo + { txInfoInputs = + [ TxInInfo effectRef effectInput + , TxInInfo govRef governorInput + ] + , txInfoOutputs = [governorOutput] + , txInfoFee = Value.singleton "" "" 2 + , txInfoMint = burnt + , txInfoDCert = [] + , txInfoWdrl = [] + , txInfoValidRange = Interval.always + , txInfoSignatories = [signer] + , txInfoData = datumPair <$> [governorInputDatum, governorOutputDatum, effectInputDatum] + , txInfoId = "4dae3806cc69615b721d52ed09b758f43f25a8f39b7934d6b28514caf71f5f7b" } + +validNewGovernorDatum :: GovernorDatum +validNewGovernorDatum = + GovernorDatum + { proposalThresholds = defaultProposalThresholds + , nextProposalId = ProposalId 42 + } + +invalidNewGovernorDatum :: GovernorDatum +invalidNewGovernorDatum = + GovernorDatum + { proposalThresholds = + defaultProposalThresholds + { countVoting = Tagged (-1) + } + , nextProposalId = ProposalId 42 + } diff --git a/agora-sample/Sample/Governor.hs b/agora-sample/Sample/Governor.hs index ff5f0bf..1704035 100644 --- a/agora-sample/Sample/Governor.hs +++ b/agora-sample/Sample/Governor.hs @@ -502,7 +502,7 @@ mintGATs = The effect script should carry an valid tagged authority token, and said token will be burnt in the transaction. We use 'noOpValidator' here as a mock effect, so no actual change is done to the governor state. - TODO: use 'mutateGovernorEffect' as the mock effect in the future. + TODO: use 'Agora.Effect.GovernorMutation.mutateGovernorEffect' as the mock effect in the future. The governor will ensure the new governor state is valid. -} diff --git a/agora-test/Spec/Effect/GovernorMutation.hs b/agora-test/Spec/Effect/GovernorMutation.hs index 354bf0b..207e0b1 100644 --- a/agora-test/Spec/Effect/GovernorMutation.hs +++ b/agora-test/Spec/Effect/GovernorMutation.hs @@ -1,30 +1,67 @@ module Spec.Effect.GovernorMutation (tests) where -import Agora.Effect.GovernorMutation (MutateGovernorDatum (..), mutateGovernorValidator) -import Agora.Governor (GovernorDatum (..)) +import Agora.Effect.GovernorMutation (mutateGovernorValidator) +import Agora.Governor (GovernorDatum (..), GovernorRedeemer (MutateGovernor)) +import Agora.Governor.Scripts (governorValidator) import Agora.Proposal (ProposalId (..)) -import Plutus.V1.Ledger.Api (TxOutRef (..)) -import Sample.Effect.GovernorMutation (validContext) -import Sample.Shared (defaultProposalThresholds, governor) +import Plutus.V1.Ledger.Api (ScriptContext (ScriptContext), ScriptPurpose (Spending)) +import Sample.Effect.GovernorMutation ( + effectRef, + govRef, + invalidNewGovernorDatum, + mkEffectDatum, + mkEffectTransaction, + validNewGovernorDatum, + ) +import Sample.Shared qualified as Shared import Test.Tasty (TestTree, testGroup) -import Test.Util (effectSucceedsWith) +import Test.Util (effectFailsWith, effectSucceedsWith, validatorFailsWith, validatorSucceedsWith) tests :: [TestTree] tests = [ testGroup "validator" - [ effectSucceedsWith - "Simple" - (mutateGovernorValidator governor) - ( MutateGovernorDatum - { governorRef = TxOutRef "614481d2159bfb72350222d61fce17e548e0fc00e5a1f841ff1837c431346ce7" 1 - , newDatum = - GovernorDatum - { nextProposalId = ProposalId 42 - , proposalThresholds = defaultProposalThresholds - } - } - ) - validContext + [ testGroup + "valid new governor datum" + [ validatorSucceedsWith + "governor" + (governorValidator Shared.governor) + ( GovernorDatum + { proposalThresholds = Shared.defaultProposalThresholds + , nextProposalId = ProposalId 0 + } + ) + MutateGovernor + ( ScriptContext + (mkEffectTransaction validNewGovernorDatum) + (Spending govRef) + ) + , effectSucceedsWith + "effect" + (mutateGovernorValidator Shared.governor) + (mkEffectDatum validNewGovernorDatum) + (ScriptContext (mkEffectTransaction validNewGovernorDatum) (Spending effectRef)) + ] + , testGroup + "invalid new governor datum" + [ validatorFailsWith + "governor" + (governorValidator Shared.governor) + ( GovernorDatum + { proposalThresholds = Shared.defaultProposalThresholds + , nextProposalId = ProposalId 0 + } + ) + MutateGovernor + ( ScriptContext + (mkEffectTransaction invalidNewGovernorDatum) + (Spending govRef) + ) + , effectFailsWith + "effect" + (mutateGovernorValidator Shared.governor) + (mkEffectDatum validNewGovernorDatum) + (ScriptContext (mkEffectTransaction invalidNewGovernorDatum) (Spending effectRef)) + ] ] ]