Skip to content

Commit

Permalink
Merge pull request #791 from klim0v/v3.2.x
Browse files Browse the repository at this point in the history
V3.2.x
  • Loading branch information
Klimov Sergey authored Apr 27, 2022
2 parents 8641711 + f355045 commit b6a87ce
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 35 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
# Changelog

## [v3.2.0](https://github.com/MinterTeam/minter-go-node/tree/v3.2.0)

[Full Changelog](https://github.com/MinterTeam/minter-go-node/compare/v3.1.1...v3.2.0)

### Fixed

- Smooth increase in rewards after the fall
- Accruals for DAOs and developers, taking into account blocked stakes

## [v3.1.1](https://github.com/MinterTeam/minter-go-node/tree/v3.1.1)

[Full Changelog](https://github.com/MinterTeam/minter-go-node/compare/v3.1.0...v3.1.1)

### Fixed

- Find coins with last symbol `-`
- Accrual of rewards x3 with `GetAccumReward == 0`
- Accrual of rewards x3 with candidate's `AccumReward` is 0

## [v3.1.0](https://github.com/MinterTeam/minter-go-node/tree/v3.1.0)

Expand Down
25 changes: 10 additions & 15 deletions cmd/minter/cmd/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package cmd
import (
"crypto/sha256"
"encoding/json"
"github.com/MinterTeam/minter-go-node/coreV2/minter"
"github.com/MinterTeam/minter-go-node/coreV2/rewards"
"github.com/MinterTeam/minter-go-node/version"
"github.com/tendermint/go-amino"
"io"
Expand Down Expand Up @@ -90,19 +88,16 @@ func export(cmd *cobra.Command, args []string) error {
}
log.Printf("Verify state OK\n")

appState.Version = minter.V3
//versions := db.GetVersions()
//for _, v := range versions {
// appState.Versions = append(appState.Versions, mtypes.Version{
// Height: v.Height,
// Name: v.Name,
// })
//}

//appState.Emission = db.Emission().String()
appState.Emission = rewards.NewReward().GetBeforeBlock(height).String()
reserve0, reserve1 := currentState.Swap().GetSwapper(0, 1993).Reserves()
db.UpdatePrice(time.Unix(0, int64(genesisTime)).UTC(), reserve0, reserve1)
//appState.Version = minter.V3
versions := db.GetVersions()
for _, v := range versions {
appState.Versions = append(appState.Versions, mtypes.Version{
Height: v.Height,
Name: v.Name,
})
}

appState.Emission = db.Emission().String()
t, r0, r1, reward, off := db.GetPrice()
appState.PrevReward = mtypes.RewardPrice{
Time: uint64(t.UTC().UnixNano()),
Expand Down
46 changes: 45 additions & 1 deletion coreV2/appdb/appdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,51 @@ type TimePrice struct {
Last *big.Int
}

func (appDB *AppDB) UpdatePrice(t time.Time, r0, r1 *big.Int) (reward, safeReward *big.Int) {
func (appDB *AppDB) UpdatePriceFix(t time.Time, r0, r1 *big.Int) (reward, safeReward *big.Int) {
tOld, reserve0, reserve1, last, off := appDB.GetPrice()

fNew := big.NewRat(1, 1).SetFrac(r1, r0)
// Price ^ (1/4) * 350
priceCount, _ := new(big.Float).Mul(new(big.Float).Mul(math.Pow(new(big.Float).SetRat(fNew), big.NewFloat(0.25)), big.NewFloat(350)), big.NewFloat(1e18)).Int(nil)
if tOld.IsZero() {
appDB.SetPrice(t, r0, r1, priceCount, false)
return new(big.Int).Set(priceCount), new(big.Int).Set(priceCount)
}

defer func() { appDB.SetPrice(t, r0, r1, last, off) }()

fOld := big.NewRat(1, 1).SetFrac(reserve1, reserve0)

rat := new(big.Rat).Mul(new(big.Rat).Quo(new(big.Rat).Sub(fNew, fOld), fOld), new(big.Rat).SetInt64(100))
diff := big.NewInt(0).Div(rat.Num(), rat.Denom())

if diff.Cmp(big.NewInt(-10)) != 1 {
last.SetInt64(0)
off = true
return last, new(big.Int).Set(priceCount)
}

if off && last.Cmp(priceCount) == -1 {
last.Add(last, big.NewInt(5e18))
last.Add(last, big.NewInt(5e18))
burn := big.NewInt(0).Sub(priceCount, last)
if burn.Sign() != 1 {
last.Set(priceCount)
off = false
return new(big.Int).Set(last), new(big.Int).Set(priceCount)
}
return new(big.Int).Set(last), new(big.Int).Set(priceCount)
}

off = false
last.Set(priceCount)

return new(big.Int).Set(last), new(big.Int).Set(priceCount)
}

// UpdatePriceBug
// Deprecated
func (appDB *AppDB) UpdatePriceBug(t time.Time, r0, r1 *big.Int) (reward, safeReward *big.Int) {
tOld, reserve0, reserve1, last, off := appDB.GetPrice()

fNew := big.NewRat(1, 1).SetFrac(r1, r0)
Expand Down
26 changes: 17 additions & 9 deletions coreV2/minter/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ func NewMinterBlockchain(storages *utils.Storage, cfg *config.Config, ctx contex
knownUpdates: map[string]struct{}{
V3: {}, // tokenomics
V310: {}, // hotfix
V320: {},
},
executor: GetExecutor(V3),
}
Expand Down Expand Up @@ -177,6 +178,7 @@ func GetExecutor(v string) transaction.ExecutorTx {
const ( // known update versions
V3 = "v300" // tokenomics
V310 = "v310" // hotfix
V320 = "v320" // hotfix
)

func (blockchain *Blockchain) initState() {
Expand Down Expand Up @@ -275,7 +277,11 @@ func (blockchain *Blockchain) BeginBlock(req abciTypes.RequestBeginBlock) abciTy
t, _, _, _, _ := blockchain.appDB.GetPrice()
if height%blockchain.updateStakesAndPayRewardsPeriod == 1 && (t.IsZero() || (req.Header.Time.Hour() >= 12 && req.Header.Time.Hour() <= 14) && req.Header.Time.Sub(t) > 3*time.Hour) {
reserve0, reserve1 := blockchain.stateCheck.Swap().GetSwapper(0, types.USDTID).Reserves()
newRewards, safeReward := blockchain.appDB.UpdatePrice(req.Header.Time, reserve0, reserve1)
funcUpdatePrice := blockchain.appDB.UpdatePriceBug
if h := blockchain.appDB.GetVersionHeight(V320); h > 0 && height > h {
funcUpdatePrice = blockchain.appDB.UpdatePriceFix
}
newRewards, safeReward := funcUpdatePrice(req.Header.Time, reserve0, reserve1)
blockchain.stateDeliver.App.SetReward(newRewards, safeReward)
blockchain.eventsDB.AddEvent(&eventsdb.UpdatedBlockRewardEvent{Value: newRewards.String(), ValueLockedStakeRewards: new(big.Int).Mul(safeReward, big.NewInt(3)).String()})
}
Expand Down Expand Up @@ -445,15 +451,17 @@ func (blockchain *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes.
// pay rewards
var moreRewards = big.NewInt(0)
if height%blockchain.updateStakesAndPayRewardsPeriod == 0 {
if h := blockchain.appDB.GetVersionHeight(V310); h > 0 && height > h {
moreRewards = blockchain.stateDeliver.Validators.PayRewardsV4(heightIsMaxIfIssueIsOverOrNotDynamic, int64(blockchain.updateStakesAndPayRewardsPeriod))
blockchain.appDB.SetEmission(big.NewInt(0).Add(blockchain.appDB.Emission(), moreRewards))
blockchain.stateDeliver.Checker.AddCoinVolume(types.GetBaseCoinID(), moreRewards)
} else {
moreRewards = blockchain.stateDeliver.Validators.PayRewardsV3(heightIsMaxIfIssueIsOverOrNotDynamic, int64(blockchain.updateStakesAndPayRewardsPeriod))
blockchain.appDB.SetEmission(big.NewInt(0).Add(blockchain.appDB.Emission(), moreRewards))
blockchain.stateDeliver.Checker.AddCoinVolume(types.GetBaseCoinID(), moreRewards)
PayRewards := blockchain.stateDeliver.Validators.PayRewardsV3
if h := blockchain.appDB.GetVersionHeight(V320); h > 0 && height > h {
PayRewards = blockchain.stateDeliver.Validators.PayRewardsV5
} else if h := blockchain.appDB.GetVersionHeight(V310); h > 0 && height > h {
PayRewards = blockchain.stateDeliver.Validators.PayRewardsV4
}

moreRewards = PayRewards(heightIsMaxIfIssueIsOverOrNotDynamic, int64(blockchain.updateStakesAndPayRewardsPeriod))
blockchain.appDB.SetEmission(big.NewInt(0).Add(blockchain.appDB.Emission(), moreRewards))
blockchain.stateDeliver.Checker.AddCoinVolume(types.GetBaseCoinID(), moreRewards)

}

if heightIsMaxIfIssueIsOverOrNotDynamic != math.MaxUint64 {
Expand Down
198 changes: 197 additions & 1 deletion coreV2/state/validators/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,203 @@ func (v *Validators) PayRewardsV3(height uint64, period int64) (moreRewards *big
return moreRewards
}

// PayRewardsV4 distributes accumulated rewards between validator, delegators, DAO and developers addresses
// PayRewardsV5 distributes accumulated rewards between validator, delegators, DAO and developers addresses
func (v *Validators) PayRewardsV5(height uint64, period int64) (moreRewards *big.Int) {
moreRewards = big.NewInt(0)

vals := v.GetValidators()

calcReward, safeReward := v.bus.App().Reward()
var totalAccumRewards = big.NewInt(0)
for _, validator := range vals {
totalAccumRewards = totalAccumRewards.Add(totalAccumRewards, validator.GetAccumReward())
}

var totalStakes = big.NewInt(0)
if totalAccumRewards.Sign() != 1 {
for _, validator := range vals {
totalStakes = totalStakes.Add(totalStakes, validator.GetTotalBipStake())
}
}

for _, validator := range vals {
candidate := v.bus.Candidates().GetCandidate(validator.PubKey)

totalReward := big.NewInt(0).Set(validator.GetAccumReward())
remainder := big.NewInt(0).Set(validator.GetAccumReward())

// pay commission to DAO

DAOReward := big.NewInt(0).Set(totalReward)
DAOReward.Mul(DAOReward, big.NewInt(int64(dao.Commission)))
DAOReward.Div(DAOReward, big.NewInt(100))

// pay commission to Developers

DevelopersReward := big.NewInt(0).Set(totalReward)
DevelopersReward.Mul(DevelopersReward, big.NewInt(int64(developers.Commission)))
DevelopersReward.Div(DevelopersReward, big.NewInt(100))

totalReward.Sub(totalReward, DevelopersReward)
totalReward.Sub(totalReward, DAOReward)
remainder.Sub(remainder, DAOReward)
remainder.Sub(remainder, DevelopersReward)

// pay commission to validator
validatorReward := big.NewInt(0).Set(totalReward)
validatorReward.Mul(validatorReward, big.NewInt(int64(candidate.Commission)))
validatorReward.Div(validatorReward, big.NewInt(100))
totalReward.Sub(totalReward, validatorReward)

candidate.AddUpdate(types.GetBaseCoinID(), validatorReward, validatorReward, candidate.RewardAddress)
v.bus.Checker().AddCoin(types.GetBaseCoinID(), validatorReward)

remainder.Sub(remainder, validatorReward)
v.bus.Events().AddEvent(&eventsdb.RewardEvent{
Role: eventsdb.RoleValidator.String(),
Address: candidate.RewardAddress,
Amount: validatorReward.String(),
ValidatorPubKey: validator.PubKey,
ForCoin: 0,
})

stakes := v.bus.Candidates().GetStakes(validator.PubKey)
for _, stake := range stakes {
if stake.BipValue.Sign() == 0 {
continue
}

reward := big.NewInt(0).Set(totalReward)
reward.Mul(reward, stake.BipValue)

reward.Div(reward, validator.GetTotalBipStake())

remainder.Sub(remainder, reward)

safeRewardVariable := big.NewInt(0).Set(reward)
if validator.bus.Accounts().IsX3Mining(stake.Owner, height) {
if totalAccumRewards.Sign() == 1 && validator.GetAccumReward().Sign() == 1 {
safeRewards := big.NewInt(0).Mul(safeReward, big.NewInt(period))
safeRewards.Mul(safeRewards, stake.BipValue)
safeRewards.Mul(safeRewards, big.NewInt(3))
safeRewards.Mul(safeRewards, validator.GetAccumReward())
safeRewards.Div(safeRewards, validator.GetTotalBipStake())

taxDAOx3 := big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(developers.Commission))), big.NewInt(100))
taxDEVx3 := big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(dao.Commission))), big.NewInt(100))

safeRewards.Sub(safeRewards, taxDAOx3)
safeRewards.Sub(safeRewards, taxDEVx3)
safeRewards.Sub(safeRewards, big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(candidate.Commission))), big.NewInt(100)))
safeRewards.Div(safeRewards, totalAccumRewards)

calcRewards := big.NewInt(0).Mul(calcReward, big.NewInt(period))
calcRewards.Mul(calcRewards, stake.BipValue)
calcRewards.Mul(calcRewards, validator.GetAccumReward())
calcRewards.Div(calcRewards, validator.GetTotalBipStake())

taxDAO := big.NewInt(0).Div(big.NewInt(0).Mul(calcRewards, big.NewInt(int64(developers.Commission))), big.NewInt(100))
taxDEV := big.NewInt(0).Div(big.NewInt(0).Mul(calcRewards, big.NewInt(int64(dao.Commission))), big.NewInt(100))

calcRewards.Sub(calcRewards, taxDAO)
calcRewards.Sub(calcRewards, taxDEV)
calcRewards.Sub(calcRewards, big.NewInt(0).Div(big.NewInt(0).Mul(calcRewards, big.NewInt(int64(developers.Commission+dao.Commission))), big.NewInt(100)))
calcRewards.Sub(calcRewards, big.NewInt(0).Div(big.NewInt(0).Mul(calcRewards, big.NewInt(int64(candidate.Commission))), big.NewInt(100)))
calcRewards.Div(calcRewards, totalAccumRewards)

diffDAO := big.NewInt(0).Sub(taxDAOx3, taxDAO)
diffDEV := big.NewInt(0).Sub(taxDAOx3, taxDEV)
DAOReward.Add(DAOReward, diffDAO)
DevelopersReward.Add(DevelopersReward, diffDEV)

moreRewards.Add(moreRewards, diffDAO)
moreRewards.Add(moreRewards, diffDEV)

feeRewards := big.NewInt(0).Sub(reward, calcRewards)
safeRewardVariable.Set(big.NewInt(0).Add(safeRewards, feeRewards))
} else if totalAccumRewards.Sign() != 1 && validator.GetAccumReward().Sign() != 1 {
safeRewards := big.NewInt(0).Mul(safeReward, big.NewInt(period))
safeRewards.Mul(safeRewards, stake.BipValue)
safeRewards.Mul(safeRewards, big.NewInt(3))

taxDAO := big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(developers.Commission))), big.NewInt(100))
taxDEV := big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(dao.Commission))), big.NewInt(100))

DAOReward.Add(DAOReward, taxDAO)
DevelopersReward.Add(DevelopersReward, taxDEV)
moreRewards.Add(moreRewards, taxDAO)
moreRewards.Add(moreRewards, taxDEV)

safeRewards.Sub(safeRewards, taxDAO)
safeRewards.Sub(safeRewards, taxDEV)

safeRewards.Sub(safeRewards, big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(candidate.Commission))), big.NewInt(100)))
safeRewards.Div(safeRewards, totalStakes)

safeRewardVariable.Set(safeRewards)
}

if safeRewardVariable.Sign() < 1 {
continue
}

moreRewards.Add(moreRewards, new(big.Int).Sub(safeRewardVariable, reward))
}

if safeRewardVariable.Sign() < 1 {
continue
}

candidate.AddUpdate(types.GetBaseCoinID(), safeRewardVariable, safeRewardVariable, stake.Owner)
v.bus.Checker().AddCoin(types.GetBaseCoinID(), safeRewardVariable)

v.bus.Events().AddEvent(&eventsdb.RewardEvent{
Role: eventsdb.RoleDelegator.String(),
Address: stake.Owner,
Amount: safeRewardVariable.String(),
ValidatorPubKey: validator.PubKey,
ForCoin: uint64(stake.Coin),
})
}

{
candidate.AddUpdate(types.GetBaseCoinID(), DAOReward, DAOReward, dao.Address)
v.bus.Checker().AddCoin(types.GetBaseCoinID(), DAOReward)
v.bus.Events().AddEvent(&eventsdb.RewardEvent{
Role: eventsdb.RoleDAO.String(),
Address: dao.Address,
Amount: DAOReward.String(),
ValidatorPubKey: validator.PubKey,
ForCoin: 0,
})
}

{
candidate.AddUpdate(types.GetBaseCoinID(), DevelopersReward, DevelopersReward, developers.Address)
v.bus.Checker().AddCoin(types.GetBaseCoinID(), DevelopersReward)
v.bus.Events().AddEvent(&eventsdb.RewardEvent{
Role: eventsdb.RoleDevelopers.String(),
Address: developers.Address,
Amount: DevelopersReward.String(),
ValidatorPubKey: validator.PubKey,
ForCoin: 0,
})
}

validator.SetAccumReward(big.NewInt(0))

if remainder.Sign() != -1 {
v.bus.App().AddTotalSlashed(remainder)
} else {
panic(fmt.Sprintf("Negative remainder: %s", remainder.String()))
}
}

return moreRewards
}

// PayRewardsV4
// Deprecated
func (v *Validators) PayRewardsV4(height uint64, period int64) (moreRewards *big.Int) {
moreRewards = big.NewInt(0)

Expand Down
Loading

0 comments on commit b6a87ce

Please sign in to comment.