mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
feat: fixed reward per node (per capita)
This commit is contained in:
parent
84ae914350
commit
6bac06b1e7
3 changed files with 42 additions and 60 deletions
|
|
@ -224,21 +224,21 @@ func TestHookRewardAfterUpgrade(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
result := reward["rewards"].(map[common.Address]interface{})
|
||||
assert.Equal(t, 2, len(result))
|
||||
// two signing account, 3 txs, reward is split by 1:2 (total reward is 250...000)
|
||||
// two signing account, both get fixed reward
|
||||
for addr, x := range result {
|
||||
if addr == acc1Addr {
|
||||
r := x.(map[common.Address]*big.Int)
|
||||
owner := state.GetCandidateOwner(parentState, addr)
|
||||
a, _ := big.NewInt(0).SetString("299999999999999999998", 10)
|
||||
a, _ := big.NewInt(0).SetString("450000000000000000000", 10)
|
||||
assert.Zero(t, a.Cmp(r[owner]), "real reward is", r[owner])
|
||||
b, _ := big.NewInt(0).SetString("33333333333333333333", 10)
|
||||
b, _ := big.NewInt(0).SetString("50000000000000000000", 10)
|
||||
assert.Zero(t, b.Cmp(r[config.XDPoS.FoudationWalletAddr]), "real reward is", r[config.XDPoS.FoudationWalletAddr])
|
||||
} else if addr == signer {
|
||||
r := x.(map[common.Address]*big.Int)
|
||||
owner := state.GetCandidateOwner(parentState, addr)
|
||||
a, _ := big.NewInt(0).SetString("149999999999999999999", 10)
|
||||
a, _ := big.NewInt(0).SetString("450000000000000000000", 10)
|
||||
assert.Zero(t, a.Cmp(r[owner]), "real reward is", r[owner])
|
||||
b, _ := big.NewInt(0).SetString("16666666666666666666", 10)
|
||||
b, _ := big.NewInt(0).SetString("50000000000000000000", 10)
|
||||
assert.Zero(t, b.Cmp(r[config.XDPoS.FoudationWalletAddr]), "real reward is", r[config.XDPoS.FoudationWalletAddr])
|
||||
} else {
|
||||
assert.Fail(t, "wrong reward")
|
||||
|
|
@ -262,22 +262,22 @@ func TestHookRewardAfterUpgrade(t *testing.T) {
|
|||
// only protector1 and 2 has signingtx.
|
||||
|
||||
resultProtector := reward["rewardsProtector"].(map[common.Address]interface{})
|
||||
// 2 protector and split by 1:2
|
||||
// 2 protector both get fixed reward
|
||||
assert.Equal(t, 2, len(resultProtector))
|
||||
for addr, x := range resultProtector {
|
||||
if addr == protector1Addr {
|
||||
r := x.(map[common.Address]*big.Int)
|
||||
owner := state.GetCandidateOwner(parentState, addr)
|
||||
a, _ := big.NewInt(0).SetString("119999999999999999999", 10)
|
||||
a, _ := big.NewInt(0).SetString("360000000000000000000", 10)
|
||||
assert.Zero(t, a.Cmp(r[owner]), "real reward is", r[owner])
|
||||
b, _ := big.NewInt(0).SetString("13333333333333333333", 10)
|
||||
b, _ := big.NewInt(0).SetString("40000000000000000000", 10)
|
||||
assert.Zero(t, b.Cmp(r[config.XDPoS.FoudationWalletAddr]), "real reward is", r[config.XDPoS.FoudationWalletAddr])
|
||||
} else if addr == protector2Addr {
|
||||
r := x.(map[common.Address]*big.Int)
|
||||
owner := state.GetCandidateOwner(parentState, addr)
|
||||
a, _ := big.NewInt(0).SetString("239999999999999999999", 10)
|
||||
a, _ := big.NewInt(0).SetString("360000000000000000000", 10)
|
||||
assert.Zero(t, a.Cmp(r[owner]), "real reward is", r[owner])
|
||||
b, _ := big.NewInt(0).SetString("26666666666666666666", 10)
|
||||
b, _ := big.NewInt(0).SetString("40000000000000000000", 10)
|
||||
assert.Zero(t, b.Cmp(r[config.XDPoS.FoudationWalletAddr]), "real reward is", r[config.XDPoS.FoudationWalletAddr])
|
||||
} else {
|
||||
assert.Fail(t, "wrong reward")
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
|||
return nil, err
|
||||
}
|
||||
// Add reward for coin holders.
|
||||
voterResults := make(map[common.Address]interface{})
|
||||
rewardResults := make(map[common.Address]interface{})
|
||||
for signer, calcReward := range rewardSigners {
|
||||
rewards, err := contracts.CalculateRewardForHolders(foundationWalletAddr, parentState, signer, calcReward, number)
|
||||
if err != nil {
|
||||
|
|
@ -227,13 +227,12 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
|||
stateBlock.AddBalance(holder, reward)
|
||||
}
|
||||
}
|
||||
voterResults[signer] = rewards
|
||||
rewardResults[signer] = rewards
|
||||
}
|
||||
rewardsMap["rewards"] = voterResults
|
||||
rewardsMap["rewards"] = rewardResults
|
||||
} else {
|
||||
rewardsMap["signersProtector"] = signers[ProtectorNodeBeneficiary]
|
||||
rewardsMap["signersObserver"] = signers[ObserverNodeBeneficiary]
|
||||
epochRewardTotal := new(big.Int).SetUint64(currentConfig.MasternodeReward + currentConfig.ProtectorReward + currentConfig.ObserverReward)
|
||||
type rewardWithType struct {
|
||||
r uint64
|
||||
t Beneficiary
|
||||
|
|
@ -245,25 +244,14 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
|||
{currentConfig.ObserverReward, ObserverNodeBeneficiary, "rewardsObserver"},
|
||||
} {
|
||||
originalReward := new(big.Int).Mul(new(big.Int).SetUint64(rwt.r), new(big.Int).SetUint64(params.Ether))
|
||||
chainReward := new(big.Int)
|
||||
if !chain.Config().IsTIPEpochHalving(header.Number) {
|
||||
chainReward = util.RewardInflation(chain, originalReward, number, common.BlocksPerYear)
|
||||
} else {
|
||||
halvingSupply := big.NewInt(9000000000) // TODO use config.halvingSupply
|
||||
_, epochNum, err := adaptor.EngineV2.IsEpochSwitch(header)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
epochSinceHalving := epochNum // TODO Minus config.epochHalvingOnset
|
||||
chainReward = util.RewardHalving(originalReward, epochRewardTotal, halvingSupply, epochSinceHalving)
|
||||
}
|
||||
rewardSigners, err := CalculateRewardForSigner(chainReward, signers[rwt.t])
|
||||
chainReward := util.RewardInflation(chain, originalReward, number, common.BlocksPerYear)
|
||||
rewardSigners, err := CalculateRewardForSignerFixed(chainReward, signers[rwt.t])
|
||||
if err != nil {
|
||||
log.Error("[HookReward] Fail to calculate reward type 0 for masternode, 1 for protector, 2 for observer", "error", err, "type", rwt.t)
|
||||
return nil, err
|
||||
}
|
||||
// Add reward for coin holders.
|
||||
voterResults := make(map[common.Address]interface{})
|
||||
rewardResults := make(map[common.Address]interface{})
|
||||
for signer, calcReward := range rewardSigners {
|
||||
rewards, err := contracts.CalculateRewardForHolders(foundationWalletAddr, parentState, signer, calcReward, number)
|
||||
if err != nil {
|
||||
|
|
@ -275,9 +263,9 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
|||
stateBlock.AddBalance(holder, reward)
|
||||
}
|
||||
}
|
||||
voterResults[signer] = rewards
|
||||
rewardResults[signer] = rewards
|
||||
}
|
||||
rewardsMap[rwt.key] = voterResults
|
||||
rewardsMap[rwt.key] = rewardResults
|
||||
}
|
||||
}
|
||||
log.Debug("Time Calculated HookReward ", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start)))
|
||||
|
|
@ -356,7 +344,7 @@ func GetSigningTxCount(c *XDPoS.XDPoS, chain consensus.ChainReader, header *type
|
|||
}
|
||||
if len(protector) < currentConfig.MaxProtectorNodes {
|
||||
protector = append(protector, node.Address)
|
||||
} else {
|
||||
} else if len(observer) < currentConfig.MaxObverserNodes {
|
||||
observer = append(observer, node.Address)
|
||||
}
|
||||
}
|
||||
|
|
@ -457,29 +445,21 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
|
|||
return resultSigners, nil
|
||||
}
|
||||
|
||||
// func TestRewardBeZero(t *testing.T) {
|
||||
// billion := big.NewInt(1000000000)
|
||||
// epochRewardTotal := big.NewInt(16000)
|
||||
// epochRewardTotal.Mul(epochRewardTotal, billion)
|
||||
// epochReward1 := big.NewInt(10000)
|
||||
// epochReward1.Mul(epochReward1, billion)
|
||||
// epochReward2 := big.NewInt(4000)
|
||||
// epochReward2.Mul(epochReward2, billion)
|
||||
// epochReward3 := big.NewInt(2000)
|
||||
// epochReward3.Mul(epochReward3, billion)
|
||||
// // 45 Billion - 39 Billion XDC (1 XDC = 10^9 wei)
|
||||
// halvingSupply := big.NewInt(6000000000)
|
||||
// halvingSupply.Mul(halvingSupply, billion)
|
||||
// sum := big.NewInt(0)
|
||||
// for i := uint64(0); i < 30000000; i++ {
|
||||
// r := new(big.Int).Add(RewardHalving(epochReward1, epochRewardTotal, halvingSupply, i), RewardHalving(epochReward2, epochRewardTotal, halvingSupply, i))
|
||||
// r.Add(r, RewardHalving(epochReward3, epochRewardTotal, halvingSupply, i))
|
||||
// if r.BitLen() == 0 {
|
||||
// t.Log("reward be 0 at i=", i) // reward be 0 at i= 11225088, wich is more than 200 years in the future
|
||||
// break
|
||||
// }
|
||||
// sum.Add(sum, r)
|
||||
// }
|
||||
// t.Log("sum", sum) // sum 5999999999982635022, which is less than total, and never reach totoal
|
||||
// assert.True(t, sum.Cmp(halvingSupply) < 0)
|
||||
// }
|
||||
// Calculate reward for signers with fixed reward.
|
||||
func CalculateRewardForSignerFixed(chainReward *big.Int, signers map[common.Address]*RewardLog) (map[common.Address]*big.Int, error) {
|
||||
resultSigners := make(map[common.Address]*big.Int)
|
||||
// Add reward for signers.
|
||||
for signer, rLog := range signers {
|
||||
// Add reward for signer.
|
||||
calcReward := new(big.Int).SetBytes(chainReward.Bytes())
|
||||
rLog.Reward = calcReward
|
||||
resultSigners[signer] = calcReward
|
||||
}
|
||||
|
||||
log.Info("Signers data", "percapitaReward", chainReward)
|
||||
for addr, signer := range signers {
|
||||
log.Debug("Signer reward", "signer", addr, "sign", signer.Sign, "reward", signer.Reward)
|
||||
}
|
||||
|
||||
return resultSigners, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ var (
|
|||
900: {
|
||||
MaxMasternodes: 20,
|
||||
MaxProtectorNodes: 17,
|
||||
MaxObverserNodes: 1,
|
||||
SwitchRound: 900,
|
||||
CertThreshold: 0.667,
|
||||
TimeoutSyncThreshold: 4,
|
||||
|
|
@ -454,15 +455,16 @@ type V2 struct {
|
|||
type V2Config struct {
|
||||
MaxMasternodes int `json:"maxMasternodes"` // v2 max masternodes
|
||||
MaxProtectorNodes int `json:"maxProtectorNodes"` // v2 max ProtectorNodes
|
||||
MaxObverserNodes int `json:"maxObserverNodes"` // v2 max ObserverNodes
|
||||
SwitchRound uint64 `json:"switchRound"` // v1 to v2 switch block number
|
||||
MinePeriod int `json:"minePeriod"` // Miner mine period to mine a block
|
||||
TimeoutSyncThreshold int `json:"timeoutSyncThreshold"` // send syncInfo after number of timeout
|
||||
TimeoutPeriod int `json:"timeoutPeriod"` // Duration in ms
|
||||
CertThreshold float64 `json:"certificateThreshold"` // Necessary number of messages from master nodes to form a certificate
|
||||
|
||||
MasternodeReward uint64 `json:"masternodeReward"` // Block reward for master nodes (core validators) - unit Ether
|
||||
ProtectorReward uint64 `json:"protectorReward"` // Block reward for protectors - unit Ether
|
||||
ObserverReward uint64 `json:"observerReward"` // Block reward for observer - unit Ether
|
||||
MasternodeReward uint64 `json:"masternodeReward"` // Block reward per master node (core validator) - unit Ether
|
||||
ProtectorReward uint64 `json:"protectorReward"` // Block reward per protector - unit Ether
|
||||
ObserverReward uint64 `json:"observerReward"` // Block reward per observer - unit Ether
|
||||
|
||||
ExpTimeoutConfig ExpTimeoutConfig `json:"expTimeoutConfig"`
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue