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. // Ubqhash proof-of-work protocol constants.
var ( var (
blockReward *big.Int = big.NewInt(8e+18) // Block reward in wei for successfully mining a block // 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 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 allowedFutureBlockTime = 15 * time.Second // Max time from current time allowed for blocks, before they're considered future blocks
) )
// Diff algo constants. // Diff algo constants.
@ -650,34 +650,21 @@ func (ubqhash *Ubqhash) SealHash(header *types.Header) (hash common.Hash) {
return hash return hash
} }
// Calculates the base block reward as per the ubiq monetary policy // CalcBaseBlockReward calculates the base block reward as per the ubiq monetary
func CalcBaseBlockReward(height *big.Int) *big.Int { // policy.
reward := new(big.Int).Set(blockReward) func CalcBaseBlockReward(config *params.UbqhashConfig, height *big.Int) *big.Int {
reward := new(big.Int).Set(config.BlockReward)
if height.Cmp(big.NewInt(358363)) > 0 { for _, step := range config.MonetaryPolicy {
reward = big.NewInt(7e+18) if height.Cmp(step.Block) > 0 {
} reward = step.Reward
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 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 { func CalcUncleBlockReward(config *params.ChainConfig, blockHeight *big.Int, uncleHeight *big.Int, blockReward *big.Int) *big.Int {
reward := new(big.Int) reward := new(big.Int)
// calculate reward based on depth // 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 // reward. The total reward consists of the static block reward and rewards for
// included uncles. The coinbase of each uncle block is also rewarded. // 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) { func accumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
ubqhashConfig := config.Ubqhash
// block reward (miner) // block reward (miner)
reward := CalcBaseBlockReward(header.Number) reward := CalcBaseBlockReward(ubqhashConfig, header.Number)
// Uncle reward step down fix. (activates along-side byzantium) // 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) { if config.IsByzantium(header.Number) {
ufixReward = reward ufixReward = reward
} }

View file

@ -17,20 +17,22 @@
package ubqhash package ubqhash
import ( import (
"encoding/json" // "encoding/json"
"math/big" "math/big"
"os" // "os"
"path/filepath" // "path/filepath"
"testing" "testing"
"github.com/ubiq/go-ubiq/common/math" // "github.com/ubiq/go-ubiq/common/math"
"github.com/ubiq/go-ubiq/core" // "github.com/ubiq/go-ubiq/core"
"github.com/ubiq/go-ubiq/core/types" // "github.com/ubiq/go-ubiq/core/types"
"github.com/ubiq/go-ubiq/core/vm" // "github.com/ubiq/go-ubiq/core/vm"
"github.com/ubiq/go-ubiq/ethdb" // "github.com/ubiq/go-ubiq/ethdb"
"github.com/ubiq/go-ubiq/params" "github.com/ubiq/go-ubiq/params"
) )
// TODO: write new difficulty tests
/*
type diffTest struct { type diffTest struct {
ParentTimestamp uint64 ParentTimestamp uint64
ParentDifficulty *big.Int ParentDifficulty *big.Int
@ -101,73 +103,74 @@ func TestCalcDifficulty(t *testing.T) {
t.Error(name, "failed. Expected", test.CurrentDifficulty, "and calculated", diff) t.Error(name, "failed. Expected", test.CurrentDifficulty, "and calculated", diff)
} }
} }
} }*/
func TestCalcBaseBlockReward(t *testing.T) { 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 { if reward.Cmp(big.NewInt(8e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 8 (start)", "failed. Expected", big.NewInt(8e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(8e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 8 (end)", "failed. Expected", big.NewInt(8e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(7e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 7 (start)", "failed. Expected", big.NewInt(7e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(7e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 7 (end)", "failed. Expected", big.NewInt(7e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(6e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 6 (start)", "failed. Expected", big.NewInt(6e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(6e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 6 (end)", "failed. Expected", big.NewInt(6e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(5e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 5 (start)", "failed. Expected", big.NewInt(5e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(5e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 5 (end)", "failed. Expected", big.NewInt(5e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(4e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 4 (start)", "failed. Expected", big.NewInt(4e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(4e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 4 (end)", "failed. Expected", big.NewInt(4e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(3e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 3 (start)", "failed. Expected", big.NewInt(3e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(3e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 3 (end)", "failed. Expected", big.NewInt(3e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(2e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 2 (start)", "failed. Expected", big.NewInt(2e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(2e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 2 (end)", "failed. Expected", big.NewInt(2e+18), "and calculated", reward) 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 { if reward.Cmp(big.NewInt(1e+18)) != 0 {
t.Error("TestCalcBaseBlockReward 1 (start)", "failed. Expected", big.NewInt(1e+18), "and calculated", reward) 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), ConstantinopleBlock: big.NewInt(math.MaxInt64),
PetersburgBlock: big.NewInt(math.MaxInt64), PetersburgBlock: big.NewInt(math.MaxInt64),
Ubqhash: &UbqhashConfig{ Ubqhash: &UbqhashConfig{
BlockReward: big.NewInt(8e+18), // 8 UBQ in wei
DigishieldModBlock: big.NewInt(4088), DigishieldModBlock: big.NewInt(4088),
FluxBlock: big.NewInt(8000), 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), ConstantinopleBlock: big.NewInt(math.MaxInt64),
PetersburgBlock: big.NewInt(math.MaxInt64), PetersburgBlock: big.NewInt(math.MaxInt64),
Ubqhash: &UbqhashConfig{ Ubqhash: &UbqhashConfig{
BlockReward: big.NewInt(8e+18), // 8 UBQ in wei
DigishieldModBlock: big.NewInt(4088), DigishieldModBlock: big.NewInt(4088),
FluxBlock: big.NewInt(8000), 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 // This configuration is intentionally not using keyed fields to force anyone
// adding flags to the config to also have to set these fields. // 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 // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
// and accepted by the Ubiq core developers into the Clique consensus. // 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. // 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}} 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)) TestRules = TestChainConfig.Rules(new(big.Int))
) )
@ -140,10 +202,18 @@ type ChainConfig struct {
Clique *CliqueConfig `json:"clique,omitempty"` 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. // UbqhashConfig is the consensus engine configs for proof-of-work based sealing.
type UbqhashConfig struct { type UbqhashConfig struct {
DigishieldModBlock *big.Int `json:"digishieldModBlock"` // Block to activate the DigiShield V3 mod BlockReward *big.Int `json:"blockReward"` // Initial block reward in wei for mining a block
FluxBlock *big.Int `json:"fluxBlock"` // Block to activate the Flux difficulty algorithm (must be > DigiShieldModBlock) 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. // String implements the stringer interface, returning the consensus engine details.