Merge branch 'main' into connor/mutate-governor

This commit is contained in:
方泓睿 2022-05-24 12:38:46 +08:00 committed by GitHub
commit 4bffc1005d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 1225 additions and 41 deletions

View file

@ -73,12 +73,14 @@ import Sample.Shared (
gstUTXORef,
minAda,
proposalPolicySymbol,
proposalTimingConfig,
proposalValidatorAddress,
signer,
signer2,
stake,
stakeAddress,
stakeAssetClass,
tmpProposalStartingTime,
)
import Test.Util (datumPair, toDatumHash)
@ -234,6 +236,8 @@ createProposal =
, cosigners = [signer]
, thresholds = defaultProposalThresholds
, votes = emptyVotesFor effects
, timingConfig = proposalTimingConfig
, startingTime = tmpProposalStartingTime
}
)
proposalOutput :: TxOut
@ -408,6 +412,8 @@ mintGATs =
, cosigners = [signer, signer2]
, thresholds = defaultProposalThresholds
, votes = proposalVotes
, timingConfig = proposalTimingConfig
, startingTime = tmpProposalStartingTime
}
proposalInputDatum :: Datum
proposalInputDatum = Datum $ toBuiltinData proposalInputDatum'

View file

@ -11,6 +11,8 @@ module Sample.Proposal (
cosignProposal,
proposalRef,
stakeRef,
voteOnProposal,
VotingParameters (..),
) where
--------------------------------------------------------------------------------
@ -21,6 +23,7 @@ import Plutus.V1.Ledger.Api (
Address (Address),
Credential (ScriptCredential),
Datum (Datum),
POSIXTimeRange,
PubKeyHash,
ScriptContext (..),
ScriptPurpose (..),
@ -43,14 +46,16 @@ import Agora.Proposal (
ProposalDatum (..),
ProposalId (..),
ProposalStatus (..),
ProposalVotes (..),
ResultTag (..),
emptyVotesFor,
)
import Agora.Stake (Stake (..), StakeDatum (StakeDatum))
import Agora.Proposal.Time (ProposalTimingConfig (..))
import Agora.Stake (ProposalLock (ProposalLock), Stake (..), StakeDatum (..))
import Plutarch.SafeMoney (Tagged (Tagged), untag)
import PlutusTx.AssocMap qualified as AssocMap
import Sample.Shared
import Test.Util (datumPair, toDatumHash)
import Test.Util (closedBoundedInterval, datumPair, toDatumHash, updateMap)
--------------------------------------------------------------------------------
@ -74,6 +79,8 @@ proposalCreation =
, cosigners = [signer]
, thresholds = defaultProposalThresholds
, votes = emptyVotesFor effects
, timingConfig = proposalTimingConfig
, startingTime = tmpProposalStartingTime
}
)
@ -167,11 +174,18 @@ cosignProposal newSigners =
, cosigners = [signer]
, thresholds = defaultProposalThresholds
, votes = emptyVotesFor effects
, timingConfig = proposalTimingConfig
, startingTime = tmpProposalStartingTime
}
stakeDatum :: StakeDatum
stakeDatum = StakeDatum (Tagged 50_000_000) signer2 []
proposalAfter :: ProposalDatum
proposalAfter = proposalBefore {cosigners = newSigners <> proposalBefore.cosigners}
validTimeRange :: POSIXTimeRange
validTimeRange =
closedBoundedInterval
10
(proposalTimingConfig.draftTime - 10)
in TxInfo
{ txInfoInputs =
[ TxInInfo
@ -223,7 +237,7 @@ cosignProposal newSigners =
, txInfoMint = st
, txInfoDCert = []
, txInfoWdrl = []
, txInfoValidRange = Interval.always
, txInfoValidRange = validTimeRange
, txInfoSignatories = newSigners
, txInfoData =
[ datumPair . Datum $ toBuiltinData proposalBefore
@ -232,3 +246,157 @@ cosignProposal newSigners =
]
, txInfoId = "0b2086cbf8b6900f8cb65e012de4516cb66b5cb08a9aaba12a8b88be"
}
--------------------------------------------------------------------------------
-- | Parameters for creating a voting transaction.
data VotingParameters = VotingParameters
{ voteFor :: ResultTag
-- ^ The outcome the transaction is voting for.
, voteCount :: Integer
-- ^ The count of votes.
}
-- | Create a valid transaction that votes on a propsal, given the parameters.
voteOnProposal :: VotingParameters -> TxInfo
voteOnProposal params =
let pst = Value.singleton proposalPolicySymbol "" 1
sst = Value.assetClassValue stakeAssetClass 1
---
stakeOwner = signer
---
effects =
AssocMap.fromList
[ (ResultTag 0, AssocMap.empty)
, (ResultTag 1, AssocMap.empty)
]
---
initialVotes :: AssocMap.Map ResultTag Integer
initialVotes =
AssocMap.fromList
[ (ResultTag 0, 42)
, (ResultTag 1, 4242)
]
---
proposalInputDatum' :: ProposalDatum
proposalInputDatum' =
ProposalDatum
{ proposalId = ProposalId 42
, effects = effects
, status = VotingReady
, cosigners = [stakeOwner]
, thresholds = defaultProposalThresholds
, votes = ProposalVotes initialVotes
, timingConfig = proposalTimingConfig
, startingTime = tmpProposalStartingTime
}
proposalInputDatum :: Datum
proposalInputDatum = Datum $ toBuiltinData proposalInputDatum'
proposalInput :: TxOut
proposalInput =
TxOut
{ txOutAddress = proposalValidatorAddress
, txOutValue = pst
, txOutDatumHash = Just $ toDatumHash proposalInputDatum
}
---
existingLocks :: [ProposalLock]
existingLocks =
[ ProposalLock (ResultTag 0) (ProposalId 0)
, ProposalLock (ResultTag 2) (ProposalId 1)
]
---
stakeInputDatum' :: StakeDatum
stakeInputDatum' =
StakeDatum
{ stakedAmount = Tagged params.voteCount
, owner = stakeOwner
, lockedBy = existingLocks
}
stakeInputDatum :: Datum
stakeInputDatum = Datum $ toBuiltinData stakeInputDatum'
stakeInput :: TxOut
stakeInput =
TxOut
{ txOutAddress = stakeAddress
, txOutValue =
mconcat
[ sst
, Value.assetClassValue (untag stake.gtClassRef) params.voteCount
, minAda
]
, txOutDatumHash = Just $ toDatumHash stakeInputDatum
}
---
updatedVotes :: AssocMap.Map ResultTag Integer
updatedVotes = updateMap (Just . (+ params.voteCount)) params.voteFor initialVotes
---
proposalOutputDatum' :: ProposalDatum
proposalOutputDatum' =
proposalInputDatum'
{ votes = ProposalVotes updatedVotes
}
proposalOutputDatum :: Datum
proposalOutputDatum = Datum $ toBuiltinData proposalOutputDatum'
proposalOutput :: TxOut
proposalOutput =
proposalInput
{ txOutDatumHash = Just $ toDatumHash proposalOutputDatum
}
---
-- Off-chain code should do exactly like this: prepend new lock to the list.
updatedLocks :: [ProposalLock]
updatedLocks = ProposalLock params.voteFor proposalInputDatum'.proposalId : existingLocks
---
stakeOutputDatum' :: StakeDatum
stakeOutputDatum' =
stakeInputDatum'
{ lockedBy = updatedLocks
}
stakeOutputDatum :: Datum
stakeOutputDatum = Datum $ toBuiltinData stakeOutputDatum'
stakeOutput :: TxOut
stakeOutput =
stakeInput
{ txOutDatumHash = Just $ toDatumHash stakeOutputDatum
}
---
validTimeRange =
closedBoundedInterval (proposalTimingConfig.draftTime + 1) (proposalTimingConfig.votingTime - 1)
in TxInfo
{ txInfoInputs =
[ TxInInfo proposalRef proposalInput
, TxInInfo stakeRef stakeInput
]
, txInfoOutputs = [proposalOutput, stakeOutput]
, txInfoFee = Value.singleton "" "" 2
, txInfoMint = mempty
, txInfoDCert = []
, txInfoWdrl = []
, txInfoValidRange = validTimeRange
, txInfoSignatories = [stakeOwner]
, txInfoData = datumPair <$> [proposalInputDatum, proposalOutputDatum, stakeInputDatum, stakeOutputDatum]
, txInfoId = "827598fb2d69a896bbd9e645bb14c307df907f422b39eecbe4d6329bc30b428c"
}

View file

@ -36,6 +36,8 @@ module Sample.Shared (
proposalPolicySymbol,
proposalValidatorHash,
proposalValidatorAddress,
proposalTimingConfig,
tmpProposalStartingTime,
-- ** Authority
authorityToken,
@ -74,6 +76,10 @@ import Agora.Proposal (
Proposal (..),
ProposalThresholds (..),
)
import Agora.Proposal.Time (
ProposalStartingTime (..),
ProposalTimingConfig (..),
)
import Agora.Stake (Stake (..))
import Agora.Treasury (treasuryValidator)
import Agora.Utils (validatorHashToTokenName)
@ -184,6 +190,22 @@ authorityToken = authorityTokenFromGovernor governor
authorityTokenSymbol :: CurrencySymbol
authorityTokenSymbol = authorityTokenSymbolFromGovernor governor
proposalTimingConfig :: ProposalTimingConfig
proposalTimingConfig =
ProposalTimingConfig
{ draftTime = 50
, votingTime = 1000
, lockingTime = 2000
, executingTime = 3000
}
{- | Hard coded starting time of every propoal.
This will be calculated by the governor in the future.
FIXME: Remove this.
-}
tmpProposalStartingTime :: ProposalStartingTime
tmpProposalStartingTime = ProposalStartingTime 0
------------------------------------------------------------------
treasuryOut :: TxOut