add pwinner to find the winning outcome

This commit is contained in:
fanghr 2022-05-26 22:28:53 +08:00 committed by Hongrui Fang
parent 8231d1b079
commit b01b48497c
No known key found for this signature in database
GPG key ID: 1C4711FFF64C0254
2 changed files with 37 additions and 22 deletions

View file

@ -53,6 +53,7 @@ import Agora.Proposal (
ProposalStatus (Draft, Locked),
pemptyVotesFor,
proposalDatumValid,
pwinner,
)
import Agora.Proposal.Scripts (
proposalPolicy,
@ -77,7 +78,6 @@ import Agora.Utils (
mustFindDatum',
pfindTxInByTxOutRef,
pisDJust,
pisJust,
pisUTXOSpent,
psymbolValueOf,
ptryFindDatum,
@ -605,27 +605,7 @@ governorValidator gov =
-- TODO: anything else to check here?
-- Find the highest votes and the corresponding tag.
let highestVoteFolder =
phoistAcyclic $
plam
( \pair last' ->
pif
(pisJust # last')
( unTermCont $ do
PJust last <- tcmatch last'
let lastHighestVote = pfromData $ psndBuiltin # last
thisVote = pfromData $ psndBuiltin # pair
pure $ pif (lastHighestVote #< thisVote) (pcon $ PJust pair) last'
)
(pcon $ PJust pair)
)
votesList = pto $ pto $ pfromData proposalInputDatumF.votes
maybeWinner =
pfoldr # highestVoteFolder # pcon PNothing # votesList
winner <- tclet $ mustBePJust # "No winning outcome" # maybeWinner
winner <- tclet $ mustBePJust # "No winning outcome" #$ pwinner # proposalInputDatumF.votes
PDiscrete minimumVotes' <- pmatchC $ pfromData $ pfield @"execute" # proposalInputDatumF.thresholds
let highestVote = pfromData $ psndBuiltin # winner

View file

@ -31,6 +31,7 @@ module Agora.Proposal (
-- * Plutarch helpers
proposalDatumValid,
pemptyVotesFor,
pwinner,
) where
import GHC.Generics qualified as GHC
@ -448,3 +449,37 @@ proposalDatumValid proposal =
, ptraceIfFalse "Proposal has fewer cosigners than the limit" $ plength # (pfromData datum.cosigners) #<= pconstant proposal.maximumCosigners
, ptraceIfFalse "Proposal votes and effects are compatible with each other" $ pkeysEqual # datum.effects # pto (pfromData datum.votes)
]
{- | Find the winning outcome (and the corresponding vote count) given the votes.
FIXME: What if two or more outcomes have the exact same vote count?
-}
pwinner ::
Term
s
( PProposalVotes
:--> PMaybe (PBuiltinPair (PAsData PResultTag) (PAsData PInteger))
)
pwinner = phoistAcyclic $
plam $ \votes ->
let l :: Term _ (PBuiltinList _)
l = pto $ pto votes
f ::
Term
_
( PBuiltinPair (PAsData PResultTag) (PAsData PInteger)
:--> PMaybe (PBuiltinPair (PAsData PResultTag) (PAsData PInteger))
:--> PMaybe (PBuiltinPair (PAsData PResultTag) (PAsData PInteger))
)
f = phoistAcyclic $
plam $ \this maybeLast -> pmatch maybeLast $ \case
PNothing -> pcon $ PJust this
PJust last ->
let lastVotes = pfromData $ psndBuiltin # last
thisVotes = pfromData $ psndBuiltin # this
in pif
(lastVotes #< thisVotes)
(pcon $ PJust this)
maybeLast
in pfoldr # f # pcon PNothing # l