72 lines
2.4 KiB
Go
72 lines
2.4 KiB
Go
package block
|
|
|
|
import (
|
|
"git.gammaspectra.live/P2Pool/consensus/v3/monero"
|
|
"lukechampine.com/uint128"
|
|
"math"
|
|
"math/bits"
|
|
)
|
|
|
|
func GetBaseReward(alreadyGeneratedCounts uint64) uint64 {
|
|
result := (^alreadyGeneratedCounts) >> 19
|
|
if result < monero.TailEmissionReward {
|
|
return monero.TailEmissionReward
|
|
}
|
|
return result
|
|
}
|
|
|
|
// GetBlockReward
|
|
// Taken from https://github.com/monero-project/monero/blob/b0bf49a65a38ceb1acfbc8e17f40e63383ac140d/src/cryptonote_basic/cryptonote_basic_impl.cpp#L83
|
|
func GetBlockReward(medianWeight, currentBlockWeight, alreadyGeneratedCoins uint64, version uint8) (reward uint64) {
|
|
const DIFFICULTY_TARGET_V1 = 60 // seconds - before first fork
|
|
const DIFFICULTY_TARGET_V2 = 120 // seconds
|
|
const EMISSION_SPEED_FACTOR_PER_MINUTE = 20
|
|
const FINAL_SUBSIDY_PER_MINUTE = 300000000000 // 3 * pow(10, 11)
|
|
const MONEY_SUPPLY = math.MaxUint64
|
|
const CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 = 20000 //size of block (bytes) after which reward for block calculated using block size - before first fork
|
|
const CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 = 60000 //size of block (bytes) after which reward for block calculated using block size
|
|
const CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5 = 300000 //size of block (bytes) after which reward for block calculated using block size - second change, from v5
|
|
|
|
target := uint64(DIFFICULTY_TARGET_V2)
|
|
if version < 2 {
|
|
target = DIFFICULTY_TARGET_V1
|
|
}
|
|
|
|
targetMinutes := target / 60
|
|
|
|
emissionSpeedFactor := EMISSION_SPEED_FACTOR_PER_MINUTE - (targetMinutes - 1)
|
|
|
|
baseReward := (MONEY_SUPPLY - alreadyGeneratedCoins) >> emissionSpeedFactor
|
|
if baseReward < (FINAL_SUBSIDY_PER_MINUTE * targetMinutes) {
|
|
baseReward = FINAL_SUBSIDY_PER_MINUTE * targetMinutes
|
|
}
|
|
|
|
fullRewardZone := func(version uint8) uint64 {
|
|
// From get_min_block_weight()
|
|
if version < 2 {
|
|
return CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1
|
|
}
|
|
if version < 5 {
|
|
return CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2
|
|
}
|
|
return CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5
|
|
}(version)
|
|
|
|
//make it soft
|
|
if medianWeight < fullRewardZone {
|
|
medianWeight = fullRewardZone
|
|
}
|
|
|
|
if currentBlockWeight <= medianWeight {
|
|
return baseReward
|
|
}
|
|
|
|
if currentBlockWeight > 2*medianWeight {
|
|
//Block cumulative weight is too big
|
|
return 0
|
|
}
|
|
|
|
hi, lo := bits.Mul64(baseReward, (2*medianWeight-currentBlockWeight)*currentBlockWeight)
|
|
|
|
return uint128.New(lo, hi).Div64(medianWeight).Div64(medianWeight).Lo
|
|
}
|