Skip to content

Commit

Permalink
unlocker: add monetary policies/reward logic for ethereum, ropsten & …
Browse files Browse the repository at this point in the history
…ubiq
  • Loading branch information
iquidus committed Jan 11, 2021
1 parent 89dfb14 commit 03f5a2d
Showing 1 changed file with 166 additions and 26 deletions.
192 changes: 166 additions & 26 deletions payouts/unlocker.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,41 @@ import (
)

type UnlockerConfig struct {
Enabled bool `json:"enabled"`
PoolFee float64 `json:"poolFee"`
PoolFeeAddress string `json:"poolFeeAddress"`
Donate bool `json:"donate"`
Depth int64 `json:"depth"`
ImmatureDepth int64 `json:"immatureDepth"`
KeepTxFees bool `json:"keepTxFees"`
Interval string `json:"interval"`
Daemon string `json:"daemon"`
Timeout string `json:"timeout"`
Ecip1017FBlock int64 `json:"ecip1017FBlock"`
Ecip1017EraRounds *big.Int `json:"ecip1017EraRounds"`
Enabled bool `json:"enabled"`
PoolFee float64 `json:"poolFee"`
PoolFeeAddress string `json:"poolFeeAddress"`
Donate bool `json:"donate"`
Depth int64 `json:"depth"`
ImmatureDepth int64 `json:"immatureDepth"`
KeepTxFees bool `json:"keepTxFees"`
Interval string `json:"interval"`
Daemon string `json:"daemon"`
Timeout string `json:"timeout"`
Ecip1017FBlock int64 `json:"ecip1017FBlock"`
Ecip1017EraRounds *big.Int `json:"ecip1017EraRounds"`
ByzantiumFBlock *big.Int `json:"byzantiumFBlock"`
ConstantinopleFBlock *big.Int `json:"constantinopleFBlock"`
Network string `json:"network"`
}

const minDepth = 16

// params for etchash
var homesteadReward = math.MustParseBig256("5000000000000000000")
var disinflationRateQuotient = big.NewInt(4) // Disinflation rate quotient for ECIP1017
var disinflationRateDivisor = big.NewInt(5) // Disinflation rate divisor for ECIP1017
// params for ethash
var frontierBlockReward = big.NewInt(5e+18)
var byzantiumBlockReward = big.NewInt(3e+18)
var constantinopleBlockReward = big.NewInt(2e+18)

// params for ubqhash
var ubiqStartReward = big.NewInt(8e+18)

// misc consts
var big32 = big.NewInt(32)
var big8 = big.NewInt(8)

var homesteadReward = math.MustParseBig256("5000000000000000000")
var big2 = big.NewInt(2)

type BlockUnlocker struct {
config *UnlockerConfig
Expand All @@ -47,17 +60,29 @@ type BlockUnlocker struct {
lastFail error
}

func NewBlockUnlocker(cfg *UnlockerConfig, backend *storage.RedisClient, network *string) *BlockUnlocker {
if *network == "classic" {
func NewBlockUnlocker(cfg *UnlockerConfig, backend *storage.RedisClient, network string) *BlockUnlocker {
// determine which monetary policy to use based on network
// configure any reward params if needed.
if network == "classic" {
cfg.Ecip1017FBlock = 5000000
cfg.Ecip1017EraRounds = big.NewInt(5000000)
} else if *network == "mordor" {
} else if network == "mordor" {
cfg.Ecip1017FBlock = 0
cfg.Ecip1017EraRounds = big.NewInt(2000000)
} else if network == "ethereum" {
cfg.ByzantiumFBlock = big.NewInt(4370000)
cfg.ConstantinopleFBlock = big.NewInt(7280000)
} else if network == "ropsten" {
cfg.ByzantiumFBlock = big.NewInt(1700000)
cfg.ConstantinopleFBlock = big.NewInt(4230000)
} else if network == "ubiq" {
// nothing needs configuring here, simply proceed.
} else {
log.Fatalln("Invalid network set", network)
}

cfg.Network = network

if len(cfg.PoolFeeAddress) != 0 && !util.IsValidHexAddress(cfg.PoolFeeAddress) {
log.Fatalln("Invalid poolFeeAddress", cfg.PoolFeeAddress)
}
Expand Down Expand Up @@ -226,13 +251,31 @@ func (u *BlockUnlocker) handleBlock(block *rpc.GetBlockReply, candidate *storage
return err
}
candidate.Height = correctHeight
era := GetBlockEra(big.NewInt(candidate.Height), u.config.Ecip1017EraRounds)
reward := getConstReward(era)

// Add reward for including uncles
uncleReward := getRewardForUncle(reward)
rewardForUncles := big.NewInt(0).Mul(uncleReward, big.NewInt(int64(len(block.Uncles))))
reward.Add(reward, rewardForUncles)
var reward *big.Int = big.NewInt(0)
if u.config.Network == "classic" || u.config.Network == "mordor" {
era := GetBlockEra(big.NewInt(candidate.Height), u.config.Ecip1017EraRounds)
reward = getConstReward(era)
// Add reward for including uncles
uncleReward := getRewardForUncle(reward)
rewardForUncles := big.NewInt(0).Mul(uncleReward, big.NewInt(int64(len(block.Uncles))))
reward.Add(reward, rewardForUncles)

} else if u.config.Network == "ubiq" {
reward = getConstRewardUbiq(candidate.Height)
// Add reward for including uncles
uncleReward := new(big.Int).Div(reward, big32)
rewardForUncles := big.NewInt(0).Mul(uncleReward, big.NewInt(int64(len(block.Uncles))))
reward.Add(reward, rewardForUncles)

} else if u.config.Network == "ethereum" || u.config.Network == "ropsten" {
reward = getConstRewardEthereum(candidate.Height, u.config)
// Add reward for including uncles
uncleReward := new(big.Int).Div(reward, big32)
rewardForUncles := big.NewInt(0).Mul(uncleReward, big.NewInt(int64(len(block.Uncles))))
reward.Add(reward, rewardForUncles)
} else {
log.Fatalln("Invalid network set", u.config.Network)
}

// Add TX fees
extraTxReward, err := u.getExtraRewardForTx(block)
Expand All @@ -248,6 +291,7 @@ func (u *BlockUnlocker) handleBlock(block *rpc.GetBlockReply, candidate *storage
candidate.Orphan = false
candidate.Hash = block.Hash
candidate.Reward = reward

return nil
}

Expand All @@ -256,8 +300,15 @@ func handleUncle(height int64, uncle *rpc.GetBlockReply, candidate *storage.Bloc
if err != nil {
return err
}
era := GetBlockEra(big.NewInt(height), cfg.Ecip1017EraRounds)
reward := getUncleReward(new(big.Int).SetInt64(uncleHeight), new(big.Int).SetInt64(height), era, getConstReward(era))
var reward *big.Int = big.NewInt(0)
if cfg.Network == "classic" || cfg.Network == "mordor" {
era := GetBlockEra(big.NewInt(height), cfg.Ecip1017EraRounds)
reward = getUncleReward(new(big.Int).SetInt64(uncleHeight), new(big.Int).SetInt64(height), era, getConstReward(era))
} else if cfg.Network == "ubiq" {
reward = getUncleRewardUbiq(new(big.Int).SetInt64(uncleHeight), new(big.Int).SetInt64(height), getConstRewardUbiq(height))
} else if cfg.Network == "ethereum" || cfg.Network == "ropsten" {
reward = getUncleRewardEthereum(new(big.Int).SetInt64(uncleHeight), new(big.Int).SetInt64(height), getConstRewardUbiq(height))
}
candidate.Height = height
candidate.UncleHeight = uncleHeight
candidate.Orphan = false
Expand Down Expand Up @@ -551,16 +602,19 @@ func GetBlockEra(blockNum, eraLength *big.Int) *big.Int {
return new(big.Int).Sub(d, dremainder)
}

// etchash
func getConstReward(era *big.Int) *big.Int {
var blockReward = homesteadReward
wr := GetBlockWinnerRewardByEra(era, blockReward)
return wr
}

//etchash
func getRewardForUncle(blockReward *big.Int) *big.Int {
return new(big.Int).Div(blockReward, big32) //return new(big.Int).Div(reward, new(big.Int).SetInt64(32))
}

// etchash
func getUncleReward(uHeight *big.Int, height *big.Int, era *big.Int, reward *big.Int) *big.Int {
// Era 1 (index 0):
// An extra reward to the winning miner for including uncles as part of the block, in the form of an extra 1/32 (0.15625ETC) per uncle included, up to a maximum of two (2) uncles.
Expand All @@ -576,6 +630,92 @@ func getUncleReward(uHeight *big.Int, height *big.Int, era *big.Int, reward *big
return getRewardForUncle(reward)
}

// ubqhash
func getConstRewardUbiq(height int64) *big.Int {
// Rewards
reward := new(big.Int).Set(ubiqStartReward)
headerNumber := big.NewInt(height)

if headerNumber.Cmp(big.NewInt(358363)) > 0 {
reward = big.NewInt(7e+18)
// Year 1
}
if headerNumber.Cmp(big.NewInt(716727)) > 0 {
reward = big.NewInt(6e+18)
// Year 2
}
if headerNumber.Cmp(big.NewInt(1075090)) > 0 {
reward = big.NewInt(5e+18)
// Year 3
}
if headerNumber.Cmp(big.NewInt(1433454)) > 0 {
reward = big.NewInt(4e+18)
// Year 4
}
if headerNumber.Cmp(big.NewInt(1791818)) > 0 {
reward = big.NewInt(3e+18)
// Year 5
}
if headerNumber.Cmp(big.NewInt(2150181)) > 0 {
reward = big.NewInt(2e+18)
// Year 6
}
if headerNumber.Cmp(big.NewInt(2508545)) > 0 {
reward = big.NewInt(1e+18)
// Year 7
}

return reward
}

// ubqhash
func getUncleRewardUbiq(uHeight *big.Int, height *big.Int, reward *big.Int) *big.Int {

r := new(big.Int)

r.Add(uHeight, big2)
r.Sub(r, height)
r.Mul(r, reward)
r.Div(r, big2)
if r.Cmp(big.NewInt(0)) < 0 {
// blocks older than the previous block are not rewarded
r = big.NewInt(0)
}

return r
}

// ethash
func getConstRewardEthereum(height int64, cfg *UnlockerConfig) *big.Int {
// Select the correct block reward based on chain progression
blockReward := frontierBlockReward
headerNumber := big.NewInt(height)
if cfg.ByzantiumFBlock.Cmp(headerNumber) <= 0 {
blockReward = byzantiumBlockReward
}
if cfg.ConstantinopleFBlock.Cmp(headerNumber) <= 0 {
blockReward = constantinopleBlockReward
}
// Accumulate the rewards for the miner and any included uncles
reward := new(big.Int).Set(blockReward)
return reward
}

// ethash
func getUncleRewardEthereum(uHeight *big.Int, height *big.Int, reward *big.Int) *big.Int {
r := new(big.Int)
r.Add(uHeight, big8)
r.Sub(r, height)
r.Mul(r, reward)
r.Div(r, big8)
if r.Cmp(big.NewInt(0)) < 0 {
r = big.NewInt(0)
}

return r
}

// ethash, etchash, ubqhash
func (u *BlockUnlocker) getExtraRewardForTx(block *rpc.GetBlockReply) (*big.Int, error) {
amount := new(big.Int)

Expand Down

0 comments on commit 03f5a2d

Please sign in to comment.