You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.5 KiB

  1. package emission
  2. import "fmt"
  3. import "math/big"
  4. import "github.com/deroproject/derosuite/config"
  5. // the logic is same as cryptonote_basic_impl.cpp
  6. // this file controls the logic for emission of coins at each height
  7. // calculates block reward
  8. func GetBlockReward(bl_median_size uint64,
  9. bl_current_size uint64,
  10. already_generated_coins uint64,
  11. hard_fork_version uint64,
  12. fee uint64) (reward uint64) {
  13. target := config.COIN_DIFFICULTY_TARGET
  14. target_minutes := target / 60
  15. emission_speed_factor := config.COIN_EMISSION_SPEED_FACTOR - (target_minutes - 1)
  16. // handle special cases
  17. switch already_generated_coins {
  18. case 0:
  19. reward = 1000000000000 // give 1 DERO to genesis, but we gave 35 due to a silly typo, so continue as is
  20. return reward
  21. case 1000000000000:
  22. reward = 2000000 * 1000000000000 // give the developers initial premine, while keeping the, into account and respecting transparancy
  23. return reward
  24. }
  25. base_reward := (config.COIN_MONEY_SUPPLY - already_generated_coins) >> emission_speed_factor
  26. if base_reward < (config.COIN_FINAL_SUBSIDY_PER_MINUTE * target_minutes) {
  27. base_reward = config.COIN_FINAL_SUBSIDY_PER_MINUTE * target_minutes
  28. }
  29. //full_reward_zone = get_min_block_size(version);
  30. full_reward_zone := config.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE
  31. if bl_median_size < full_reward_zone {
  32. bl_median_size = full_reward_zone
  33. }
  34. if bl_current_size <= bl_median_size {
  35. reward = base_reward
  36. fmt.Printf("Retunring base reward\n")
  37. return reward
  38. }
  39. // block is bigger than median size , we must calculate it
  40. if bl_current_size > 2*bl_median_size {
  41. //MERROR("Block cumulative size is too big: " << current_block_size << ", expected less than " << 2 * median_size);
  42. panic("Block size is too big\n")
  43. return
  44. }
  45. //panic("This mode of base reward calculation is not yet implemented\n")
  46. multiplicand := (2 * bl_median_size) - bl_current_size
  47. multiplicand = multiplicand * bl_current_size
  48. var big_base_reward, big_multiplicand, big_product, big_reward, big_median_size big.Int
  49. big_median_size.SetUint64(bl_median_size)
  50. big_base_reward.SetUint64(base_reward)
  51. big_multiplicand.SetUint64(multiplicand)
  52. big_product.Mul(&big_base_reward, &big_multiplicand)
  53. big_reward.Div(&big_product, &big_median_size)
  54. big_product.Set(&big_reward)
  55. big_reward.Div(&big_product, &big_median_size)
  56. // lower 64 bits contains the reward
  57. if !big_reward.IsUint64() {
  58. panic("GetBlockReward has issues\n")
  59. }
  60. reward_lo := big_reward.Uint64()
  61. if reward_lo > base_reward {
  62. panic("Reward must be less than base reward\n")
  63. }
  64. return reward_lo
  65. }