Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tokenomics suite #2320

Merged
merged 7 commits into from May 6, 2023
Expand Up @@ -135,7 +135,7 @@ func TestGetSmartContract(t *testing.T) {
{
name: "storage",
address: storagesc.ADDRESS,
restpoints: 42,
restpoints: 48,
},
{
name: "multisig",
Expand Down
8 changes: 7 additions & 1 deletion code/go/0chain.net/smartcontract/dbs/event/challenge.go
Expand Up @@ -28,6 +28,12 @@ type Challenge struct {
ExpiredN int `json:"expired_n" gorm:"-"`
}

func (edb *EventDb) GetAllChallengesByAllocationID(allocationID string) (Challenges, error) {
var chs Challenges
result := edb.Store.Get().Model(&Challenge{}).Where(&Challenge{AllocationID: allocationID}).Find(&chs)
Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved
return chs, result.Error
}

func (edb *EventDb) GetChallenge(challengeID string) (*Challenge, error) {
var ch Challenge

Expand Down Expand Up @@ -81,7 +87,7 @@ func (edb *EventDb) updateChallenges(chs []Challenge) error {
var (
challengeIdList []string
respondedList []bool
passedList []bool
passedList []bool
)

for _, ch := range chs {
Expand Down
42 changes: 42 additions & 0 deletions code/go/0chain.net/smartcontract/dbs/event/reward-delegate-test.go
Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved
@@ -0,0 +1,42 @@
package event

import "0chain.net/smartcontract/stakepool/spenum"

func (edb *EventDb) GetRewardsToDelegates(blockNumber, startBlockNumber, endBlockNumber string, rewardType int) []RewardDelegate {

if blockNumber != "" {
var rds []RewardDelegate
edb.Get().Where("block_number = ? AND reward_type = ?", blockNumber, rewardType).Find(&rds)

return rds
}

if startBlockNumber != "" && endBlockNumber != "" {
var rds []RewardDelegate
edb.Get().Where("block_number >= ? AND block_number <= ? AND reward_type = ?", startBlockNumber, endBlockNumber, rewardType).Find(&rds)

return rds
}

return nil
Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved

}

func (edb *EventDb) GetChallengeRewardsToDelegates(challengeID string) ([]RewardDelegate, []RewardDelegate) {

var blobberRewards []RewardDelegate
edb.Get().Where("challenge_id = ? AND reward_type = ?", challengeID, spenum.ChallengePassReward).Find(&blobberRewards)

var validatorRewards []RewardDelegate
edb.Get().Where("challenge_id = ? AND reward_type = ?", challengeID, spenum.ValidationReward).Find(&validatorRewards)

Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved
return blobberRewards, validatorRewards
}

func (edb *EventDb) GetAllocationCancellationRewardsToDelegates(startBlock, endBlock string) []RewardDelegate {

var rps []RewardDelegate
edb.Get().Where("block_number >= ? AND block_number <= ? AND reward_type = ?", startBlock, endBlock, spenum.CancellationChargeReward).Find(&rps)

Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved
return rps
}
41 changes: 41 additions & 0 deletions code/go/0chain.net/smartcontract/dbs/event/reward-provider-test.go
@@ -0,0 +1,41 @@
package event

import "0chain.net/smartcontract/stakepool/spenum"

func (edb *EventDb) GetRewardToProviders(blockNumber, startBlockNumber, endBlockNumber string, rewardType int) []RewardProvider {

if blockNumber != "" {
var rps []RewardProvider
edb.Get().Where("block_number = ? AND reward_type = ?", blockNumber, rewardType).Find(&rps)

return rps
}

if startBlockNumber != "" && endBlockNumber != "" {
var rps []RewardProvider
edb.Get().Where("block_number >= ? AND block_number <= ? AND reward_type = ?", startBlockNumber, endBlockNumber, rewardType).Find(&rps)
Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved

return rps
}

return nil
}

func (edb *EventDb) GetChallengeRewardsToProviders(challengeID string) ([]RewardProvider, []RewardProvider) {

var blobberRewards []RewardProvider
edb.Get().Where("challenge_id = ? AND reward_type = ?", challengeID, spenum.ChallengePassReward).Find(&blobberRewards)

var validatorRewards []RewardProvider
edb.Get().Where("challenge_id = ? AND reward_type = ?", challengeID, spenum.ValidationReward).Find(&validatorRewards)

return blobberRewards, validatorRewards
}

func (edb *EventDb) GetAllocationCancellationRewardsToProviders(startBlock, endBlock string) []RewardProvider {

var rps []RewardProvider
edb.Get().Where("block_number >= ? AND block_number <= ? AND reward_type = ?", startBlock, endBlock, spenum.CancellationChargeReward).Find(&rps)

return rps
}
Expand Up @@ -17,6 +17,7 @@ type RewardDelegate struct {
PoolID string `json:"pool_id" gorm:"index:idx_rew_del_prov,priority:2"`
ProviderID string `json:"provider_id"`
RewardType spenum.Reward `json:"reward_type"`
ChallengeID string `json:"challenge_id"`
}

func (edb *EventDb) insertDelegateReward(inserts []dbs.StakePoolReward, round int64) error {
Expand All @@ -29,6 +30,7 @@ func (edb *EventDb) insertDelegateReward(inserts []dbs.StakePoolReward, round in
PoolID: poolId,
ProviderID: sp.ID,
RewardType: sp.RewardType,
ChallengeID: sp.ChallengeID,
}
drs = append(drs, dr)
}
Expand All @@ -39,6 +41,7 @@ func (edb *EventDb) insertDelegateReward(inserts []dbs.StakePoolReward, round in
PoolID: poolId,
ProviderID: sp.ID,
RewardType: sp.RewardType,
ChallengeID: sp.ChallengeID,
}
drs = append(drs, dp)
}
Expand Down
Expand Up @@ -16,6 +16,7 @@ type RewardProvider struct {
BlockNumber int64 `json:"block_number" gorm:"index:idx_rew_block_prov,priority:1"`
ProviderId string `json:"provider_id" gorm:"index:idx_rew_block_prov,priority:2"`
RewardType spenum.Reward `json:"reward_type"`
ChallengeID string `json:"challenge_id"`
}

func (edb *EventDb) insertProviderReward(inserts []dbs.StakePoolReward, round int64) error {
Expand Down
Expand Up @@ -742,7 +742,8 @@ CREATE TABLE public.reward_delegates (
amount bigint,
block_number bigint,
pool_id text,
reward_type bigint
reward_type bigint,
challenge_id text
);


Expand Down Expand Up @@ -820,7 +821,8 @@ CREATE TABLE public.reward_providers (
amount bigint,
block_number bigint,
provider_id text,
reward_type bigint
reward_type bigint,
challenge_id text
);


Expand Down
2 changes: 2 additions & 0 deletions code/go/0chain.net/smartcontract/dbs/types.go
Expand Up @@ -46,6 +46,8 @@ type StakePoolReward struct {
DelegateRewards map[string]currency.Coin `json:"delegate_rewards"`
// penalties delegate pools
DelegatePenalties map[string]currency.Coin `json:"delegate_penalties"`
// challenge id
ChallengeID string `json:"challenge_id"`
}

type DelegatePoolId struct {
Expand Down
15 changes: 12 additions & 3 deletions code/go/0chain.net/smartcontract/stakepool/edb_stakepool.go
@@ -1,11 +1,10 @@
package stakepool

import (
"0chain.net/smartcontract/dbs"
"0chain.net/smartcontract/stakepool/spenum"
"github.com/0chain/common/core/currency"

"0chain.net/smartcontract/dbs"

cstate "0chain.net/chaincore/chain/state"
"0chain.net/smartcontract/dbs/event"
)
Expand All @@ -26,13 +25,22 @@ func (sp *StakePool) EmitStakePoolBalanceUpdate(
}
}

func NewStakePoolReward(pId string, pType spenum.Provider, rewardType spenum.Reward) *StakePoolReward {
func NewStakePoolReward(pId string, pType spenum.Provider, rewardType spenum.Reward, options ...string) *StakePoolReward {
var spu StakePoolReward
spu.ID = pId
spu.Type = pType
spu.DelegateRewards = make(map[string]currency.Coin)
spu.DelegatePenalties = make(map[string]currency.Coin)
spu.RewardType = rewardType

var challengeID string
if len(options) > 0 {
challengeID = options[0]
} else {
challengeID = ""
Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved
}
spu.ChallengeID = challengeID

return &spu
}

Expand All @@ -56,5 +64,6 @@ func stakePoolRewardToStakePoolRewardEvent(spu StakePoolReward) *dbs.StakePoolRe
Reward: spu.Reward,
DelegateRewards: spu.DelegateRewards,
RewardType: spu.RewardType,
ChallengeID: spu.ChallengeID,
}
}
9 changes: 8 additions & 1 deletion code/go/0chain.net/smartcontract/stakepool/stakepool.go
Expand Up @@ -505,11 +505,18 @@ func (sp *StakePool) DistributeRewards(
providerType spenum.Provider,
rewardType spenum.Reward,
balances cstate.StateContextI,
options ...string,
) (err error) {
if value == 0 || sp.HasBeenKilled {
return nil // nothing to move
}
var spUpdate = NewStakePoolReward(providerId, providerType, rewardType)

var spUpdate *StakePoolReward
if len(options) > 0 {
spUpdate = NewStakePoolReward(providerId, providerType, rewardType, options[0])
} else {
spUpdate = NewStakePoolReward(providerId, providerType, rewardType)
}
Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved

// if no stake pools pay all rewards to the provider
if len(sp.Pools) == 0 {
Expand Down
21 changes: 16 additions & 5 deletions code/go/0chain.net/smartcontract/storagesc/challenge.go
Expand Up @@ -75,7 +75,7 @@ func (sc *StorageSmartContract) getAllocationChallenges(allocID string,
// move tokens from challenge pool to blobber's stake pool (to unlocked)
func (sc *StorageSmartContract) blobberReward(alloc *StorageAllocation, latestCompletedChallTime common.Timestamp,
blobAlloc *BlobberAllocation, validators []string, partial float64,
balances cstate.StateContextI) error {
balances cstate.StateContextI, options ...string) error {
conf, err := sc.getConfig(balances, true)
if err != nil {
return fmt.Errorf("can't get SC configurations: %v", err.Error())
Expand Down Expand Up @@ -119,6 +119,11 @@ func (sc *StorageSmartContract) blobberReward(alloc *StorageAllocation, latestCo
return err
}

var challengeID string
if len(options) > 0 {
challengeID = options[0]
}

// part of tokens goes to related validators
var validatorsReward currency.Coin
validatorsReward, err = currency.MultFloat64(move, conf.ValidatorReward)
Expand Down Expand Up @@ -176,7 +181,7 @@ func (sc *StorageSmartContract) blobberReward(alloc *StorageAllocation, latestCo
return err
}

err = cp.moveToBlobbers(sc.ID, blobberReward, blobAlloc.BlobberID, sp, balances)
err = cp.moveToBlobbers(sc.ID, blobberReward, blobAlloc.BlobberID, sp, balances, challengeID)
if err != nil {
return fmt.Errorf("rewarding validators: %v", err)
}
Expand Down Expand Up @@ -277,7 +282,7 @@ func (ssc *StorageSmartContract) saveStakePools(validators []datastore.Key,

// move tokens from challenge pool back to write pool
func (sc *StorageSmartContract) blobberPenalty(alloc *StorageAllocation, prev common.Timestamp,
blobAlloc *BlobberAllocation, validators []string, balances cstate.StateContextI) (err error) {
blobAlloc *BlobberAllocation, validators []string, balances cstate.StateContextI, options ...string) (err error) {
var conf *Config
if conf, err = sc.getConfig(balances, true); err != nil {
return fmt.Errorf("can't get SC configurations: %v", err.Error())
Expand Down Expand Up @@ -337,8 +342,14 @@ func (sc *StorageSmartContract) blobberPenalty(alloc *StorageAllocation, prev co
return
}

var challengeID string

if len(options) > 0 {
challengeID = options[0]
Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved
}

// validators reward
err = cp.moveToValidators(sc.ID, validatorsReward, validators, vSPs, balances)
err = cp.moveToValidators(sc.ID, validatorsReward, validators, vSPs, balances, challengeID)
if err != nil {
return fmt.Errorf("rewarding validators: %v", err)
}
Expand Down Expand Up @@ -713,7 +724,7 @@ func (sc *StorageSmartContract) challengePassed(
partial = float64(cab.success) / float64(cab.threshold)
}

err = sc.blobberReward(cab.alloc, cab.latestCompletedChallTime, cab.blobAlloc, cab.validators, partial, balances)
err = sc.blobberReward(cab.alloc, cab.latestCompletedChallTime, cab.blobAlloc, cab.validators, partial, balances, cab.challenge.ID)
if err != nil {
return "", common.NewError("challenge_reward_error", err.Error())
}
Expand Down
21 changes: 18 additions & 3 deletions code/go/0chain.net/smartcontract/storagesc/challengepool.go
Expand Up @@ -95,6 +95,7 @@ func (cp *challengePool) moveToValidators(sscKey string, reward currency.Coin,
validators []datastore.Key,
vSPs []*stakePool,
balances cstate.StateContextI,
options ...string,
) error {
if len(validators) == 0 || reward == 0 {
return nil // nothing to move, or nothing to move to
Expand All @@ -109,16 +110,23 @@ func (cp *challengePool) moveToValidators(sscKey string, reward currency.Coin,
return err
}

var challengeID string
if len(options) > 0 {
challengeID = options[0]
} else {
challengeID = ""
}
Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved

for i, sp := range vSPs {
err := sp.DistributeRewards(oneReward, validators[i], spenum.Validator, spenum.ValidationReward, balances)
err := sp.DistributeRewards(oneReward, validators[i], spenum.Validator, spenum.ValidationReward, balances, challengeID)
if err != nil {
return fmt.Errorf("moving to validator %s: %v",
validators[i], err)
}
}
if bal > 0 {
for i := 0; i < int(bal); i++ {
err := vSPs[i].DistributeRewards(1, validators[i], spenum.Validator, spenum.ValidationReward, balances)
err := vSPs[i].DistributeRewards(1, validators[i], spenum.Validator, spenum.ValidationReward, balances, challengeID)
if err != nil {
return fmt.Errorf("moving to validator %s: %v",
validators[i], err)
Expand All @@ -134,6 +142,7 @@ func (cp *challengePool) moveToBlobbers(sscKey string, reward currency.Coin,
blobberId datastore.Key,
sp *stakePool,
balances cstate.StateContextI,
options ...string,
) error {

if reward == 0 {
Expand All @@ -144,7 +153,13 @@ func (cp *challengePool) moveToBlobbers(sscKey string, reward currency.Coin,
return fmt.Errorf("not enough tokens in challenge pool: %v < %v", cp.Balance, reward)
}

err := sp.DistributeRewards(reward, blobberId, spenum.Blobber, spenum.ChallengePassReward, balances)
challengeID := ""

if len(options) > 0 {
challengeID = options[0]
}
Jayashsatolia403 marked this conversation as resolved.
Show resolved Hide resolved

err := sp.DistributeRewards(reward, blobberId, spenum.Blobber, spenum.ChallengePassReward, balances, challengeID)
if err != nil {
return fmt.Errorf("can't move tokens to blobber: %v", err)
}
Expand Down
14 changes: 13 additions & 1 deletion code/go/0chain.net/smartcontract/storagesc/handler.go
@@ -1,6 +1,7 @@
package storagesc

import (
"0chain.net/chaincore/config"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -50,7 +51,7 @@ func SetupRestHandler(rh rest.RestHandlerI) {
func GetEndpoints(rh rest.RestHandlerI) []rest.Endpoint {
srh := NewStorageRestHandler(rh)
storage := "/v1/screst/" + ADDRESS
return []rest.Endpoint{
restEndpoints := []rest.Endpoint{
rest.MakeEndpoint(storage+"/getBlobber", common.UserRateLimit(srh.getBlobber)),
rest.MakeEndpoint(storage+"/getblobbers", common.UserRateLimit(srh.getBlobbers)),
rest.MakeEndpoint(storage+"/blobbers-by-rank", common.UserRateLimit(srh.getBlobbersByRank)),
Expand Down Expand Up @@ -95,6 +96,17 @@ func GetEndpoints(rh rest.RestHandlerI) []rest.Endpoint {
rest.MakeEndpoint(storage+"/replicate-validator-aggregates", srh.replicateValidatorAggregates),
rest.MakeEndpoint(storage+"/replicate-user-aggregates", srh.replicateUserAggregates),
}

if config.Development() {
restEndpoints = append(restEndpoints, rest.MakeEndpoint(storage+"/all-challenges", srh.getAllChallenges))
restEndpoints = append(restEndpoints, rest.MakeEndpoint(storage+"/block-rewards", srh.getBlockRewards))
restEndpoints = append(restEndpoints, rest.MakeEndpoint(storage+"/read-rewards", srh.getReadRewards))
restEndpoints = append(restEndpoints, rest.MakeEndpoint(storage+"/challenge-rewards", srh.getChallengeRewards))
restEndpoints = append(restEndpoints, rest.MakeEndpoint(storage+"/total-challenge-rewards", srh.getTotalChallengeRewards))
restEndpoints = append(restEndpoints, rest.MakeEndpoint(storage+"/cancellation-rewards", srh.getAllocationCancellationReward))
}

return restEndpoints
}

// swagger:route GET /v1/screst/6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7/blobber_ids blobber_ids
Expand Down