Skip to content

Commit

Permalink
feat(x/tally): executor payout in uniform case
Browse files Browse the repository at this point in the history
  • Loading branch information
hacheigriega committed Jan 13, 2025
1 parent a269136 commit efd1cb0
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 17 deletions.
20 changes: 15 additions & 5 deletions x/tally/keeper/endblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,22 @@ func (k Keeper) FilterAndTally(ctx sdk.Context, req types.Request, params types.
}

// Phase III: Calculate Payouts
// TODO: Calculate gas used & payouts
result.ExecGasUsed = calculateExecGasUsed(reveals)
distMsgs := types.DistributionMessages{
Messages: []types.DistributionMessage{},
RefundType: types.DistributionTypeNoConsensus,
// TODO guarantee: len(reveals) > 0
var distMsgs types.DistributionMessages
var gasUsed uint64
var err error
if req.ReplicationFactor == 1 || areGasReportsUniform(reveals) {
distMsgs.Messages, gasUsed, err = CalculateUniformPayouts(reveals, req.ExecGasLimit, req.ReplicationFactor, req.GasPrice)
} else {
distMsgs.Messages, gasUsed, err = CalculateDivergentPayouts(reveals, req.ExecGasLimit, req.ReplicationFactor, req.GasPrice)
}
if err != nil {
return filterResult, result, types.DistributionMessages{} // TODO
}
distMsgs.RefundType = types.DistributionTypeNoConsensus // TODO check
result.ExecGasUsed = gasUsed
// TODO: Requestor refund

return filterResult, result, distMsgs
}

Expand Down
11 changes: 8 additions & 3 deletions x/tally/keeper/endblock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,25 @@ func TestEndBlock(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
drID := f.commitRevealDataRequest(t, tt.memo, "Ghkvq84TmIuEmU1ClubNxBjVXi8df5QhiNQEC5T8V6w=", tt.replicationFactor, tt.numCommits, tt.numReveals, tt.timeout)
drID, stakers := f.commitRevealDataRequest(t, tt.memo, "Ghkvq84TmIuEmU1ClubNxBjVXi8df5QhiNQEC5T8V6w=", tt.replicationFactor, tt.numCommits, tt.numReveals, tt.timeout)

beforeBalance := f.bankKeeper.GetBalance(f.Context(), stakers[0].address, bondDenom)

err := f.tallyKeeper.EndBlock(f.Context())
require.NoError(t, err)

// TODO query get_staker pending_withdrawal and check diff
afterBalance := f.bankKeeper.GetBalance(f.Context(), stakers[0].address, bondDenom)
diff := afterBalance.Sub(beforeBalance)
require.Equal(t, "0aseda", diff.String())

dataResult, err := f.batchingKeeper.GetLatestDataResult(f.Context(), drID)
require.NoError(t, err)
require.Equal(t, tt.expExitCode, dataResult.ExitCode)

dataResults, err := f.batchingKeeper.GetDataResults(f.Context(), false)
require.NoError(t, err)
require.Contains(t, dataResults, *dataResult)

// TODO: Check before and after balances
})
}
}
Expand Down
7 changes: 4 additions & 3 deletions x/tally/keeper/integration_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ const (

// commitRevealDataRequest simulates stakers committing and revealing
// for a data request. It returns the data request ID.
func (f *fixture) commitRevealDataRequest(t *testing.T, requestMemo, reveal string, replicationFactor, numCommits, numReveals int, timeout bool) string {
func (f *fixture) commitRevealDataRequest(t *testing.T, requestMemo, reveal string, replicationFactor, numCommits, numReveals int, timeout bool) (string, []staker) {
stakers := f.addStakers(t, 5)
f.initAccountWithCoins(t, f.deployer, sdk.NewCoins(sdk.NewCoin(bondDenom, math.NewIntFromUint64(1e18))))

// Upload data request and tally oracle programs.
execProgram := wasmstoragetypes.NewOracleProgram(testdata.SampleTallyWasm(), f.Context().BlockTime(), f.Context().BlockHeight(), 1000)
Expand All @@ -46,7 +47,7 @@ func (f *fixture) commitRevealDataRequest(t *testing.T, requestMemo, reveal stri
resJSON, err := f.contractKeeper.Execute(
f.Context(),
f.coreContractAddr,
stakers[0].address,
f.deployer,
postDataRequestMsg(execProgram.Hash, tallyProgram.Hash, requestMemo, replicationFactor),
sdk.NewCoins(sdk.NewCoin(bondDenom, math.NewIntFromUint64(3000000000000100))),
)
Expand Down Expand Up @@ -103,7 +104,7 @@ func (f *fixture) commitRevealDataRequest(t *testing.T, requestMemo, reveal stri
}
}

return res.DrID
return res.DrID, stakers
}

type staker struct {
Expand Down
50 changes: 44 additions & 6 deletions x/tally/keeper/payout.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper

import (
"fmt"
"sort"

"cosmossdk.io/math"
Expand Down Expand Up @@ -50,11 +51,48 @@ func (k Keeper) CalculateCommitterPayouts(ctx sdk.Context, req types.Request) (t
return result, nil
}

// TODO: This will become more complex when we introduce incentives.
func calculateExecGasUsed(reveals []types.RevealBody) uint64 {
var execGasUsed uint64
for _, reveal := range reveals {
execGasUsed += reveal.GasUsed
// CalculateUniformPayouts returns payouts for the executors of the given reveals
// and the total gas used for the execution under the uniform reporting scenario.
func CalculateUniformPayouts(reveals []types.RevealBody, execGasLimit uint64, replicationFactor uint16, gasPrice string) ([]types.DistributionMessage, uint64, error) {
gasUsed := max(reveals[0].GasUsed, execGasLimit/uint64(replicationFactor))
gasPriceInt, ok := math.NewIntFromString(gasPrice)
if !ok {
return nil, 0, fmt.Errorf("invalid gas price: %s", gasPrice) // TODO error
}
return execGasUsed
payout := gasPriceInt.Mul(math.NewIntFromUint64(gasUsed))

distMsgs := make([]types.DistributionMessage, len(reveals))
for i, reveal := range reveals {
distMsgs[i] = types.DistributionMessage{
Kind: types.DistributionKind{
ExecutorReward: &types.DistributionExecutorReward{
Identity: reveal.ID,
Amount: payout,
},
},
Type: types.DistributionTypeTimedOut, // TODO check
}
}
return distMsgs, gasUsed, nil
}

// CalculateDivergentPayouts returns payouts for the executors of the given reveals
// and the total gas used for the execution under the divergent reporting scenario.
func CalculateDivergentPayouts(reveals []types.RevealBody, execGasLimit uint64, replicationFactor uint16, gasPrice string) ([]types.DistributionMessage, uint64, error) {
return nil, 0, nil
}

// areGasReportsUniform returns true if the gas reports of the given reveals are
// uniform.
func areGasReportsUniform(reveals []types.RevealBody) bool {
if len(reveals) == 0 {
return true
}
firstGas := reveals[0].GasUsed
for i := 1; i < len(reveals); i++ {
if reveals[i].GasUsed != firstGas {
return false
}
}
return true
}

0 comments on commit efd1cb0

Please sign in to comment.