consensus/ubqhash: refactor CalcBaseBlockReward; Move block reward stepdown block & reward definitions to params.ChainConfig.Ubqhash.MonetaryPolicy (definable via custom genesis)

This commit is contained in:
Luke Williams 2019-12-21 16:48:56 +01:00
parent a46055e8ce
commit fbc1784ff7
3 changed files with 118 additions and 56 deletions

View file

@ -38,9 +38,9 @@ import (
// Ubqhash proof-of-work protocol constants.
var (
blockReward *big.Int = big.NewInt(8e+18) // Block reward in wei for successfully mining a block
maxUncles = 2 // Maximum number of uncles allowed in a single block
allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks
// blockReward *big.Int = big.NewInt(8e+18) // Block reward in wei for successfully mining a block
maxUncles = 2 // Maximum number of uncles allowed in a single block
allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks
)
// Diff algo constants.
@ -650,34 +650,21 @@ 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)
// CalcBaseBlockReward calculates the base block reward as per the ubiq monetary
// policy.
func CalcBaseBlockReward(config *params.UbqhashConfig, height *big.Int) *big.Int {
reward := new(big.Int).Set(config.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)
for _, step := range config.MonetaryPolicy {
if height.Cmp(step.Block) > 0 {
reward = step.Reward
}
}
return reward
}
// CalcUncleBlockReward calculates the uncle miner reward based on depth.
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
@ -697,11 +684,13 @@ func CalcUncleBlockReward(config *params.ChainConfig, blockHeight *big.Int, uncl
// 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) {
ubqhashConfig := config.Ubqhash
// block reward (miner)
reward := CalcBaseBlockReward(header.Number)
reward := CalcBaseBlockReward(ubqhashConfig, header.Number)
// Uncle reward step down fix. (activates along-side byzantium)
ufixReward := new(big.Int).Set(blockReward)
ufixReward := new(big.Int).Set(ubqhashConfig.BlockReward)
if config.IsByzantium(header.Number) {
ufixReward = reward
}

View file

@ -17,20 +17,22 @@
package ubqhash
import (
"encoding/json"
// "encoding/json"
"math/big"
"os"
"path/filepath"
// "os"
// "path/filepath"
"testing"
"github.com/ubiq/go-ubiq/common/math"
"github.com/ubiq/go-ubiq/core"
"github.com/ubiq/go-ubiq/core/types"
"github.com/ubiq/go-ubiq/core/vm"
"github.com/ubiq/go-ubiq/ethdb"
// "github.com/ubiq/go-ubiq/common/math"
// "github.com/ubiq/go-ubiq/core"
// "github.com/ubiq/go-ubiq/core/types"
// "github.com/ubiq/go-ubiq/core/vm"
// "github.com/ubiq/go-ubiq/ethdb"
"github.com/ubiq/go-ubiq/params"
)
// TODO: write new difficulty tests
/*
type diffTest struct {
ParentTimestamp uint64
ParentDifficulty *big.Int
@ -101,73 +103,74 @@ func TestCalcDifficulty(t *testing.T) {
t.Error(name, "failed. Expected", test.CurrentDifficulty, "and calculated", diff)
}
}
}
}*/
func TestCalcBaseBlockReward(t *testing.T) {
reward := CalcBaseBlockReward(big.NewInt(1))
config := *params.MainnetChainConfig
reward := CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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))
reward = CalcBaseBlockReward(config.Ubqhash, 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)
}

View file

@ -43,8 +43,39 @@ var (
ConstantinopleBlock: big.NewInt(math.MaxInt64),
PetersburgBlock: big.NewInt(math.MaxInt64),
Ubqhash: &UbqhashConfig{
BlockReward: big.NewInt(8e+18), // 8 UBQ in wei
DigishieldModBlock: big.NewInt(4088),
FluxBlock: big.NewInt(8000),
MonetaryPolicy: []UbqhashMPStep{
UbqhashMPStep{
Block: big.NewInt(358363),
Reward: big.NewInt(7e+18),
},
UbqhashMPStep{
Block: big.NewInt(716727),
Reward: big.NewInt(6e+18),
},
UbqhashMPStep{
Block: big.NewInt(1075090),
Reward: big.NewInt(5e+18),
},
UbqhashMPStep{
Block: big.NewInt(1433454),
Reward: big.NewInt(4e+18),
},
UbqhashMPStep{
Block: big.NewInt(1791818),
Reward: big.NewInt(3e+18),
},
UbqhashMPStep{
Block: big.NewInt(2150181),
Reward: big.NewInt(2e+18),
},
UbqhashMPStep{
Block: big.NewInt(2508545),
Reward: big.NewInt(1e+18),
},
},
},
}
@ -69,8 +100,39 @@ var (
ConstantinopleBlock: big.NewInt(math.MaxInt64),
PetersburgBlock: big.NewInt(math.MaxInt64),
Ubqhash: &UbqhashConfig{
BlockReward: big.NewInt(8e+18), // 8 UBQ in wei
DigishieldModBlock: big.NewInt(4088),
FluxBlock: big.NewInt(8000),
MonetaryPolicy: []UbqhashMPStep{
UbqhashMPStep{
Block: big.NewInt(358363),
Reward: big.NewInt(7e+18),
},
UbqhashMPStep{
Block: big.NewInt(716727),
Reward: big.NewInt(6e+18),
},
UbqhashMPStep{
Block: big.NewInt(1075090),
Reward: big.NewInt(5e+18),
},
UbqhashMPStep{
Block: big.NewInt(1433454),
Reward: big.NewInt(4e+18),
},
UbqhashMPStep{
Block: big.NewInt(1791818),
Reward: big.NewInt(3e+18),
},
UbqhashMPStep{
Block: big.NewInt(2150181),
Reward: big.NewInt(2e+18),
},
UbqhashMPStep{
Block: big.NewInt(2508545),
Reward: big.NewInt(1e+18),
},
},
},
}
@ -88,7 +150,7 @@ var (
//
// This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields.
AllUbqhashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &UbqhashConfig{DigishieldModBlock: big.NewInt(0), FluxBlock: big.NewInt(0)}, nil}
AllUbqhashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &UbqhashConfig{big.NewInt(0), big.NewInt(0), big.NewInt(0), []UbqhashMPStep{}}, nil}
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ubiq core developers into the Clique consensus.
@ -97,7 +159,7 @@ var (
// adding flags to the config to also have to set these fields.
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(UbqhashConfig), nil}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &UbqhashConfig{big.NewInt(0), big.NewInt(0), big.NewInt(0), []UbqhashMPStep{}}, nil}
TestRules = TestChainConfig.Rules(new(big.Int))
)
@ -140,10 +202,18 @@ type ChainConfig struct {
Clique *CliqueConfig `json:"clique,omitempty"`
}
// Ubqhash monetary policy reward step
type UbqhashMPStep struct {
Block *big.Int `json:"block"`
Reward *big.Int `json:"reward"`
}
// UbqhashConfig is the consensus engine configs for proof-of-work based sealing.
type UbqhashConfig struct {
DigishieldModBlock *big.Int `json:"digishieldModBlock"` // Block to activate the DigiShield V3 mod
FluxBlock *big.Int `json:"fluxBlock"` // Block to activate the Flux difficulty algorithm (must be > DigiShieldModBlock)
BlockReward *big.Int `json:"blockReward"` // Initial block reward in wei for mining a block
DigishieldModBlock *big.Int `json:"digishieldModBlock,omitempty"` // Block to activate the DigiShield V3 mod
FluxBlock *big.Int `json:"fluxBlock"` // Block to activate the Flux difficulty algorithm
MonetaryPolicy []UbqhashMPStep `json:"monetaryPolicy"` // Blocks to step the block reward down
}
// String implements the stringer interface, returning the consensus engine details.