consensus/ubqhash: add CalcBaseBlockReward & CalcUncleBlockReward (with tests), refactor accumulateRewards

This commit is contained in:
Luke Williams 2019-12-18 21:49:51 +01:00
parent 29ee8e58ba
commit 8b1cff54b9
2 changed files with 168 additions and 45 deletions

View file

@ -703,62 +703,71 @@ func (ubqhash *Ubqhash) SealHash(header *types.Header) (hash common.Hash) {
return hash
}
// Calculates the base block reward as per the ubiq monetary policy
func CalcBaseBlockReward(height *big.Int) *big.Int {
reward := new(big.Int).Set(blockReward)
if height.Cmp(big.NewInt(358363)) > 0 {
reward = big.NewInt(7e+18)
}
if height.Cmp(big.NewInt(716727)) > 0 {
reward = big.NewInt(6e+18)
}
if height.Cmp(big.NewInt(1075090)) > 0 {
reward = big.NewInt(5e+18)
}
if height.Cmp(big.NewInt(1433454)) > 0 {
reward = big.NewInt(4e+18)
}
if height.Cmp(big.NewInt(1791818)) > 0 {
reward = big.NewInt(3e+18)
}
if height.Cmp(big.NewInt(2150181)) > 0 {
reward = big.NewInt(2e+18)
}
if height.Cmp(big.NewInt(2508545)) > 0 {
reward = big.NewInt(1e+18)
}
return reward
}
func CalcUncleBlockReward(config *params.ChainConfig, blockHeight *big.Int, uncleHeight *big.Int, blockReward *big.Int) *big.Int {
reward := new(big.Int)
// calculate reward based on depth
reward.Add(uncleHeight, big2)
reward.Sub(reward, blockHeight)
reward.Mul(reward, blockReward)
reward.Div(reward, big2)
// negative uncle reward fix. (activates along-side EIP158)
if config.IsEIP158(blockHeight) && reward.Cmp(big.NewInt(0)) < 0 {
reward = big.NewInt(0)
}
return reward
}
// AccumulateRewards credits the coinbase of the given block with the mining
// reward. The total reward consists of the static block reward and rewards for
// included uncles. The coinbase of each uncle block is also rewarded.
func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
reward := new(big.Int).Set(blockReward)
// block reward (miner)
reward := CalcBaseBlockReward(header.Number)
if header.Number.Cmp(big.NewInt(358363)) > 0 {
reward = big.NewInt(7e+18)
}
if header.Number.Cmp(big.NewInt(716727)) > 0 {
reward = big.NewInt(6e+18)
}
if header.Number.Cmp(big.NewInt(1075090)) > 0 {
reward = big.NewInt(5e+18)
}
if header.Number.Cmp(big.NewInt(1433454)) > 0 {
reward = big.NewInt(4e+18)
}
if header.Number.Cmp(big.NewInt(1791818)) > 0 {
reward = big.NewInt(3e+18)
}
if header.Number.Cmp(big.NewInt(2150181)) > 0 {
reward = big.NewInt(2e+18)
}
if header.Number.Cmp(big.NewInt(2508545)) > 0 {
reward = big.NewInt(1e+18)
}
// Uncle reward step down fix.
// Uncle reward step down fix. (activates along-side byzantium)
ufixReward := new(big.Int).Set(blockReward)
if config.IsByzantium(header.Number) {
ufixReward = reward
}
r := new(big.Int)
for _, uncle := range uncles {
r.Add(uncle.Number, big2)
r.Sub(r, header.Number)
r.Mul(r, ufixReward)
r.Div(r, big2)
if header.Number.Cmp(big.NewInt(10)) < 0 {
state.AddBalance(uncle.Coinbase, r)
r.Div(ufixReward, big32)
if r.Cmp(big.NewInt(0)) < 0 {
r = big.NewInt(0)
}
} else {
if r.Cmp(big.NewInt(0)) < 0 {
r = big.NewInt(0)
}
state.AddBalance(uncle.Coinbase, r)
r.Div(ufixReward, big32)
}
reward.Add(reward, r)
// uncle block miner reward (depth === 1 ? baseBlockReward * 0.5 : 0)
uncleReward := CalcUncleBlockReward(config, header.Number, uncle.Number, ufixReward)
// update uncle miner balance
state.AddBalance(uncle.Coinbase, uncleReward)
// include uncle bonus reward (baseBlockReward/32)
uncleReward.Div(ufixReward, big32)
reward.Add(reward, uncleReward)
}
// update block miner balance
state.AddBalance(header.Coinbase, reward)
}

View file

@ -102,3 +102,117 @@ func TestCalcDifficulty(t *testing.T) {
}
}
}
func TestCalcBaseBlockReward(t *testing.T) {
reward := CalcBaseBlockReward(big.NewInt(1))
if reward.Cmp(big.NewInt(8e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 8 (start)", "failed. Expected", big.NewInt(8e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(358363))
if reward.Cmp(big.NewInt(8e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 8 (end)", "failed. Expected", big.NewInt(8e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(358364))
if reward.Cmp(big.NewInt(7e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 7 (start)", "failed. Expected", big.NewInt(7e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(716727))
if reward.Cmp(big.NewInt(7e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 7 (end)", "failed. Expected", big.NewInt(7e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(716728))
if reward.Cmp(big.NewInt(6e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 6 (start)", "failed. Expected", big.NewInt(6e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(1075090))
if reward.Cmp(big.NewInt(6e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 6 (end)", "failed. Expected", big.NewInt(6e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(1075091))
if reward.Cmp(big.NewInt(5e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 5 (start)", "failed. Expected", big.NewInt(5e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(1433454))
if reward.Cmp(big.NewInt(5e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 5 (end)", "failed. Expected", big.NewInt(5e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(1433455))
if reward.Cmp(big.NewInt(4e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 4 (start)", "failed. Expected", big.NewInt(4e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(1791818))
if reward.Cmp(big.NewInt(4e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 4 (end)", "failed. Expected", big.NewInt(4e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(1791819))
if reward.Cmp(big.NewInt(3e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 3 (start)", "failed. Expected", big.NewInt(3e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(2150181))
if reward.Cmp(big.NewInt(3e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 3 (end)", "failed. Expected", big.NewInt(3e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(2150182))
if reward.Cmp(big.NewInt(2e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 2 (start)", "failed. Expected", big.NewInt(2e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(2508545))
if reward.Cmp(big.NewInt(2e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 2 (end)", "failed. Expected", big.NewInt(2e+18), "and calculated", reward)
}
reward = CalcBaseBlockReward(big.NewInt(2508546))
if reward.Cmp(big.NewInt(1e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 1 (start)", "failed. Expected", big.NewInt(1e+18), "and calculated", reward)
}
}
func TestCalcUncleBlockReward(t *testing.T) {
config := &params.ChainConfig{HomesteadBlock: big.NewInt(0), EIP158Block: big.NewInt(10)}
reward := big.NewInt(8e+18)
// depth 1
u := CalcUncleBlockReward(config, big.NewInt(5), big.NewInt(4), reward)
if u.Cmp(big.NewInt(4e+18)) != 0 {
t.Error("TestCalcUncleBlockReward 8", "failed. Expected", big.NewInt(4e+18), "and calculated", u)
}
// depth 2
u = CalcUncleBlockReward(config, big.NewInt(8), big.NewInt(6), reward)
if u.Cmp(big.NewInt(0)) != 0 {
t.Error("TestCalcUncleBlockReward 8", "failed. Expected", big.NewInt(0), "and calculated", u)
}
// depth 3 (before negative fix)
u = CalcUncleBlockReward(config, big.NewInt(8), big.NewInt(5), reward)
if u.Cmp(big.NewInt(-4e+18)) != 0 {
t.Error("TestCalcUncleBlockReward 8", "failed. Expected", big.NewInt(-4e+18), "and calculated", u)
}
// depth 3 (after negative fix)
u = CalcUncleBlockReward(config, big.NewInt(10), big.NewInt(7), reward)
if u.Cmp(big.NewInt(0)) != 0 {
t.Error("TestCalcUncleBlockReward 8", "failed. Expected", big.NewInt(0), "and calculated", u)
}
reward = big.NewInt(7e+18)
expected := big.NewInt(35e+17)
// depth 1 (after stepdown)
u = CalcUncleBlockReward(config, big.NewInt(8), big.NewInt(7), reward)
if u.Cmp(expected) != 0 {
t.Error("TestCalcUncleBlockReward 7", "failed. Expected", expected, "and calculated", u)
}
reward = big.NewInt(5e+18)
expected = big.NewInt(25e+17)
// depth 1 (after stepdown)
u = CalcUncleBlockReward(config, big.NewInt(8), big.NewInt(7), reward)
if u.Cmp(expected) != 0 {
t.Error("TestCalcUncleBlockReward 5", "failed. Expected", expected, "and calculated", u)
}
}