Skip to content

Commit de768df

Browse files
author
Klimov Sergey
authored
Merge pull request #792 from MinterTeam/dev
v3.2.0
2 parents 43f4f18 + b6a87ce commit de768df

8 files changed

Lines changed: 311 additions & 35 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
# Changelog
22

3+
## [v3.2.0](https://github.com/MinterTeam/minter-go-node/tree/v3.2.0)
4+
5+
[Full Changelog](https://github.com/MinterTeam/minter-go-node/compare/v3.1.1...v3.2.0)
6+
7+
### Fixed
8+
9+
- Smooth increase in rewards after the fall
10+
- Accruals for DAOs and developers, taking into account blocked stakes
11+
312
## [v3.1.1](https://github.com/MinterTeam/minter-go-node/tree/v3.1.1)
413

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

716
### Fixed
817

918
- Find coins with last symbol `-`
10-
- Accrual of rewards x3 with `GetAccumReward == 0`
19+
- Accrual of rewards x3 with candidate's `AccumReward` is 0
1120

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

cmd/minter/cmd/export.go

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package cmd
33
import (
44
"crypto/sha256"
55
"encoding/json"
6-
"github.com/MinterTeam/minter-go-node/coreV2/minter"
7-
"github.com/MinterTeam/minter-go-node/coreV2/rewards"
86
"github.com/MinterTeam/minter-go-node/version"
97
"github.com/tendermint/go-amino"
108
"io"
@@ -90,19 +88,16 @@ func export(cmd *cobra.Command, args []string) error {
9088
}
9189
log.Printf("Verify state OK\n")
9290

93-
appState.Version = minter.V3
94-
//versions := db.GetVersions()
95-
//for _, v := range versions {
96-
// appState.Versions = append(appState.Versions, mtypes.Version{
97-
// Height: v.Height,
98-
// Name: v.Name,
99-
// })
100-
//}
101-
102-
//appState.Emission = db.Emission().String()
103-
appState.Emission = rewards.NewReward().GetBeforeBlock(height).String()
104-
reserve0, reserve1 := currentState.Swap().GetSwapper(0, 1993).Reserves()
105-
db.UpdatePrice(time.Unix(0, int64(genesisTime)).UTC(), reserve0, reserve1)
91+
//appState.Version = minter.V3
92+
versions := db.GetVersions()
93+
for _, v := range versions {
94+
appState.Versions = append(appState.Versions, mtypes.Version{
95+
Height: v.Height,
96+
Name: v.Name,
97+
})
98+
}
99+
100+
appState.Emission = db.Emission().String()
106101
t, r0, r1, reward, off := db.GetPrice()
107102
appState.PrevReward = mtypes.RewardPrice{
108103
Time: uint64(t.UTC().UnixNano()),

coreV2/appdb/appdb.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,51 @@ type TimePrice struct {
447447
Last *big.Int
448448
}
449449

450-
func (appDB *AppDB) UpdatePrice(t time.Time, r0, r1 *big.Int) (reward, safeReward *big.Int) {
450+
func (appDB *AppDB) UpdatePriceFix(t time.Time, r0, r1 *big.Int) (reward, safeReward *big.Int) {
451+
tOld, reserve0, reserve1, last, off := appDB.GetPrice()
452+
453+
fNew := big.NewRat(1, 1).SetFrac(r1, r0)
454+
// Price ^ (1/4) * 350
455+
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)
456+
if tOld.IsZero() {
457+
appDB.SetPrice(t, r0, r1, priceCount, false)
458+
return new(big.Int).Set(priceCount), new(big.Int).Set(priceCount)
459+
}
460+
461+
defer func() { appDB.SetPrice(t, r0, r1, last, off) }()
462+
463+
fOld := big.NewRat(1, 1).SetFrac(reserve1, reserve0)
464+
465+
rat := new(big.Rat).Mul(new(big.Rat).Quo(new(big.Rat).Sub(fNew, fOld), fOld), new(big.Rat).SetInt64(100))
466+
diff := big.NewInt(0).Div(rat.Num(), rat.Denom())
467+
468+
if diff.Cmp(big.NewInt(-10)) != 1 {
469+
last.SetInt64(0)
470+
off = true
471+
return last, new(big.Int).Set(priceCount)
472+
}
473+
474+
if off && last.Cmp(priceCount) == -1 {
475+
last.Add(last, big.NewInt(5e18))
476+
last.Add(last, big.NewInt(5e18))
477+
burn := big.NewInt(0).Sub(priceCount, last)
478+
if burn.Sign() != 1 {
479+
last.Set(priceCount)
480+
off = false
481+
return new(big.Int).Set(last), new(big.Int).Set(priceCount)
482+
}
483+
return new(big.Int).Set(last), new(big.Int).Set(priceCount)
484+
}
485+
486+
off = false
487+
last.Set(priceCount)
488+
489+
return new(big.Int).Set(last), new(big.Int).Set(priceCount)
490+
}
491+
492+
// UpdatePriceBug
493+
// Deprecated
494+
func (appDB *AppDB) UpdatePriceBug(t time.Time, r0, r1 *big.Int) (reward, safeReward *big.Int) {
451495
tOld, reserve0, reserve1, last, off := appDB.GetPrice()
452496

453497
fNew := big.NewRat(1, 1).SetFrac(r1, r0)

coreV2/minter/blockchain.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ func NewMinterBlockchain(storages *utils.Storage, cfg *config.Config, ctx contex
146146
knownUpdates: map[string]struct{}{
147147
V3: {}, // tokenomics
148148
V310: {}, // hotfix
149+
V320: {},
149150
},
150151
executor: GetExecutor(V3),
151152
}
@@ -177,6 +178,7 @@ func GetExecutor(v string) transaction.ExecutorTx {
177178
const ( // known update versions
178179
V3 = "v300" // tokenomics
179180
V310 = "v310" // hotfix
181+
V320 = "v320" // hotfix
180182
)
181183

182184
func (blockchain *Blockchain) initState() {
@@ -275,7 +277,11 @@ func (blockchain *Blockchain) BeginBlock(req abciTypes.RequestBeginBlock) abciTy
275277
t, _, _, _, _ := blockchain.appDB.GetPrice()
276278
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) {
277279
reserve0, reserve1 := blockchain.stateCheck.Swap().GetSwapper(0, types.USDTID).Reserves()
278-
newRewards, safeReward := blockchain.appDB.UpdatePrice(req.Header.Time, reserve0, reserve1)
280+
funcUpdatePrice := blockchain.appDB.UpdatePriceBug
281+
if h := blockchain.appDB.GetVersionHeight(V320); h > 0 && height > h {
282+
funcUpdatePrice = blockchain.appDB.UpdatePriceFix
283+
}
284+
newRewards, safeReward := funcUpdatePrice(req.Header.Time, reserve0, reserve1)
279285
blockchain.stateDeliver.App.SetReward(newRewards, safeReward)
280286
blockchain.eventsDB.AddEvent(&eventsdb.UpdatedBlockRewardEvent{Value: newRewards.String(), ValueLockedStakeRewards: new(big.Int).Mul(safeReward, big.NewInt(3)).String()})
281287
}
@@ -445,15 +451,17 @@ func (blockchain *Blockchain) EndBlock(req abciTypes.RequestEndBlock) abciTypes.
445451
// pay rewards
446452
var moreRewards = big.NewInt(0)
447453
if height%blockchain.updateStakesAndPayRewardsPeriod == 0 {
448-
if h := blockchain.appDB.GetVersionHeight(V310); h > 0 && height > h {
449-
moreRewards = blockchain.stateDeliver.Validators.PayRewardsV4(heightIsMaxIfIssueIsOverOrNotDynamic, int64(blockchain.updateStakesAndPayRewardsPeriod))
450-
blockchain.appDB.SetEmission(big.NewInt(0).Add(blockchain.appDB.Emission(), moreRewards))
451-
blockchain.stateDeliver.Checker.AddCoinVolume(types.GetBaseCoinID(), moreRewards)
452-
} else {
453-
moreRewards = blockchain.stateDeliver.Validators.PayRewardsV3(heightIsMaxIfIssueIsOverOrNotDynamic, int64(blockchain.updateStakesAndPayRewardsPeriod))
454-
blockchain.appDB.SetEmission(big.NewInt(0).Add(blockchain.appDB.Emission(), moreRewards))
455-
blockchain.stateDeliver.Checker.AddCoinVolume(types.GetBaseCoinID(), moreRewards)
454+
PayRewards := blockchain.stateDeliver.Validators.PayRewardsV3
455+
if h := blockchain.appDB.GetVersionHeight(V320); h > 0 && height > h {
456+
PayRewards = blockchain.stateDeliver.Validators.PayRewardsV5
457+
} else if h := blockchain.appDB.GetVersionHeight(V310); h > 0 && height > h {
458+
PayRewards = blockchain.stateDeliver.Validators.PayRewardsV4
456459
}
460+
461+
moreRewards = PayRewards(heightIsMaxIfIssueIsOverOrNotDynamic, int64(blockchain.updateStakesAndPayRewardsPeriod))
462+
blockchain.appDB.SetEmission(big.NewInt(0).Add(blockchain.appDB.Emission(), moreRewards))
463+
blockchain.stateDeliver.Checker.AddCoinVolume(types.GetBaseCoinID(), moreRewards)
464+
457465
}
458466

459467
if heightIsMaxIfIssueIsOverOrNotDynamic != math.MaxUint64 {

coreV2/state/validators/validators.go

Lines changed: 197 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,203 @@ func (v *Validators) PayRewardsV3(height uint64, period int64) (moreRewards *big
431431
return moreRewards
432432
}
433433

434-
// PayRewardsV4 distributes accumulated rewards between validator, delegators, DAO and developers addresses
434+
// PayRewardsV5 distributes accumulated rewards between validator, delegators, DAO and developers addresses
435+
func (v *Validators) PayRewardsV5(height uint64, period int64) (moreRewards *big.Int) {
436+
moreRewards = big.NewInt(0)
437+
438+
vals := v.GetValidators()
439+
440+
calcReward, safeReward := v.bus.App().Reward()
441+
var totalAccumRewards = big.NewInt(0)
442+
for _, validator := range vals {
443+
totalAccumRewards = totalAccumRewards.Add(totalAccumRewards, validator.GetAccumReward())
444+
}
445+
446+
var totalStakes = big.NewInt(0)
447+
if totalAccumRewards.Sign() != 1 {
448+
for _, validator := range vals {
449+
totalStakes = totalStakes.Add(totalStakes, validator.GetTotalBipStake())
450+
}
451+
}
452+
453+
for _, validator := range vals {
454+
candidate := v.bus.Candidates().GetCandidate(validator.PubKey)
455+
456+
totalReward := big.NewInt(0).Set(validator.GetAccumReward())
457+
remainder := big.NewInt(0).Set(validator.GetAccumReward())
458+
459+
// pay commission to DAO
460+
461+
DAOReward := big.NewInt(0).Set(totalReward)
462+
DAOReward.Mul(DAOReward, big.NewInt(int64(dao.Commission)))
463+
DAOReward.Div(DAOReward, big.NewInt(100))
464+
465+
// pay commission to Developers
466+
467+
DevelopersReward := big.NewInt(0).Set(totalReward)
468+
DevelopersReward.Mul(DevelopersReward, big.NewInt(int64(developers.Commission)))
469+
DevelopersReward.Div(DevelopersReward, big.NewInt(100))
470+
471+
totalReward.Sub(totalReward, DevelopersReward)
472+
totalReward.Sub(totalReward, DAOReward)
473+
remainder.Sub(remainder, DAOReward)
474+
remainder.Sub(remainder, DevelopersReward)
475+
476+
// pay commission to validator
477+
validatorReward := big.NewInt(0).Set(totalReward)
478+
validatorReward.Mul(validatorReward, big.NewInt(int64(candidate.Commission)))
479+
validatorReward.Div(validatorReward, big.NewInt(100))
480+
totalReward.Sub(totalReward, validatorReward)
481+
482+
candidate.AddUpdate(types.GetBaseCoinID(), validatorReward, validatorReward, candidate.RewardAddress)
483+
v.bus.Checker().AddCoin(types.GetBaseCoinID(), validatorReward)
484+
485+
remainder.Sub(remainder, validatorReward)
486+
v.bus.Events().AddEvent(&eventsdb.RewardEvent{
487+
Role: eventsdb.RoleValidator.String(),
488+
Address: candidate.RewardAddress,
489+
Amount: validatorReward.String(),
490+
ValidatorPubKey: validator.PubKey,
491+
ForCoin: 0,
492+
})
493+
494+
stakes := v.bus.Candidates().GetStakes(validator.PubKey)
495+
for _, stake := range stakes {
496+
if stake.BipValue.Sign() == 0 {
497+
continue
498+
}
499+
500+
reward := big.NewInt(0).Set(totalReward)
501+
reward.Mul(reward, stake.BipValue)
502+
503+
reward.Div(reward, validator.GetTotalBipStake())
504+
505+
remainder.Sub(remainder, reward)
506+
507+
safeRewardVariable := big.NewInt(0).Set(reward)
508+
if validator.bus.Accounts().IsX3Mining(stake.Owner, height) {
509+
if totalAccumRewards.Sign() == 1 && validator.GetAccumReward().Sign() == 1 {
510+
safeRewards := big.NewInt(0).Mul(safeReward, big.NewInt(period))
511+
safeRewards.Mul(safeRewards, stake.BipValue)
512+
safeRewards.Mul(safeRewards, big.NewInt(3))
513+
safeRewards.Mul(safeRewards, validator.GetAccumReward())
514+
safeRewards.Div(safeRewards, validator.GetTotalBipStake())
515+
516+
taxDAOx3 := big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(developers.Commission))), big.NewInt(100))
517+
taxDEVx3 := big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(dao.Commission))), big.NewInt(100))
518+
519+
safeRewards.Sub(safeRewards, taxDAOx3)
520+
safeRewards.Sub(safeRewards, taxDEVx3)
521+
safeRewards.Sub(safeRewards, big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(candidate.Commission))), big.NewInt(100)))
522+
safeRewards.Div(safeRewards, totalAccumRewards)
523+
524+
calcRewards := big.NewInt(0).Mul(calcReward, big.NewInt(period))
525+
calcRewards.Mul(calcRewards, stake.BipValue)
526+
calcRewards.Mul(calcRewards, validator.GetAccumReward())
527+
calcRewards.Div(calcRewards, validator.GetTotalBipStake())
528+
529+
taxDAO := big.NewInt(0).Div(big.NewInt(0).Mul(calcRewards, big.NewInt(int64(developers.Commission))), big.NewInt(100))
530+
taxDEV := big.NewInt(0).Div(big.NewInt(0).Mul(calcRewards, big.NewInt(int64(dao.Commission))), big.NewInt(100))
531+
532+
calcRewards.Sub(calcRewards, taxDAO)
533+
calcRewards.Sub(calcRewards, taxDEV)
534+
calcRewards.Sub(calcRewards, big.NewInt(0).Div(big.NewInt(0).Mul(calcRewards, big.NewInt(int64(developers.Commission+dao.Commission))), big.NewInt(100)))
535+
calcRewards.Sub(calcRewards, big.NewInt(0).Div(big.NewInt(0).Mul(calcRewards, big.NewInt(int64(candidate.Commission))), big.NewInt(100)))
536+
calcRewards.Div(calcRewards, totalAccumRewards)
537+
538+
diffDAO := big.NewInt(0).Sub(taxDAOx3, taxDAO)
539+
diffDEV := big.NewInt(0).Sub(taxDAOx3, taxDEV)
540+
DAOReward.Add(DAOReward, diffDAO)
541+
DevelopersReward.Add(DevelopersReward, diffDEV)
542+
543+
moreRewards.Add(moreRewards, diffDAO)
544+
moreRewards.Add(moreRewards, diffDEV)
545+
546+
feeRewards := big.NewInt(0).Sub(reward, calcRewards)
547+
safeRewardVariable.Set(big.NewInt(0).Add(safeRewards, feeRewards))
548+
} else if totalAccumRewards.Sign() != 1 && validator.GetAccumReward().Sign() != 1 {
549+
safeRewards := big.NewInt(0).Mul(safeReward, big.NewInt(period))
550+
safeRewards.Mul(safeRewards, stake.BipValue)
551+
safeRewards.Mul(safeRewards, big.NewInt(3))
552+
553+
taxDAO := big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(developers.Commission))), big.NewInt(100))
554+
taxDEV := big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(dao.Commission))), big.NewInt(100))
555+
556+
DAOReward.Add(DAOReward, taxDAO)
557+
DevelopersReward.Add(DevelopersReward, taxDEV)
558+
moreRewards.Add(moreRewards, taxDAO)
559+
moreRewards.Add(moreRewards, taxDEV)
560+
561+
safeRewards.Sub(safeRewards, taxDAO)
562+
safeRewards.Sub(safeRewards, taxDEV)
563+
564+
safeRewards.Sub(safeRewards, big.NewInt(0).Div(big.NewInt(0).Mul(safeRewards, big.NewInt(int64(candidate.Commission))), big.NewInt(100)))
565+
safeRewards.Div(safeRewards, totalStakes)
566+
567+
safeRewardVariable.Set(safeRewards)
568+
}
569+
570+
if safeRewardVariable.Sign() < 1 {
571+
continue
572+
}
573+
574+
moreRewards.Add(moreRewards, new(big.Int).Sub(safeRewardVariable, reward))
575+
}
576+
577+
if safeRewardVariable.Sign() < 1 {
578+
continue
579+
}
580+
581+
candidate.AddUpdate(types.GetBaseCoinID(), safeRewardVariable, safeRewardVariable, stake.Owner)
582+
v.bus.Checker().AddCoin(types.GetBaseCoinID(), safeRewardVariable)
583+
584+
v.bus.Events().AddEvent(&eventsdb.RewardEvent{
585+
Role: eventsdb.RoleDelegator.String(),
586+
Address: stake.Owner,
587+
Amount: safeRewardVariable.String(),
588+
ValidatorPubKey: validator.PubKey,
589+
ForCoin: uint64(stake.Coin),
590+
})
591+
}
592+
593+
{
594+
candidate.AddUpdate(types.GetBaseCoinID(), DAOReward, DAOReward, dao.Address)
595+
v.bus.Checker().AddCoin(types.GetBaseCoinID(), DAOReward)
596+
v.bus.Events().AddEvent(&eventsdb.RewardEvent{
597+
Role: eventsdb.RoleDAO.String(),
598+
Address: dao.Address,
599+
Amount: DAOReward.String(),
600+
ValidatorPubKey: validator.PubKey,
601+
ForCoin: 0,
602+
})
603+
}
604+
605+
{
606+
candidate.AddUpdate(types.GetBaseCoinID(), DevelopersReward, DevelopersReward, developers.Address)
607+
v.bus.Checker().AddCoin(types.GetBaseCoinID(), DevelopersReward)
608+
v.bus.Events().AddEvent(&eventsdb.RewardEvent{
609+
Role: eventsdb.RoleDevelopers.String(),
610+
Address: developers.Address,
611+
Amount: DevelopersReward.String(),
612+
ValidatorPubKey: validator.PubKey,
613+
ForCoin: 0,
614+
})
615+
}
616+
617+
validator.SetAccumReward(big.NewInt(0))
618+
619+
if remainder.Sign() != -1 {
620+
v.bus.App().AddTotalSlashed(remainder)
621+
} else {
622+
panic(fmt.Sprintf("Negative remainder: %s", remainder.String()))
623+
}
624+
}
625+
626+
return moreRewards
627+
}
628+
629+
// PayRewardsV4
630+
// Deprecated
435631
func (v *Validators) PayRewardsV4(height uint64, period int64) (moreRewards *big.Int) {
436632
moreRewards = big.NewInt(0)
437633

0 commit comments

Comments
 (0)