github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/emission/emission.go (about)

     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  
    17  package emission
    18  
    19  import "fmt"
    20  import "math/big"
    21  import "github.com/deroproject/derosuite/config"
    22  
    23  //TODO trickling code  is note implemented still, but we do NOT require it atleast for another 7-8 years
    24  
    25  // the logic is same as cryptonote_basic_impl.cpp
    26  
    27  // this file controls the logic for emission of coins at each height
    28  // calculates block reward
    29  
    30  func GetBlockReward(bl_median_size uint64,
    31  	bl_current_size uint64,
    32  	already_generated_coins uint64,
    33  	hard_fork_version uint64,
    34  	fee uint64) (reward uint64) {
    35  
    36  	target := config.COIN_DIFFICULTY_TARGET
    37  	target_minutes := target / 60
    38  	emission_speed_factor := config.COIN_EMISSION_SPEED_FACTOR - (target_minutes - 1)
    39  	// handle special cases
    40  	switch already_generated_coins {
    41  	case 0:
    42  		reward = 1000000000000 // give 1 DERO to genesis, but we gave 35 due to a silly typo, so continue as is
    43  		return reward
    44  	case 1000000000000:
    45  		reward = 2000000 * 1000000000000 // give the developers initial premine, while keeping the, into account and respecting transparancy
    46  		return reward
    47  	}
    48  
    49  	base_reward := (config.COIN_MONEY_SUPPLY - already_generated_coins) >> emission_speed_factor
    50  	if base_reward < (config.COIN_FINAL_SUBSIDY_PER_MINUTE * target_minutes) {
    51  		base_reward = config.COIN_FINAL_SUBSIDY_PER_MINUTE * target_minutes
    52  	}
    53  
    54  	//full_reward_zone = get_min_block_size(version);
    55  	full_reward_zone := config.CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE
    56  
    57  	if bl_median_size < full_reward_zone {
    58  		bl_median_size = full_reward_zone
    59  	}
    60  
    61  	if bl_current_size <= bl_median_size {
    62  		reward = base_reward
    63  		return reward
    64  	}
    65  
    66  	// block is bigger than median size , we must calculate it
    67  	if bl_current_size > 2*bl_median_size {
    68  		//MERROR("Block cumulative size is too big: " << current_block_size << ", expected less than " << 2 * median_size);
    69  		panic(fmt.Sprintf("Block size is too big current size %d  max possible size %d", bl_current_size, 2*bl_median_size))
    70  	}
    71  
    72  	multiplicand := (2 * bl_median_size) - bl_current_size
    73  	multiplicand = multiplicand * bl_current_size
    74  
    75  	var big_base_reward, big_multiplicand, big_product, big_reward, big_median_size big.Int
    76  
    77  	big_median_size.SetUint64(bl_median_size)
    78  	big_base_reward.SetUint64(base_reward)
    79  	big_multiplicand.SetUint64(multiplicand)
    80  
    81  	big_product.Mul(&big_base_reward, &big_multiplicand)
    82  
    83  	big_reward.Div(&big_product, &big_median_size)
    84  	big_reward.Div(&big_reward, &big_median_size)
    85  	// lower 64 bits contains the reward
    86  	if !big_reward.IsUint64() {
    87  		panic("GetBlockReward has issues\n")
    88  	}
    89  
    90  	reward_lo := big_reward.Uint64()
    91  
    92  	if reward_lo > base_reward {
    93  		panic("Reward must be less than base reward\n")
    94  	}
    95  	return reward_lo
    96  }
    97  
    98  // atlantis has very simple block reward
    99  // since our chain has already bootstrapped
   100  //  FIXME this will not workaround , when already already_generated_coins wraps around
   101  // but we have few years, atleast 6-7 to fix it
   102  func GetBlockReward_Atlantis(hard_fork_version int64, already_generated_coins uint64) (reward uint64) {
   103  
   104  	target := uint64(120) // initial target was 120 secs however difficult targeted 180 secs
   105  	target_minutes := target / 60
   106  	emission_speed_factor := config.COIN_EMISSION_SPEED_FACTOR - (target_minutes - 1)
   107  
   108  	base_reward := (config.COIN_MONEY_SUPPLY - already_generated_coins) >> emission_speed_factor
   109  	if base_reward < (config.COIN_FINAL_SUBSIDY_PER_MINUTE * target_minutes) {
   110  		base_reward = config.COIN_FINAL_SUBSIDY_PER_MINUTE * target_minutes
   111  	}
   112  
   113  	// however the new target is less than 10 secs, so divide the reward into equal parts
   114  	//base_reward = (base_reward * config.BLOCK_TIME)/ target
   115  	base_reward = (base_reward * config.BLOCK_TIME) / 180 // original daemon emission schedule
   116  
   117  	return base_reward
   118  }