Skip to content

Commit

Permalink
Add some tally logic
Browse files Browse the repository at this point in the history
  • Loading branch information
akremstudy committed Oct 30, 2023
1 parent 008c921 commit 1678e6c
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 57 deletions.
2 changes: 1 addition & 1 deletion proto/layer/dispute/vote.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ message Vote {
uint64 id = 1;
google.protobuf.Timestamp voteStart = 2 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
google.protobuf.Timestamp voteEnd = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
string voteResult = 4;
VoteResult voteResult = 4;
}

enum VoteResult {
Expand Down
8 changes: 8 additions & 0 deletions x/dispute/keeper/dispute.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/sha256"
"encoding/binary"
"fmt"
"time"

"cosmossdk.io/math"

Expand Down Expand Up @@ -269,3 +270,10 @@ func (k Keeper) AddDisputeRound(ctx sdk.Context, dispute types.Dispute) error {
// Reducing the fee total means that feeTotal - burnAmount could be zero and the fee payers don't get anything from the feePaid or who gets what is not clear
return nil
}

// Add time to dispute end time
func (k Keeper) AddTimeToDisputeEndTime(ctx sdk.Context, dispute types.Dispute, timeToAdd time.Duration) {
dispute.DisputeEndTime = dispute.DisputeEndTime.Add(timeToAdd)
k.SetDisputeById(ctx, dispute.DisputeId, dispute)
k.SetDisputeByReporter(ctx, dispute)
}
106 changes: 106 additions & 0 deletions x/dispute/keeper/tally.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package keeper

import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/tellor-io/layer/x/dispute/types"
)

func (k Keeper) Tally(ctx sdk.Context, ids []uint64) {
for _, id := range ids {
k.TallyVote(ctx, id)
}
}

func (k Keeper) TallyVote(ctx sdk.Context, id uint64) {
dispute := k.GetDisputeById(ctx, id)
if dispute == nil {
return
}
tally := k.GetTally(ctx, id)
if tally == nil {
return
}
vote := k.GetVote(ctx, id)
if vote == nil {
return
}
// Check if vote period ended
if vote.VoteEnd.After(ctx.BlockTime()) {
return
}
tokenHolderVoteSum := tally.ForVotes.TokenHolders.Add(tally.AgainstVotes.TokenHolders)
validatorVoteSum := tally.ForVotes.Validators.Add(tally.AgainstVotes.Validators)
userVoteSum := tally.ForVotes.Users.Add(tally.AgainstVotes.Users)
teamVoteSum := tally.ForVotes.Team.Add(tally.AgainstVotes.Team)

// Prevent zero-division
if tokenHolderVoteSum.IsZero() {
tokenHolderVoteSum = sdk.NewInt(1)
}
if validatorVoteSum.IsZero() {
validatorVoteSum = sdk.NewInt(1)
}
if userVoteSum.IsZero() {
userVoteSum = sdk.NewInt(1)
}
if teamVoteSum.IsZero() {
teamVoteSum = sdk.NewInt(1)
}

// Convert to Dec for precision
tokenHolderVoteSumDec := sdk.NewDecFromInt(tokenHolderVoteSum)
validatorVoteSumDec := sdk.NewDecFromInt(validatorVoteSum)
userVoteSumDec := sdk.NewDecFromInt(userVoteSum)
teamVoteSumDec := sdk.NewDecFromInt(teamVoteSum)

// Normalize the votes for each group
forTokenHolders := sdk.NewDecFromInt(tally.ForVotes.TokenHolders).Quo(tokenHolderVoteSumDec)
forValidators := sdk.NewDecFromInt(tally.ForVotes.Validators).Quo(validatorVoteSumDec)
forUsers := sdk.NewDecFromInt(tally.ForVotes.Users).Quo(userVoteSumDec)
forTeam := sdk.NewDecFromInt(tally.ForVotes.Team).Quo(teamVoteSumDec)

againstTokenHolders := sdk.NewDecFromInt(tally.AgainstVotes.TokenHolders).Quo(tokenHolderVoteSumDec)
againstValidators := sdk.NewDecFromInt(tally.AgainstVotes.Validators).Quo(validatorVoteSumDec)
againstUsers := sdk.NewDecFromInt(tally.AgainstVotes.Users).Quo(userVoteSumDec)
againstTeam := sdk.NewDecFromInt(tally.AgainstVotes.Team).Quo(teamVoteSumDec)

// Sum the normalized votes and divide by number of groups to scale between 0 and 1
numGroups := sdk.NewDec(4)
scaledSupport := (forTokenHolders.Add(forValidators).Add(forUsers).Add(forTeam)).Quo(numGroups)
scaledAgainst := (againstTokenHolders.Add(againstValidators).Add(againstUsers).Add(againstTeam)).Quo(numGroups)

if scaledSupport.GT(scaledAgainst) {
// Check if support is greater than 50%
if scaledSupport.GT(sdk.NewDecWithPrec(5, 1)) {
k.SetDisputeStatus(ctx, id, types.Resolved)
k.SetVoteResult(ctx, id, types.VoteResult_PASSED)
} else {
k.SetDisputeStatus(ctx, id, types.Unresolved)
k.SetVoteResult(ctx, id, types.VoteResult_UNRESOLVEDPASSED)
// Set end time to an extra day after vote end to allow for more rounds
k.AddTimeToDisputeEndTime(ctx, *dispute, 86400)
}
}

if scaledAgainst.GT(scaledSupport) {
// Check if against is greater than 50%
if scaledAgainst.GT(sdk.NewDecWithPrec(5, 1)) {
k.SetDisputeStatus(ctx, id, types.Resolved)
k.SetVoteResult(ctx, id, types.VoteResult_FAILED)
} else {
k.SetDisputeStatus(ctx, id, types.Unresolved)
k.SetVoteResult(ctx, id, types.VoteResult_UNRESOLVEDFAILED)
// Set end time to an extra day after vote end to allow for more rounds
k.AddTimeToDisputeEndTime(ctx, *dispute, 86400)
}
}
}

// Set vote results
func (k Keeper) SetVoteResult(ctx sdk.Context, id uint64, result types.VoteResult) {
vote := k.GetVote(ctx, id)
vote.VoteResult = result
vote.VoteEnd = ctx.BlockTime()
store := k.voteStore(ctx)
store.Set(types.DisputeIdBytes(id), k.cdc.MustMarshal(vote))
}
17 changes: 13 additions & 4 deletions x/dispute/keeper/vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ func (k Keeper) GetTally(ctx sdk.Context, id uint64) *types.Tally {
func (k Keeper) SetTally(ctx sdk.Context, id uint64, voteFor bool, voter string) error {
tallies := k.GetTally(ctx, id)
if voteFor {
tallies.ForVotes.Validators.Add(k.GetValidatorTokenBalance(ctx, voter))
tallies.ForVotes.Validators.Add(k.GetValidatorPower(ctx, voter))
tallies.ForVotes.TokenHolders.Add(k.GetAccountBalance(ctx, voter))
tallies.ForVotes.Users.Add(k.GetUserTips(ctx, voter))
tallies.ForVotes.Team.Add(k.IsTeamAddress(ctx, voter))
} else {
tallies.AgainstVotes.Validators.Add(k.GetValidatorTokenBalance(ctx, voter))
tallies.AgainstVotes.Validators.Add(k.GetValidatorPower(ctx, voter))
tallies.AgainstVotes.TokenHolders.Add(k.GetAccountBalance(ctx, voter))
tallies.AgainstVotes.Users.Add(k.GetUserTips(ctx, voter))
tallies.AgainstVotes.Team.Add(k.IsTeamAddress(ctx, voter))
Expand All @@ -58,8 +58,17 @@ func (k Keeper) SetTally(ctx sdk.Context, id uint64, voteFor bool, voter string)
return nil
}

func (k Keeper) GetValidatorTokenBalance(ctx sdk.Context, voter string) math.Int {
return sdk.ZeroInt()
func (k Keeper) GetValidatorPower(ctx sdk.Context, voter string) math.Int {
addr, err := sdk.AccAddressFromBech32(voter)
if err != nil {
panic(err)
}
validator, found := k.stakingKeeper.GetValidator(ctx, sdk.ValAddress(addr))
if !found {
return sdk.ZeroInt()
}
power := validator.GetConsensusPower(validator.GetBondedTokens())
return sdk.NewInt(power)
}

func (k Keeper) GetAccountBalance(ctx sdk.Context, voter string) math.Int {
Expand Down
1 change: 1 addition & 0 deletions x/dispute/keeper/vote_start.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func (k Keeper) StartVoting(ctx sdk.Context, ids []uint64) {
if dispute.SlashAmount.GTE(dispute.FeeTotal) && dispute.DisputeStatus == types.Prevote {
// set dispute status to voting
k.SetDisputeStatus(ctx, disputeId, types.Voting)
k.AddTimeToDisputeEndTime(ctx, *dispute, 86400*2)
k.SetStartVote(ctx, disputeId)
}
}
Expand Down
2 changes: 2 additions & 0 deletions x/dispute/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ func (AppModule) ConsensusVersion() uint64 { return 1 }
func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) {
ids := am.keeper.CheckPrevoteDisputesForExpiration(ctx)
am.keeper.StartVoting(ctx, ids)
am.keeper.Tally(ctx, ids)
// am.keeper.ExecuteVotes(ctx, ids)
}

// EndBlock contains the logic that is automatically triggered at the end of each block
Expand Down
89 changes: 37 additions & 52 deletions x/dispute/types/vote.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1678e6c

Please sign in to comment.