diff --git a/agora-specs/Sample/Proposal/UnlockStake.hs b/agora-specs/Sample/Proposal/UnlockStake.hs index e453b31..46dd491 100644 --- a/agora-specs/Sample/Proposal/UnlockStake.hs +++ b/agora-specs/Sample/Proposal/UnlockStake.hs @@ -1,12 +1,19 @@ module Sample.Proposal.UnlockStake ( - unlockStake, StakeRole (..), - UnlockStakeParameters (..), - votesTemplate, - emptyEffectFor, - mkProposalInputDatum, - mkStakeInputDatum, - mkProposalValidatorTestCase, + Parameters (..), + unlockStake, + mkTestTree, + mkVoterRetractVotesWhileVotingParameters, + mkVoterCreatorRetractVotesWhileVotingParameters, + mkCreatorRemoveCreatorLocksWhenFinishedParameters, + mkVoterCreatorRemoveAllLocksWhenFinishedParameters, + mkVoterUnlockStakeAfterVotingParameters, + mkVoterCreatorRemoveVoteLocksWhenLockedParameters, + mkRetractVotesWhileNotVoting, + mkUnockIrrelevantStakeParameters, + mkRemoveCreatorLockBeforeFinishedParameters, + mkRetractVotesWithCreatorStakeParamaters, + mkAlterStakeParameters, ) where -------------------------------------------------------------------------------- @@ -21,9 +28,8 @@ import Agora.Proposal ( ) import Agora.Proposal.Scripts (proposalValidator) import Agora.Proposal.Time (ProposalStartingTime (ProposalStartingTime)) -import Agora.Stake (ProposalLock (..), Stake (..), StakeDatum (..)) -import Control.Monad (join) -import Data.Coerce (coerce) +import Agora.Stake (ProposalLock (..), Stake (..), StakeDatum (..), StakeRedeemer (RetractVotes)) +import Agora.Stake.Scripts (stakeValidator) import Data.Default.Class (Default (def)) import Data.Tagged (Tagged (..), untag) import Plutarch.Context ( @@ -32,14 +38,15 @@ import Plutarch.Context ( input, output, script, + signedWith, txId, withDatum, - withRefIndex, - withTxId, + withOutRef, withValue, ) import PlutusLedgerApi.V1 ( DatumHash, + PubKeyHash, ScriptContext (..), ScriptPurpose (Spending), TxInfo (..), @@ -48,7 +55,7 @@ import PlutusLedgerApi.V1 ( ) import PlutusLedgerApi.V1.Value qualified as Value import PlutusTx.AssocMap qualified as AssocMap -import Sample.Proposal.Shared (proposalTxRef, stakeTxRef, testFunc) +import Sample.Proposal.Shared (stakeTxRef, testFunc) import Sample.Shared ( minAda, proposalPolicySymbol, @@ -59,7 +66,7 @@ import Sample.Shared ( stakeValidatorHash, ) import Sample.Shared qualified as Shared -import Test.Specification (SpecificationTree) +import Test.Specification (SpecificationTree, group) import Test.Util (sortValue, updateMap) -------------------------------------------------------------------------------- @@ -82,104 +89,130 @@ emptyEffectFor (ProposalVotes vs) = map (,AssocMap.empty) (AssocMap.keys vs) -- | The default vote option that will be used by functions in this module. -defaultVoteFor :: ResultTag -defaultVoteFor = ResultTag 0 +defVoteFor :: ResultTag +defVoteFor = ResultTag 0 -- | The default number of GTs the stake will have. -defaultStakedGTs :: Tagged _ Integer -defaultStakedGTs = Tagged 100000 +defStakedGTs :: Tagged _ Integer +defStakedGTs = 100000 + +{- | If 'Parameters.alterOutputStake' is set to true, the + 'StakeDatum.stakedAmount' will be set to this. +-} +alteredStakedGTs :: Tagged _ Integer +alteredStakedGTs = 100 + +-- | Default owner of the stakes. +defOwner :: PubKeyHash +defOwner = signer -- | How a stake has been used on a particular proposal. data StakeRole = -- | The stake was spent to vote for a paraticular option. Voter - | -- | The stake was used to created the proposal. + | -- | The stake was used to create the proposal. Creator + | -- | The stake was used to both create and vote for the proposal. + Both | -- | The stake has nothing to do with the proposal. Irrelevant + deriving stock (Bounded, Enum, Show) -- | Parameters for creating a 'TxOut' that unlocks a stake. -data UnlockStakeParameters = UnlockStakeParameters +data Parameters = Parameters { proposalCount :: Integer -- ^ The number of proposals in the 'TxOut'. - , stakeUsage :: StakeRole + , stakeRole :: StakeRole -- ^ The role of the stake we're unlocking. , retractVotes :: Bool -- ^ Whether to retract votes or not. + , removeVoterLock :: Bool + -- ^ Remove the voter locks from the input stake. + , removeCreatorLock :: Bool + -- ^ Remove the creator locks from the input stake. , proposalStatus :: ProposalStatus -- ^ The state of all the proposals. + , alterOutputStake :: Bool } -instance Show UnlockStakeParameters where - show p = - let role = case p.stakeUsage of - Voter -> "voter" - Creator -> "creator" - _ -> "irrelevant stake" +-- | Iterate over the proposal id of every proposal, given the number of proposals. +forEachProposalId :: Parameters -> (ProposalId -> a) -> [a] +forEachProposalId ps = forEachProposalId' ps.proposalCount + where + forEachProposalId' :: Integer -> (ProposalId -> a) -> [a] + forEachProposalId' 0 _ = error "zero proposal" + forEachProposalId' n f = f . ProposalId <$> [0 .. n - 1] - action = - if p.retractVotes - then "unlock stake + retract votes" - else "unlock stake" +-- | Create locks for the input stake given the parameters. +mkInputStakeLocks :: Parameters -> [ProposalLock] +mkInputStakeLocks ps = mconcat $ forEachProposalId ps $ mkStakeLocksFor ps.stakeRole + where + mkStakeLocksFor :: StakeRole -> ProposalId -> [ProposalLock] + mkStakeLocksFor sr pid = + let voted = [Voted pid defVoteFor] + created = [Created pid] + in case sr of + Voter -> voted + Creator -> created + Both -> voted <> created + _ -> [] - while = show p.proposalStatus +-- | Create locks for the output stake by removing locks from the input locks. +mkOutputStakeLocks :: Parameters -> [ProposalLock] +mkOutputStakeLocks ps = + filter + ( \lock -> not $ case lock of + Voted _ _ -> ps.removeVoterLock + Created _ -> ps.removeCreatorLock + ) + inputLocks + where + inputLocks = mkInputStakeLocks ps - proposalInfo = mconcat [show p.proposalCount, " proposals"] - in mconcat [proposalInfo, ", ", role, ", ", action, ", ", while] +-- | Create the stake input datum given the parameters. +mkStakeInputDatum :: Parameters -> StakeDatum +mkStakeInputDatum ps = + StakeDatum + { stakedAmount = defStakedGTs + , owner = defOwner + , lockedBy = mkInputStakeLocks ps + } + +-- | Create stake output datum given the parameters. +mkStakeOutputDatum :: Parameters -> StakeDatum +mkStakeOutputDatum ps = + let template = mkStakeInputDatum ps + stakedAmount' = + if ps.alterOutputStake + then alteredStakedGTs + else defStakedGTs + in template + { stakedAmount = stakedAmount' + , lockedBy = mkOutputStakeLocks ps + } -- | Generate some input proposals and their corresponding output proposals. -mkProposals :: UnlockStakeParameters -> [(ProposalDatum, ProposalDatum)] -mkProposals p = forEachProposalId p.proposalCount $ mkProposalDatumPair p - --- | Iterate over the proposal id of every proposal, given the number of proposals. -forEachProposalId :: Integer -> (ProposalId -> a) -> [a] -forEachProposalId 0 _ = error "zero proposal" -forEachProposalId n f = f . ProposalId <$> [0 .. n - 1] - --- | Create the input stake and its corresponding output stake. -mkStakeDatumPair :: UnlockStakeParameters -> (StakeDatum, StakeDatum) -mkStakeDatumPair c = - let output = - StakeDatum - { stakedAmount = defaultStakedGTs - , owner = signer - , lockedBy = [] - } - - inputLocks = join $ forEachProposalId c.proposalCount (mkStakeLocks c.stakeUsage) - - input = output {lockedBy = inputLocks} - in (input, output) - where - mkStakeLocks :: StakeRole -> ProposalId -> [ProposalLock] - mkStakeLocks Voter pid = [Voted pid defaultVoteFor] - mkStakeLocks Creator pid = [Created pid] - mkStakeLocks _ _ = [] +mkProposals :: Parameters -> [(ProposalDatum, ProposalDatum)] +mkProposals ps = forEachProposalId ps $ mkProposalDatumPair ps -- | Create the input proposal datum. -mkProposalInputDatum :: UnlockStakeParameters -> ProposalId -> ProposalDatum +mkProposalInputDatum :: Parameters -> ProposalId -> ProposalDatum mkProposalInputDatum p pid = fst $ mkProposalDatumPair p pid --- | Create the input stake datum. -mkStakeInputDatum :: UnlockStakeParameters -> StakeDatum -mkStakeInputDatum = fst . mkStakeDatumPair - -- | Create a input proposal and its corresponding output proposal. mkProposalDatumPair :: - UnlockStakeParameters -> + Parameters -> ProposalId -> (ProposalDatum, ProposalDatum) mkProposalDatumPair params pid = - let owner = signer - - inputVotes = mkInputVotes params.stakeUsage $ untag defaultStakedGTs + let inputVotes = mkInputVotes params.stakeRole $ untag defStakedGTs input = ProposalDatum { proposalId = pid , effects = emptyEffectFor votesTemplate , status = params.proposalStatus - , cosigners = [owner] + , cosigners = [defOwner] , thresholds = def , votes = inputVotes , timingConfig = def @@ -198,62 +231,62 @@ mkProposalDatumPair params pid = -- The staked amount/votes. Integer -> ProposalVotes - mkInputVotes Voter vc = - ProposalVotes $ - updateMap (Just . const vc) defaultVoteFor $ - getProposalVotes votesTemplate mkInputVotes Creator _ = ProposalVotes $ - updateMap (Just . const 1000) defaultVoteFor $ + updateMap (Just . const 1000) defVoteFor $ + getProposalVotes votesTemplate + mkInputVotes Irrelevant _ = votesTemplate + mkInputVotes _ vc = + ProposalVotes $ + updateMap (Just . const vc) defVoteFor $ getProposalVotes votesTemplate - mkInputVotes _ _ = votesTemplate -- | Create a 'TxInfo' that tries to unlock a stake. -unlockStake :: UnlockStakeParameters -> TxInfo -unlockStake p = +unlockStake :: Parameters -> TxInfo +unlockStake ps = let pst = Value.singleton proposalPolicySymbol "" 1 sst = Value.assetClassValue stakeAssetClass 1 - pIODatums = mkProposals p - (sInDatum, sOutDatum) = mkStakeDatumPair p + pIODatums = mkProposals ps proposals = foldMap - ( \(i, o) -> + ( \((i, o), idx) -> mconcat @BaseBuilder [ input $ script proposalValidatorHash . withValue pst . withDatum i - . withTxId proposalTxRef - . withRefIndex (coerce i.proposalId + 2) + . withOutRef (mkProposalRef idx) , output $ script proposalValidatorHash . withValue (sortValue $ pst <> minAda) . withDatum o ] ) - pIODatums + (zip pIODatums [0 ..]) stakeValue = sortValue $ mconcat [ Value.assetClassValue (untag stake.gtClassRef) - (untag defaultStakedGTs) + (untag defStakedGTs) , sst , minAda ] + sInDatum = mkStakeInputDatum ps + sOutDatum = mkStakeOutputDatum ps + stakes = mconcat @BaseBuilder [ input $ script stakeValidatorHash . withValue stakeValue . withDatum sInDatum - . withTxId stakeTxRef - . withRefIndex 1 + . withOutRef stakeRef , output $ script stakeValidatorHash . withValue stakeValue @@ -265,23 +298,243 @@ unlockStake p = [ txId "388bc0b897b3dadcd479da4c88291de4113a50b72ddbed001faf7fc03f11bc52" , proposals , stakes + , signedWith defOwner ] in buildTxInfoUnsafe builder --- | Create a test case that tests the proposal validator's @'Unlock' _@ redeemer. -mkProposalValidatorTestCase :: UnlockStakeParameters -> Bool -> SpecificationTree -mkProposalValidatorTestCase p shouldSucceed = - let datum = mkProposalInputDatum p $ ProposalId 0 - redeemer = Unlock - name = show p - scriptContext = - ScriptContext - (unlockStake p) - (Spending (TxOutRef proposalTxRef 2)) - in testFunc - shouldSucceed - name - (proposalValidator Shared.proposal) - datum - redeemer - scriptContext +-- | Reference to the stake UTXO. +stakeRef :: TxOutRef +stakeRef = TxOutRef stakeTxRef 1 + +-- | Generate the reference to a proposal UTXOs, given the index of the proposal. +mkProposalRef :: Int -> TxOutRef +mkProposalRef offset = TxOutRef stakeTxRef $ 2 + fromIntegral offset + +-- | Proposal redeemer used by 'mkTestTree', in this case it's always 'Unlock'. +proposalRedeemer :: ProposalRedeemer +proposalRedeemer = Unlock + +-- | Stake redeemer used by 'mkTestTree', in this case it's always 'RetractVotes'. +stakeRedeemer :: StakeRedeemer +stakeRedeemer = RetractVotes + +-------------------------------------------------------------------------------- + +{- | Legal parameters that retract votes while the proposals is in 'VotingReady' + state, and also remove voter locks from the stake, which is + used to vote on the proposals. +-} +mkVoterRetractVotesWhileVotingParameters :: Integer -> Parameters +mkVoterRetractVotesWhileVotingParameters nProposals = + Parameters + { proposalCount = nProposals + , stakeRole = Voter + , retractVotes = True + , removeVoterLock = True + , removeCreatorLock = False + , proposalStatus = VotingReady + , alterOutputStake = False + } + +{- | Legal parameters that retract votes while the proposals is in 'VotingReady' + state, and also remove voter locks from the stake, which is + used to both create and vote on the proposals. +-} +mkVoterCreatorRetractVotesWhileVotingParameters :: Integer -> Parameters +mkVoterCreatorRetractVotesWhileVotingParameters nProposals = + Parameters + { proposalCount = nProposals + , stakeRole = Both + , retractVotes = True + , removeVoterLock = True + , removeCreatorLock = False + , proposalStatus = VotingReady + , alterOutputStake = False + } + +{- | Legal parameters that remove creator locks from the stake while the + proposals is in 'Finished' state. The stake was only used for creating + the proposals. +-} +mkCreatorRemoveCreatorLocksWhenFinishedParameters :: Integer -> Parameters +mkCreatorRemoveCreatorLocksWhenFinishedParameters nProposals = + Parameters + { proposalCount = nProposals + , stakeRole = Creator + , retractVotes = False + , removeVoterLock = False + , removeCreatorLock = True + , proposalStatus = Finished + , alterOutputStake = False + } + +{- | Legal parameters that remove voter and creator locks from the stake while + the proposals is in 'Finished' state. The stake was used for creating + and voting on the proposals. +-} +mkVoterCreatorRemoveAllLocksWhenFinishedParameters :: Integer -> Parameters +mkVoterCreatorRemoveAllLocksWhenFinishedParameters nProposals = + Parameters + { proposalCount = nProposals + , stakeRole = Both + , retractVotes = False + , removeVoterLock = True + , removeCreatorLock = True + , proposalStatus = Finished + , alterOutputStake = False + } + +{- Legal parameters that remove voter locks from the stake after the voting + phrase. The stake was used only for voting on the proposals. +-} +mkVoterUnlockStakeAfterVotingParameters :: Integer -> [Parameters] +mkVoterUnlockStakeAfterVotingParameters nProposals = + map + ( \st -> + Parameters + { proposalCount = nProposals + , stakeRole = Voter + , retractVotes = False + , removeVoterLock = True + , removeCreatorLock = False + , proposalStatus = st + , alterOutputStake = False + } + ) + [Locked, Finished] + +{- Legal parameters that remove voter locks whenproposals are in phrase. + The stake was used for crating and voting on the proposals. +-} +mkVoterCreatorRemoveVoteLocksWhenLockedParameters :: Integer -> Parameters +mkVoterCreatorRemoveVoteLocksWhenLockedParameters nProposals = + Parameters + { proposalCount = nProposals + , stakeRole = Both + , retractVotes = False + , removeVoterLock = True + , removeCreatorLock = False + , proposalStatus = Locked + , alterOutputStake = False + } + +{- | Illegal parameters that retract votes when the proposals are not in voting + phrase. +-} +mkRetractVotesWhileNotVoting :: Integer -> [Parameters] +mkRetractVotesWhileNotVoting nProposals = do + role <- enumFrom Voter + status <- [Draft, Locked, Finished] + + pure $ + Parameters + { proposalCount = nProposals + , stakeRole = role + , retractVotes = True + , removeVoterLock = True + , removeCreatorLock = False + , proposalStatus = status + , alterOutputStake = False + } + +{- | Illegal parameter that try to unlock a stake that has nothing to do with + the proposals. +-} +mkUnockIrrelevantStakeParameters :: Integer -> [Parameters] +mkUnockIrrelevantStakeParameters nProposals = do + status <- [Draft, VotingReady, Locked, Finished] + retractVotes <- [True, False] + + pure $ + Parameters + { proposalCount = nProposals + , stakeRole = Irrelevant + , retractVotes = retractVotes + , removeVoterLock = True + , removeCreatorLock = True + , proposalStatus = status + , alterOutputStake = False + } + +{- | Illegal parameters that remove the creator locks before the proposals are + 'Finished'. +-} +mkRemoveCreatorLockBeforeFinishedParameters :: Integer -> [Parameters] +mkRemoveCreatorLockBeforeFinishedParameters nProposals = do + status <- [Draft, VotingReady, Locked] + + pure $ + Parameters + { proposalCount = nProposals + , stakeRole = Creator + , retractVotes = False + , removeVoterLock = False + , removeCreatorLock = True + , proposalStatus = status + , alterOutputStake = False + } + +{- | Illegal parameters that try to retract votes with a stake that was only used + for creating the proposals. +-} +mkRetractVotesWithCreatorStakeParamaters :: Integer -> Parameters +mkRetractVotesWithCreatorStakeParamaters nProposals = + Parameters + { proposalCount = nProposals + , stakeRole = Creator + , retractVotes = True + , removeVoterLock = True + , removeCreatorLock = True + , proposalStatus = VotingReady + , alterOutputStake = False + } + +{- | Illegal parameters that try to change the 'StakeDatum.stakedAmount' field of + the output stake datum. +-} +mkAlterStakeParameters :: Integer -> [Parameters] +mkAlterStakeParameters nProposals = do + role <- enumFrom Voter + status <- [Draft, Locked, Finished] + + pure $ + Parameters + { proposalCount = nProposals + , stakeRole = role + , retractVotes = True + , removeVoterLock = True + , removeCreatorLock = False + , proposalStatus = status + , alterOutputStake = True + } + +-------------------------------------------------------------------------------- + +{- | Create a test tree that runs both the stake validator and the proposal + validator. +-} +mkTestTree :: String -> Parameters -> Bool -> SpecificationTree +mkTestTree name ps isValid = group name [stake, proposal] + where + txInfo = unlockStake ps + + stake = + testFunc + (not ps.alterOutputStake) + "stake" + (stakeValidator Shared.stake) + (mkStakeInputDatum ps) + stakeRedeemer + (ScriptContext txInfo (Spending stakeRef)) + + proposal = + let idx = 0 + pid = ProposalId $ fromIntegral idx + ref = mkProposalRef idx + in testFunc + isValid + "propsoal" + (proposalValidator Shared.proposal) + (mkProposalInputDatum ps pid) + proposalRedeemer + (ScriptContext txInfo (Spending ref)) diff --git a/agora-specs/Spec/Proposal.hs b/agora-specs/Spec/Proposal.hs index a3c54df..0e5b0ad 100644 --- a/agora-specs/Spec/Proposal.hs +++ b/agora-specs/Spec/Proposal.hs @@ -9,7 +9,6 @@ module Spec.Proposal (specs) where import Agora.Proposal ( Proposal (..), - ProposalStatus (..), ) import Agora.Proposal.Scripts (proposalPolicy) import Sample.Proposal qualified as Proposal @@ -166,110 +165,92 @@ specs = pure $ Advance.mkTestTree name ps False ] in [draftGroup, legalGroup, illegalGroup] - , group "unlocking" $ do - proposalCount <- [1, 42] + , group "unlocking" $ + let proposalCountCases = [1, 5, 10, 42] - let legalGroup = group "legal" $ do - let voterRetractVotesAndUnlockStakeWhileVoting = - UnlockStake.mkProposalValidatorTestCase - UnlockStake.UnlockStakeParameters - { UnlockStake.proposalCount = proposalCount - , UnlockStake.stakeUsage = UnlockStake.Voter - , UnlockStake.retractVotes = True - , UnlockStake.proposalStatus = VotingReady - } - True - creatorUnlockStakeWhileFinished = - UnlockStake.mkProposalValidatorTestCase - UnlockStake.UnlockStakeParameters - { UnlockStake.proposalCount = proposalCount - , UnlockStake.stakeUsage = UnlockStake.Creator - , UnlockStake.retractVotes = False - , UnlockStake.proposalStatus = Finished - } - True + mkSubgroupName nProposals = "with " <> show nProposals <> " proposals" - let voterUnlockStakeAfterVoting = group "voter unlocks stake after voting" $ do - status <- [Finished, Locked] - - pure $ - UnlockStake.mkProposalValidatorTestCase - UnlockStake.UnlockStakeParameters - { UnlockStake.proposalCount = proposalCount - , UnlockStake.stakeUsage = UnlockStake.Voter - , UnlockStake.retractVotes = False - , UnlockStake.proposalStatus = status - } - True - - [ voterRetractVotesAndUnlockStakeWhileVoting - , creatorUnlockStakeWhileFinished - , voterUnlockStakeAfterVoting + mkLegalGroup nProposals = + group + (mkSubgroupName nProposals) + [ UnlockStake.mkTestTree + "voter: retract votes while voting" + (UnlockStake.mkVoterRetractVotesWhileVotingParameters nProposals) + True + , UnlockStake.mkTestTree + "voter/creator: retract votes while voting" + (UnlockStake.mkVoterCreatorRetractVotesWhileVotingParameters nProposals) + True + , UnlockStake.mkTestTree + "creator: remove creator locks when finished" + (UnlockStake.mkCreatorRemoveCreatorLocksWhenFinishedParameters nProposals) + True + , UnlockStake.mkTestTree + "voter/creator: remove all locks when finished" + (UnlockStake.mkVoterCreatorRemoveAllLocksWhenFinishedParameters nProposals) + True + , group "voter: unlock after voting" $ + map + ( \ps -> + let name = show ps.proposalStatus + in UnlockStake.mkTestTree name ps True + ) + (UnlockStake.mkVoterUnlockStakeAfterVotingParameters nProposals) + , UnlockStake.mkTestTree + "voter/creator: remove vote locks when locked" + (UnlockStake.mkVoterCreatorRemoveVoteLocksWhenLockedParameters nProposals) + True ] - let illegalGroup = group "illegal" $ do - let retractsVotesWhileNotVotingReady = - group "voter retracts votes while not voting" $ do - status <- [Draft, Locked, Finished] - - pure $ - UnlockStake.mkProposalValidatorTestCase - UnlockStake.UnlockStakeParameters - { UnlockStake.proposalCount = proposalCount - , UnlockStake.stakeUsage = UnlockStake.Voter - , UnlockStake.retractVotes = True - , UnlockStake.proposalStatus = status - } - False - - unlockIrrelevantStake = - group "unlock an irrelevant stake" $ do - status <- [Draft, VotingReady, Locked, Finished] - shouldRetractVotes <- [True, False] - - pure $ - UnlockStake.mkProposalValidatorTestCase - UnlockStake.UnlockStakeParameters - { UnlockStake.proposalCount = proposalCount - , UnlockStake.stakeUsage = UnlockStake.Irrelevant - , UnlockStake.retractVotes = shouldRetractVotes - , UnlockStake.proposalStatus = status - } - False - - unlockCreatorStakeBeforeFinished = - group "unlock creator stake before finished" $ do - status <- [Draft, VotingReady, Locked] - - pure $ - UnlockStake.mkProposalValidatorTestCase - UnlockStake.UnlockStakeParameters - { UnlockStake.proposalCount = proposalCount - , UnlockStake.stakeUsage = UnlockStake.Creator - , UnlockStake.retractVotes = False - , UnlockStake.proposalStatus = status - } - False - retractVotesWithCreatorStake = - group "creator stake retracts votes" $ do - status <- [Draft, VotingReady, Locked, Finished] - - pure $ - UnlockStake.mkProposalValidatorTestCase - UnlockStake.UnlockStakeParameters - { UnlockStake.proposalCount = proposalCount - , UnlockStake.stakeUsage = UnlockStake.Creator - , UnlockStake.retractVotes = True - , UnlockStake.proposalStatus = status - } - False - - [ retractsVotesWhileNotVotingReady - , unlockIrrelevantStake - , unlockCreatorStakeBeforeFinished - , retractVotesWithCreatorStake + mkIllegalGroup nProposals = + group + (mkSubgroupName nProposals) + [ group "retract votes while not voting" $ + map + ( \ps -> + let name = + "role: " <> show ps.stakeRole + <> ", status: " + <> show ps.proposalStatus + in UnlockStake.mkTestTree name ps False + ) + (UnlockStake.mkRetractVotesWhileNotVoting nProposals) + , group "unlock an irrelevant stake" $ + map + ( \ps -> + let name = + "status: " <> show ps.proposalStatus + <> "retract votes: " + <> show ps.retractVotes + in UnlockStake.mkTestTree name ps False + ) + (UnlockStake.mkUnockIrrelevantStakeParameters nProposals) + , group "remove creator too early" $ + map + ( \ps -> + let name = + "status: " <> show ps.proposalStatus + in UnlockStake.mkTestTree name ps False + ) + (UnlockStake.mkRemoveCreatorLockBeforeFinishedParameters nProposals) + , UnlockStake.mkTestTree + "creator: retract votes" + (UnlockStake.mkRetractVotesWithCreatorStakeParamaters nProposals) + False + , group "alter output stake datum" $ + map + ( \ps -> + let name = + "role: " <> show ps.stakeRole + <> ", status: " + <> show ps.proposalStatus + in UnlockStake.mkTestTree name ps False + ) + (UnlockStake.mkAlterStakeParameters nProposals) ] - [legalGroup, illegalGroup] + legalGroup = group "legal" $ map mkLegalGroup proposalCountCases + illegalGroup = group "illegal" $ map mkIllegalGroup proposalCountCases + in [legalGroup, illegalGroup] ] ] diff --git a/bench.csv b/bench.csv index 4f9330d..ccb5238 100644 --- a/bench.csv +++ b/bench.csv @@ -51,14 +51,158 @@ Agora/Proposal/validator/advancing/legal/advance to failed state/from: Locked/pr Agora/Proposal/validator/advancing/legal/advance to failed state/from: Locked/stake,122255811,317464,5225 Agora/Proposal/validator/advancing/illegal/insufficient votes/stake,122255811,317464,5225 Agora/Proposal/validator/advancing/illegal/initial state is Finished/stake,122255811,317464,5217 -"Agora/Proposal/validator/unlocking/legal/1 proposals, voter, unlock stake + retract votes, VotingReady",236724208,665425,8096 -"Agora/Proposal/validator/unlocking/legal/1 proposals, creator, unlock stake, Finished",204516343,585280,8093 -"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/1 proposals, voter, unlock stake, Finished",205832495,589164,8100 -"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/1 proposals, voter, unlock stake, Locked",205832495,589164,8100 -"Agora/Proposal/validator/unlocking/legal/42 proposals, voter, unlock stake + retract votes, VotingReady",1698797000,4895231,29286 -"Agora/Proposal/validator/unlocking/legal/42 proposals, creator, unlock stake, Finished",1312344666,3843304,29242 -"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/42 proposals, voter, unlock stake, Finished",1356230175,3961906,29455 -"Agora/Proposal/validator/unlocking/legal/voter unlocks stake after voting/42 proposals, voter, unlock stake, Locked",1356230175,3961906,29455 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: retract votes while voting/stake,128424052,334368,5219 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: retract votes while voting/propsoal,236724208,665425,8127 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: retract votes while voting/stake,131655298,343422,5235 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: retract votes while voting/propsoal,250196415,705367,8138 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/creator: remove creator locks when finished/stake,128424052,334368,5217 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/creator: remove creator locks when finished/propsoal,204516343,585280,8124 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: remove all locks when finished/stake,128424052,334368,5233 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: remove all locks when finished/propsoal,212950600,610184,8136 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: unlock after voting/Locked/stake,128424052,334368,5223 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: unlock after voting/Locked/propsoal,205832495,589164,8131 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: unlock after voting/Finished/stake,128424052,334368,5223 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter: unlock after voting/Finished/propsoal,205832495,589164,8131 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: remove vote locks when locked/stake,131655298,343422,5239 +Agora/Proposal/validator/unlocking/legal/with 1 proposals/voter/creator: remove vote locks when locked/propsoal,219836278,630498,8142 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: retract votes while voting/stake,279213296,711004,7303 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: retract votes while voting/propsoal,379365456,1078089,10187 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: retract votes while voting/stake,295369526,756274,7380 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: retract votes while voting/propsoal,444893991,1269343,10239 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/creator: remove creator locks when finished/stake,279213296,711004,7293 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/creator: remove creator locks when finished/propsoal,312597155,903136,10180 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: remove all locks when finished/stake,279213296,711004,7374 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: remove all locks when finished/propsoal,350986136,1014888,10233 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: unlock after voting/Locked/stake,279213296,711004,7324 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: unlock after voting/Locked/propsoal,318066415,918212,10208 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: unlock after voting/Finished/stake,279213296,711004,7324 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter: unlock after voting/Finished/propsoal,318066415,918212,10208 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: remove vote locks when locked/stake,295369526,756274,7400 +Agora/Proposal/validator/unlocking/legal/with 5 proposals/voter/creator: remove vote locks when locked/propsoal,384126526,1110858,10259 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: retract votes while voting/stake,467699851,1181799,9909 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: retract votes while voting/propsoal,557667016,1593919,12763 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: retract votes while voting/stake,500012311,1272339,10060 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: retract votes while voting/propsoal,688265961,1974313,12864 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/creator: remove creator locks when finished/stake,467699851,1181799,9888 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/creator: remove creator locks when finished/propsoal,447698170,1300456,12750 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: remove all locks when finished/stake,467699851,1181799,10049 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: remove all locks when finished/propsoal,523530556,1520768,12853 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: unlock after voting/Locked/stake,467699851,1181799,9949 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: unlock after voting/Locked/propsoal,458358815,1329522,12803 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: unlock after voting/Finished/stake,467699851,1181799,9949 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter: unlock after voting/Finished/propsoal,458358815,1329522,12803 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: remove vote locks when locked/stake,500012311,1272339,10100 +Agora/Proposal/validator/unlocking/legal/with 10 proposals/voter/creator: remove vote locks when locked/propsoal,589489336,1711308,12904 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: retract votes while voting/stake,1674013803,4194887,26674 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: retract votes while voting/propsoal,1698797000,4895231,29317 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: retract votes while voting/stake,1809726135,4575155,27362 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: retract votes while voting/propsoal,2245846569,6486121,29776 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/creator: remove creator locks when finished/stake,1674013803,4194887,26590 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/creator: remove creator locks when finished/propsoal,1312344666,3843304,29273 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: remove all locks when finished/stake,1674013803,4194887,27301 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: remove all locks when finished/propsoal,1627814844,4758400,29715 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: unlock after voting/Locked/stake,1674013803,4194887,26843 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: unlock after voting/Locked/propsoal,1356230175,3961906,29486 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: unlock after voting/Finished/stake,1674013803,4194887,26843 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter: unlock after voting/Finished/propsoal,1356230175,3961906,29486 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: remove vote locks when locked/stake,1809726135,4575155,27531 +Agora/Proposal/validator/unlocking/legal/with 42 proposals/voter/creator: remove vote locks when locked/propsoal,1903811320,5554188,29945 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Voter, status: Draft/stake",128424052,334368,5219 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Voter, status: Locked/stake",128424052,334368,5219 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Voter, status: Finished/stake",128424052,334368,5219 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Creator, status: Draft/stake",124053466,322518,5221 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Creator, status: Locked/stake",124053466,322518,5221 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Creator, status: Finished/stake",124053466,322518,5221 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Both, status: Draft/stake",131655298,343422,5235 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Both, status: Locked/stake",131655298,343422,5235 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Both, status: Finished/stake",131655298,343422,5235 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Irrelevant, status: Draft/stake",120822220,313464,5201 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Irrelevant, status: Locked/stake",120822220,313464,5201 +"Agora/Proposal/validator/unlocking/illegal/with 1 proposals/retract votes while not voting/role: Irrelevant, status: Finished/stake",120822220,313464,5201 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Draftretract votes: True/stake,120822220,313464,5201 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Draftretract votes: False/stake,120822220,313464,5201 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: VotingReadyretract votes: True/stake,120822220,313464,5201 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: VotingReadyretract votes: False/stake,120822220,313464,5201 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Lockedretract votes: True/stake,120822220,313464,5201 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Lockedretract votes: False/stake,120822220,313464,5201 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Finishedretract votes: True/stake,120822220,313464,5201 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/unlock an irrelevant stake/status: Finishedretract votes: False/stake,120822220,313464,5201 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/remove creator too early/status: Draft/stake,128424052,334368,5217 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/remove creator too early/status: VotingReady/stake,128424052,334368,5217 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/remove creator too early/status: Locked/stake,128424052,334368,5217 +Agora/Proposal/validator/unlocking/illegal/with 1 proposals/creator: retract votes/stake,128424052,334368,5215 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Voter, status: Draft/stake",279213296,711004,7303 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Voter, status: Locked/stake",279213296,711004,7303 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Voter, status: Finished/stake",279213296,711004,7303 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Creator, status: Draft/stake",272564030,693562,7309 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Creator, status: Locked/stake",272564030,693562,7309 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Creator, status: Finished/stake",272564030,693562,7309 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Both, status: Draft/stake",295369526,756274,7380 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Both, status: Locked/stake",295369526,756274,7380 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Both, status: Finished/stake",295369526,756274,7380 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Irrelevant, status: Draft/stake",256407800,648292,7221 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Irrelevant, status: Locked/stake",256407800,648292,7221 +"Agora/Proposal/validator/unlocking/illegal/with 5 proposals/retract votes while not voting/role: Irrelevant, status: Finished/stake",256407800,648292,7221 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Draftretract votes: True/stake,256407800,648292,7221 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Draftretract votes: False/stake,256407800,648292,7221 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: VotingReadyretract votes: True/stake,256407800,648292,7221 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: VotingReadyretract votes: False/stake,256407800,648292,7221 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Lockedretract votes: True/stake,256407800,648292,7221 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Lockedretract votes: False/stake,256407800,648292,7221 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Finishedretract votes: True/stake,256407800,648292,7221 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/unlock an irrelevant stake/status: Finishedretract votes: False/stake,256407800,648292,7221 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/remove creator too early/status: Draft/stake,279213296,711004,7293 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/remove creator too early/status: VotingReady/stake,279213296,711004,7293 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/remove creator too early/status: Locked/stake,279213296,711004,7293 +Agora/Proposal/validator/unlocking/illegal/with 5 proposals/creator: retract votes/stake,279213296,711004,7283 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Voter, status: Draft/stake",467699851,1181799,9909 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Voter, status: Locked/stake",467699851,1181799,9909 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Voter, status: Finished/stake",467699851,1181799,9909 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Creator, status: Draft/stake",458202235,1157367,9920 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Creator, status: Locked/stake",458202235,1157367,9920 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Creator, status: Finished/stake",458202235,1157367,9920 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Both, status: Draft/stake",500012311,1272339,10060 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Both, status: Locked/stake",500012311,1272339,10060 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Both, status: Finished/stake",500012311,1272339,10060 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Irrelevant, status: Draft/stake",425889775,1066827,9746 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Irrelevant, status: Locked/stake",425889775,1066827,9746 +"Agora/Proposal/validator/unlocking/illegal/with 10 proposals/retract votes while not voting/role: Irrelevant, status: Finished/stake",425889775,1066827,9746 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Draftretract votes: True/stake,425889775,1066827,9746 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Draftretract votes: False/stake,425889775,1066827,9746 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: VotingReadyretract votes: True/stake,425889775,1066827,9746 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: VotingReadyretract votes: False/stake,425889775,1066827,9746 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Lockedretract votes: True/stake,425889775,1066827,9746 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Lockedretract votes: False/stake,425889775,1066827,9746 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Finishedretract votes: True/stake,425889775,1066827,9746 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/unlock an irrelevant stake/status: Finishedretract votes: False/stake,425889775,1066827,9746 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/remove creator too early/status: Draft/stake,467699851,1181799,9888 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/remove creator too early/status: VotingReady/stake,467699851,1181799,9888 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/remove creator too early/status: Locked/stake,467699851,1181799,9888 +Agora/Proposal/validator/unlocking/illegal/with 10 proposals/creator: retract votes/stake,467699851,1181799,9868 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Voter, status: Draft/stake",1674013803,4194887,26674 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Voter, status: Locked/stake",1674013803,4194887,26674 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Voter, status: Finished/stake",1674013803,4194887,26674 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Creator, status: Draft/stake",1646286747,4125719,26736 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Creator, status: Locked/stake",1646286747,4125719,26736 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Creator, status: Finished/stake",1646286747,4125719,26736 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Both, status: Draft/stake",1809726135,4575155,27362 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Both, status: Locked/stake",1809726135,4575155,27362 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Both, status: Finished/stake",1809726135,4575155,27362 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Irrelevant, status: Draft/stake",1510574415,3745451,25961 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Irrelevant, status: Locked/stake",1510574415,3745451,25961 +"Agora/Proposal/validator/unlocking/illegal/with 42 proposals/retract votes while not voting/role: Irrelevant, status: Finished/stake",1510574415,3745451,25961 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Draftretract votes: True/stake,1510574415,3745451,25961 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Draftretract votes: False/stake,1510574415,3745451,25961 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: VotingReadyretract votes: True/stake,1510574415,3745451,25961 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: VotingReadyretract votes: False/stake,1510574415,3745451,25961 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Lockedretract votes: True/stake,1510574415,3745451,25961 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Lockedretract votes: False/stake,1510574415,3745451,25961 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Finishedretract votes: True/stake,1510574415,3745451,25961 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/unlock an irrelevant stake/status: Finishedretract votes: False/stake,1510574415,3745451,25961 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/remove creator too early/status: Draft/stake,1674013803,4194887,26590 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/remove creator too early/status: VotingReady/stake,1674013803,4194887,26590 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/remove creator too early/status: Locked/stake,1674013803,4194887,26590 +Agora/Proposal/validator/unlocking/illegal/with 42 proposals/creator: retract votes/stake,1674013803,4194887,26506 Agora/AuthorityToken/singleAuthorityTokenBurned/Correct simple,21017788,55883,806 Agora/AuthorityToken/singleAuthorityTokenBurned/Correct many inputs,33204186,88241,900 Agora/Treasury/Validator/Positive/Allows for effect changes,31556709,81546,1452