Skip to content

Commit

Permalink
WIP: data provider payout
Browse files Browse the repository at this point in the history
  • Loading branch information
hacheigriega committed Jan 14, 2025
1 parent 9c23dc0 commit 2cb0c36
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 23 deletions.
21 changes: 16 additions & 5 deletions x/tally/keeper/endblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func (k Keeper) ProcessTallies(ctx sdk.Context, coreContract sdk.AccAddress) err
if !ok {
return fmt.Errorf("invalid gas price: %s", req.GasPrice) // TODO improve error handling
}
// TODO also make sure gas price is not 0

_, tallyResults[i], distMsgs = k.FilterAndTally(ctx, req, params, gasPriceInt)
dataResults[i].Result = tallyResults[i].Result
Expand Down Expand Up @@ -240,14 +241,24 @@ func (k Keeper) FilterAndTally(ctx sdk.Context, req types.Request, params types.
// Phase III: Calculate Payouts
var distMsgs types.DistributionMessages
if filterErr == nil || errors.Is(filterErr, types.ErrConsensusInError) {
var gasUsed uint64
if req.ReplicationFactor == 1 || areGasReportsUniform(reveals) {
distMsgs.Messages, gasUsed = CalculateUniformPayouts(keys, reveals[0].GasUsed, req.ExecGasLimit, req.ReplicationFactor, gasPrice)
dataProviderDistMsgs, dataProviderGasUsed, err := k.CalculateDataProviderPayouts(ctx, result.ProxyPubKeys, gasPrice)

Check failure on line 244 in x/tally/keeper/endblock.go

View workflow job for this annotation

GitHub Actions / linux-arm64

dataProviderDistMsgs declared and not used

Check failure on line 244 in x/tally/keeper/endblock.go

View workflow job for this annotation

GitHub Actions / linux-amd64

dataProviderDistMsgs declared and not used

Check failure on line 244 in x/tally/keeper/endblock.go

View workflow job for this annotation

GitHub Actions / darwin-amd64

dataProviderDistMsgs declared and not used

Check failure on line 244 in x/tally/keeper/endblock.go

View workflow job for this annotation

GitHub Actions / darwin-arm64

dataProviderDistMsgs declared and not used

Check failure on line 244 in x/tally/keeper/endblock.go

View workflow job for this annotation

GitHub Actions / golangci

dataProviderDistMsgs declared and not used (typecheck)

Check failure on line 244 in x/tally/keeper/endblock.go

View workflow job for this annotation

GitHub Actions / golangci

dataProviderDistMsgs declared and not used) (typecheck)

Check failure on line 244 in x/tally/keeper/endblock.go

View workflow job for this annotation

GitHub Actions / golangci

dataProviderDistMsgs declared and not used) (typecheck)

Check failure on line 244 in x/tally/keeper/endblock.go

View workflow job for this annotation

GitHub Actions / unit-tests

dataProviderDistMsgs declared and not used
if err != nil {
// TODO error handling
}

gasReports := make([]uint64, len(reveals))
for i, reveal := range reveals {
gasReports[i] = reveal.GasUsed - dataProviderGasUsed
}

var execGasUsed uint64
if req.ReplicationFactor == 1 || areGasReportsUniform(gasReports) {
distMsgs.Messages, execGasUsed = CalculateUniformPayouts(keys, gasReports[0], req.ExecGasLimit, req.ReplicationFactor, gasPrice)
} else {
distMsgs.Messages, gasUsed = CalculateDivergentPayouts(keys, reveals, req.ExecGasLimit, req.ReplicationFactor, gasPrice)
distMsgs.Messages, execGasUsed = CalculateDivergentPayouts(keys, gasReports, req.ExecGasLimit, req.ReplicationFactor, gasPrice)
}
distMsgs.RefundType = types.DistributionTypeExecutorReward // TODO double check
result.ExecGasUsed = gasUsed
result.ExecGasUsed = execGasUsed
}
// TODO: else pay committers?

Expand Down
4 changes: 3 additions & 1 deletion x/tally/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
type Keeper struct {
wasmStorageKeeper types.WasmStorageKeeper
batchingKeeper types.BatchingKeeper
dataProxyKeeper types.DataProxyKeeper
wasmKeeper wasmtypes.ContractOpsKeeper
wasmViewKeeper wasmtypes.ViewKeeper
authority string
Expand All @@ -26,12 +27,13 @@ type Keeper struct {
params collections.Item[types.Params]
}

func NewKeeper(cdc codec.BinaryCodec, storeService storetypes.KVStoreService, wsk types.WasmStorageKeeper, bk types.BatchingKeeper, wk wasmtypes.ContractOpsKeeper, wvk wasmtypes.ViewKeeper, authority string) Keeper {
func NewKeeper(cdc codec.BinaryCodec, storeService storetypes.KVStoreService, wsk types.WasmStorageKeeper, bk types.BatchingKeeper, dpk types.DataProxyKeeper, wk wasmtypes.ContractOpsKeeper, wvk wasmtypes.ViewKeeper, authority string) Keeper {
sb := collections.NewSchemaBuilder(storeService)

k := Keeper{
wasmStorageKeeper: wsk,
batchingKeeper: bk,
dataProxyKeeper: dpk,
wasmKeeper: wk,
wasmViewKeeper: wvk,
params: collections.NewItem(sb, types.ParamsPrefix, "params", codec.CollValue[types.Params](cdc)),
Expand Down
53 changes: 36 additions & 17 deletions x/tally/keeper/payout.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper

import (
"encoding/hex"
"sort"

"cosmossdk.io/math"
Expand All @@ -10,8 +11,27 @@ import (
"github.com/sedaprotocol/seda-chain/x/tally/types"
)

// CalculateCommitterPayouts constructs distribution messages that
// pay the fixed gas cost for each commiter of a given data request.
// CalculateDataProviderPayouts returns payouts for the data providers and
// returns the the gas used by the data providers per executor.
func (k Keeper) CalculateDataProviderPayouts(ctx sdk.Context, proxyPubKeys []string, gasPrice math.Int) (types.DistributionMessages, uint64, error) {
gasUsed := math.NewInt(0)
for _, pubKey := range proxyPubKeys {
pubKeyBytes, err := hex.DecodeString(pubKey)
if err != nil {
return types.DistributionMessages{}, 0, err
}
proxyConfig, err := k.dataProxyKeeper.GetDataProxyConfig(ctx, pubKeyBytes)
if err != nil {
return types.DistributionMessages{}, 0, err
}
gasUsed = gasUsed.Add(proxyConfig.Fee.Amount.Quo(gasPrice))
}
// TODO distMsgs?
return types.DistributionMessages{}, gasUsed.Uint64(), nil // TODO may panic
}

// CalculateCommitterPayouts returns the fixed payouts for the committers of a
// given data request.
func (k Keeper) CalculateCommitterPayouts(ctx sdk.Context, req types.Request) (types.DistributionMessages, error) {
result := types.DistributionMessages{
Messages: []types.DistributionMessage{},
Expand Down Expand Up @@ -51,10 +71,10 @@ func (k Keeper) CalculateCommitterPayouts(ctx sdk.Context, req types.Request) (t
}

// CalculateUniformPayouts calculates payouts for the executors when their gas
// reports are uniformly at "gasUsed". It also returns the total execution gas
// reports are uniformly at "gasReport". It also returns the total execution gas
// consumption.
func CalculateUniformPayouts(executors []string, gasUsed, execGasLimit uint64, replicationFactor uint16, gasPrice math.Int) ([]types.DistributionMessage, uint64) {
adjGasUsed := max(gasUsed, execGasLimit/uint64(replicationFactor))
func CalculateUniformPayouts(executors []string, gasReport, execGasLimit uint64, replicationFactor uint16, gasPrice math.Int) ([]types.DistributionMessage, uint64) {
adjGasUsed := max(gasReport, execGasLimit/uint64(replicationFactor))
payout := gasPrice.Mul(math.NewIntFromUint64(adjGasUsed))

distMsgs := make([]types.DistributionMessage, len(executors))
Expand All @@ -72,16 +92,15 @@ func CalculateUniformPayouts(executors []string, gasUsed, execGasLimit uint64, r
return distMsgs, adjGasUsed * uint64(replicationFactor)
}

// CalculateDivergentPayouts calculates payouts for the executors of the given
// reveals when their gas reports are divergent. It also returns the total
// execution gas consumption.
// CalculateDivergentPayouts calculates payouts for the executors given their
// divergent gas reports. It also returns the total execution gas consumption.
// It assumes that the i-th executor is the one who revealed the i-th reveal.
func CalculateDivergentPayouts(executors []string, reveals []types.RevealBody, execGasLimit uint64, replicationFactor uint16, gasPrice math.Int) ([]types.DistributionMessage, uint64) {
adjGasUsed := make([]uint64, len(reveals))
func CalculateDivergentPayouts(executors []string, gasReports []uint64, execGasLimit uint64, replicationFactor uint16, gasPrice math.Int) ([]types.DistributionMessage, uint64) {
adjGasUsed := make([]uint64, len(gasReports))
var lowestGasUsed uint64
var lowestReporterIndex int
for i, reveal := range reveals {
adjGasUsed[i] = min(reveal.GasUsed, execGasLimit/uint64(replicationFactor))
for i, gasReport := range gasReports {
adjGasUsed[i] = min(gasReport, execGasLimit/uint64(replicationFactor))
if i == 0 || adjGasUsed[i] < lowestGasUsed {
lowestReporterIndex = i
lowestGasUsed = adjGasUsed[i]
Expand Down Expand Up @@ -121,13 +140,13 @@ func median(arr []uint64) uint64 {

// areGasReportsUniform returns true if the gas reports of the given reveals are
// uniform.
func areGasReportsUniform(reveals []types.RevealBody) bool {
if len(reveals) == 0 {
func areGasReportsUniform(reports []uint64) bool {
if len(reports) == 0 {
return true
}
firstGas := reveals[0].GasUsed
for i := 1; i < len(reveals); i++ {
if reveals[i].GasUsed != firstGas {
firstGas := reports[0]
for i := 1; i < len(reports); i++ {
if reports[i] != firstGas {
return false
}
}
Expand Down
5 changes: 5 additions & 0 deletions x/tally/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import (
"context"

batchingtypes "github.com/sedaprotocol/seda-chain/x/batching/types"
dataproxytypes "github.com/sedaprotocol/seda-chain/x/data-proxy/types"
)

type BatchingKeeper interface {
SetDataResultForBatching(ctx context.Context, result batchingtypes.DataResult) error
}

type DataProxyKeeper interface {
GetDataProxyConfig(ctx context.Context, pubKey []byte) (result dataproxytypes.ProxyConfig, err error)
}

0 comments on commit 2cb0c36

Please sign in to comment.