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
Merged
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
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
@@ -0,0 +1,52 @@
package event

import (
"0chain.net/smartcontract/stakepool/spenum"
"github.com/pkg/errors"
)

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

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

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

return rds, err
}

return nil, errors.Errorf("start or end block number can't be empty")

}

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

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

if err != nil {
return nil, nil, err
}

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

if err != nil {
return nil, nil, err
}

return blobberRewards, validatorRewards, nil
}

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

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

return rps, err
}
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
@@ -0,0 +1,50 @@
package event

import (
"0chain.net/smartcontract/stakepool/spenum"
"github.com/pkg/errors"
)

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

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

if startBlockNumber != "" && endBlockNumber != "" {
var rps []RewardProvider
err := edb.Get().Where("block_number >= ? AND block_number <= ? AND reward_type = ?", startBlockNumber, endBlockNumber, rewardType).Find(&rps).Error

return rps, err
}

return nil, errors.Errorf("start or end block number can't be empty")
}

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

var blobberRewards []RewardProvider
err := edb.Get().Where("challenge_id = ? AND reward_type = ?", challengeID, spenum.ChallengePassReward).Find(&blobberRewards).Error
if err != nil {
return nil, nil, err
}

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

if err != nil {
return nil, nil, err
}

return blobberRewards, validatorRewards, nil
}

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

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

return rps, err
}
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 @@ -57,5 +65,6 @@ func stakePoolRewardToStakePoolRewardEvent(spu StakePoolReward) *dbs.StakePoolRe
DelegateRewards: spu.DelegateRewards,
DelegatePenalties: spu.DelegatePenalties,
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

defer func() {
if err != nil {
Expand Down
24 changes: 17 additions & 7 deletions code/go/0chain.net/smartcontract/storagesc/challenge.go
Expand Up @@ -76,8 +76,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 @@ -121,6 +120,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 @@ -180,7 +184,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 blobbers: %v", err)
}
Expand All @@ -197,7 +201,7 @@ func (sc *StorageSmartContract) blobberReward(alloc *StorageAllocation, latestCo
return err
}

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 @@ -281,7 +285,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 @@ -341,8 +345,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 @@ -717,7 +727,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
8 changes: 5 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 @@ -110,15 +111,15 @@ func (cp *challengePool) moveToValidators(sscKey string, reward currency.Coin,
}

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, options...)
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, options...)
if err != nil {
return fmt.Errorf("moving to validator %s: %v",
validators[i], err)
Expand All @@ -134,6 +135,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 +146,7 @@ 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)
err := sp.DistributeRewards(reward, blobberId, spenum.Blobber, spenum.ChallengePassReward, balances, options...)
if err != nil {
return fmt.Errorf("can't move tokens to blobber: %v", err)
}
Expand Down