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.

100 lines
3.6 KiB

  1. // Copyright 2017-2018 DERO Project. All rights reserved.
  2. // Use of this source code in any form is governed by RESEARCH license.
  3. // license can be found in the LICENSE file.
  4. // GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8
  5. //
  6. //
  7. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
  8. // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  9. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  10. // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  12. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  13. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  14. // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  15. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16. package emission
  17. //import "fmt"
  18. import "math/big"
  19. import "github.com/deroproject/derosuite/config"
  20. //TODO trickling code is note implemented still, but we do NOT require it atleast for another 7-8 years
  21. // the logic is same as cryptonote_basic_impl.cpp
  22. // this file controls the logic for emission of coins at each height
  23. // calculates block reward
  24. func GetBlockReward(bl_median_size uint64,
  25. bl_current_size uint64,
  26. already_generated_coins uint64,
  27. hard_fork_version uint64,
  28. fee uint64) (reward uint64) {
  29. target := config.COIN_DIFFICULTY_TARGET
  30. target_minutes := target / 60
  31. emission_speed_factor := config.COIN_EMISSION_SPEED_FACTOR - (target_minutes - 1)
  32. // handle special cases
  33. switch already_generated_coins {
  34. case 0:
  35. reward = 1000000000000 // give 1 DERO to genesis, but we gave 35 due to a silly typo, so continue as is
  36. return reward
  37. case 1000000000000:
  38. reward = 2000000 * 1000000000000 // give the developers initial premine, while keeping the, into account and respecting transparancy
  39. return reward
  40. }
  41. base_reward := (config.COIN_MONEY_SUPPLY - already_generated_coins) >> emission_speed_factor
  42. if base_reward < (config.COIN_FINAL_SUBSIDY_PER_MINUTE * target_minutes) {
  43. base_reward = config.COIN_FINAL_SUBSIDY_PER_MINUTE * target_minutes
  44. }
  45. //full_reward_zone = get_min_block_size(version);
  46. full_reward_zone := config.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE
  47. if bl_median_size < full_reward_zone {
  48. bl_median_size = full_reward_zone
  49. }
  50. if bl_current_size <= bl_median_size {
  51. reward = base_reward
  52. return reward
  53. }
  54. // block is bigger than median size , we must calculate it
  55. if bl_current_size > 2*bl_median_size {
  56. //MERROR("Block cumulative size is too big: " << current_block_size << ", expected less than " << 2 * median_size);
  57. panic("Block size is too big\n")
  58. //return 0xffffffff00000000
  59. }
  60. //panic("This mode of base reward calculation is not yet implemented\n")
  61. multiplicand := (2 * bl_median_size) - bl_current_size
  62. multiplicand = multiplicand * bl_current_size
  63. var big_base_reward, big_multiplicand, big_product, big_reward, big_median_size big.Int
  64. big_median_size.SetUint64(bl_median_size)
  65. big_base_reward.SetUint64(base_reward)
  66. big_multiplicand.SetUint64(multiplicand)
  67. big_product.Mul(&big_base_reward, &big_multiplicand)
  68. big_reward.Div(&big_product, &big_median_size)
  69. big_reward.Div(&big_reward, &big_median_size)
  70. // lower 64 bits contains the reward
  71. if !big_reward.IsUint64() {
  72. panic("GetBlockReward has issues\n")
  73. }
  74. reward_lo := big_reward.Uint64()
  75. if reward_lo > base_reward {
  76. panic("Reward must be less than base reward\n")
  77. }
  78. return reward_lo
  79. }