Skip to content

Commit

Permalink
Merge pull request #2320 from 0chain/tokenomics_suite
Browse files Browse the repository at this point in the history
Tokenomics suite
  • Loading branch information
dabasov committed May 6, 2023
2 parents c8e0aa1 + 87fb5fa commit c5c503e
Show file tree
Hide file tree
Showing 14 changed files with 413 additions and 19 deletions.
2 changes: 1 addition & 1 deletion code/go/0chain.net/chaincore/smartcontract/handler_test.go
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)
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
3 changes: 3 additions & 0 deletions code/go/0chain.net/smartcontract/dbs/event/reward_delegate.go
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
52 changes: 52 additions & 0 deletions code/go/0chain.net/smartcontract/dbs/event/reward_delegate_dev.go
@@ -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
50 changes: 50 additions & 0 deletions code/go/0chain.net/smartcontract/dbs/event/reward_provider_dev.go
@@ -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 = ""
}
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)
}

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]
}

// 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

0 comments on commit c5c503e

Please sign in to comment.