Electroneum
Loading...
Searching...
No Matches
block_reward.cpp
Go to the documentation of this file.
1// Copyrights(c) 2017-2021, The Electroneum Project
2// Copyrights(c) 2014-2019, The Monero Project
3//
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without modification, are
7// permitted provided that the following conditions are met:
8//
9// 1. Redistributions of source code must retain the above copyright notice, this list of
10// conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright notice, this list
13// of conditions and the following disclaimer in the documentation and/or other
14// materials provided with the distribution.
15//
16// 3. Neither the name of the copyright holder nor the names of its contributors may be
17// used to endorse or promote products derived from this software without specific
18// prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29//
30// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31
32#include "gtest/gtest.h"
33
35
36using namespace cryptonote;
37
38namespace
39{
40 //--------------------------------------------------------------------------------------------------------------------
41 class block_reward_and_already_generated_coins : public ::testing::Test
42 {
43 protected:
44 static const size_t current_block_weight = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1 / 2;
45
46 bool m_block_not_too_big;
47 uint64_t m_block_reward;
48 uint64_t median;
49 };
50
51 #define TEST_ALREADY_GENERATED_COINS(already_generated_coins, expected_reward) \
52 median = (already_generated_coins == 2002716) ? 1 : 0; \
53 m_block_not_too_big = get_block_reward(median, current_block_weight, already_generated_coins, m_block_reward,1,0); \
54 ASSERT_TRUE(m_block_not_too_big); \
55 ASSERT_EQ(m_block_reward, expected_reward);
56
57 TEST_F(block_reward_and_already_generated_coins, handles_first_values)
58 {
59 /* NB the result of Test#1 is a consequence of how the premine was implemented without */
60 /* a complimentary change to the code that creates the genesis block and stores its data. */
61 /* Premined block must also be tested with median > 0 because of its implementation in get_block_reward */
62 /* Test the first few blocks: */
64 TEST_ALREADY_GENERATED_COINS(m_block_reward, UINT64_C(1260000000000));
65 TEST_ALREADY_GENERATED_COINS(m_block_reward + 2002716 , UINT64_C(801084));
66 TEST_ALREADY_GENERATED_COINS(m_block_reward + 2002716 + 1260000000000, UINT64_C(801083));
67 /* Test some large, arbitrary number before FINAL_SUBSIDY_PER_MINUTE is reached */
68 TEST_ALREADY_GENERATED_COINS(1860000000000, UINT64_C(228881));
69 }
70
71 TEST_F(block_reward_and_already_generated_coins, correctly_steps_from_2_to_1)
72 {
76 }
77
78 TEST_F(block_reward_and_already_generated_coins, handles_max)
79 {
83 }
84
85 //--------------------------------------------------------------------------------------------------------------------
86 class block_reward_and_current_block_weight : public ::testing::Test
87 {
88 protected:
89 virtual void SetUp()
90 {
91 m_block_not_too_big = get_block_reward(0, 0, already_generated_coins, m_standard_block_reward, 1, 0);
92 ASSERT_TRUE(m_block_not_too_big);
94 }
95
96 void do_test(size_t median_block_weight, size_t current_block_weight)
97 {
98 m_block_not_too_big = get_block_reward(median_block_weight, current_block_weight, already_generated_coins, m_block_reward, 1, 0);
99 }
100
101 static const uint64_t already_generated_coins = 1260000000000;
102
103 bool m_block_not_too_big;
104 uint64_t m_block_reward;
105 uint64_t m_standard_block_reward;
106 };
107
108 TEST_F(block_reward_and_current_block_weight, handles_block_weight_less_relevance_level)
109 {
111 ASSERT_TRUE(m_block_not_too_big);
112 ASSERT_EQ(m_block_reward, m_standard_block_reward);
113 }
114
115 TEST_F(block_reward_and_current_block_weight, handles_block_weight_eq_relevance_level)
116 {
118 ASSERT_TRUE(m_block_not_too_big);
119 ASSERT_EQ(m_block_reward, m_standard_block_reward);
120 }
121
122 TEST_F(block_reward_and_current_block_weight, handles_block_weight_gt_relevance_level)
123 {
125 ASSERT_TRUE(m_block_not_too_big);
126 ASSERT_LT(m_block_reward, m_standard_block_reward);
127 }
128
129 TEST_F(block_reward_and_current_block_weight, handles_block_weight_less_2_relevance_level)
130 {
132 ASSERT_TRUE(m_block_not_too_big);
133 ASSERT_LT(m_block_reward, m_standard_block_reward);
134 ASSERT_LT(0, m_block_reward);
135 }
136
137 TEST_F(block_reward_and_current_block_weight, handles_block_weight_eq_2_relevance_level)
138 {
140 ASSERT_TRUE(m_block_not_too_big);
141 ASSERT_EQ(0, m_block_reward);
142 }
143
144 TEST_F(block_reward_and_current_block_weight, handles_block_weight_gt_2_relevance_level)
145 {
147 ASSERT_FALSE(m_block_not_too_big);
148 }
149
150#ifdef __x86_64__ // For 64-bit systems only, because block size is limited to size_t.
151 TEST_F(block_reward_and_current_block_weight, fails_on_huge_median_size)
152 {
153#if !defined(NDEBUG)
154 size_t huge_size = std::numeric_limits<uint32_t>::max() + UINT64_C(2);
155 ASSERT_DEATH(do_test(huge_size, huge_size + 1), "");
156#endif
157 }
158
159 TEST_F(block_reward_and_current_block_weight, fails_on_huge_block_weight)
160 {
161#if !defined(NDEBUG)
162 size_t huge_size = std::numeric_limits<uint32_t>::max() + UINT64_C(2);
163 ASSERT_DEATH(do_test(huge_size - 2, huge_size), "");
164#endif
165 }
166#endif // __x86_64__
167
168 //--------------------------------------------------------------------------------------------------------------------
169 class block_reward_and_last_block_weights : public ::testing::Test
170 {
171 protected:
172 virtual void SetUp()
173 {
174 m_last_block_weights.push_back(3 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1);
175 m_last_block_weights.push_back(5 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1);
176 m_last_block_weights.push_back(7 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1);
177 m_last_block_weights.push_back(11 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1);
178 m_last_block_weights.push_back(13 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1);
179
180 m_last_block_weights_median = 7 * CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1;
181
182 m_block_not_too_big = get_block_reward(epee::misc_utils::median(m_last_block_weights), 0, already_generated_coins, m_standard_block_reward, 1, 0);
183 ASSERT_TRUE(m_block_not_too_big);
185 }
186
187 void do_test(size_t current_block_weight)
188 {
189 m_block_not_too_big = get_block_reward(epee::misc_utils::median(m_last_block_weights), current_block_weight, already_generated_coins, m_block_reward, 1, 0);
190 }
191
192 static const uint64_t already_generated_coins = 1260000000000;
193
194 std::vector<size_t> m_last_block_weights;
195 uint64_t m_last_block_weights_median;
196 bool m_block_not_too_big;
197 uint64_t m_block_reward;
198 uint64_t m_standard_block_reward;
199 };
200
201 TEST_F(block_reward_and_last_block_weights, handles_block_weight_less_median)
202 {
203 do_test(m_last_block_weights_median - 1);
204 ASSERT_TRUE(m_block_not_too_big);
205 ASSERT_EQ(m_block_reward, m_standard_block_reward);
206 }
207
208 TEST_F(block_reward_and_last_block_weights, handles_block_weight_eq_median)
209 {
210 do_test(m_last_block_weights_median);
211 ASSERT_TRUE(m_block_not_too_big);
212 ASSERT_EQ(m_block_reward, m_standard_block_reward);
213 }
214
215 TEST_F(block_reward_and_last_block_weights, handles_block_weight_gt_median)
216 {
217 do_test(m_last_block_weights_median + 1);
218 ASSERT_TRUE(m_block_not_too_big);
219 ASSERT_LT(m_block_reward, m_standard_block_reward);
220 }
221
222 TEST_F(block_reward_and_last_block_weights, handles_block_weight_less_2_medians)
223 {
224 do_test(2 * m_last_block_weights_median - 1);
225 ASSERT_TRUE(m_block_not_too_big);
226 ASSERT_LT(m_block_reward, m_standard_block_reward);
227 ASSERT_LT(0, m_block_reward);
228 }
229
230 TEST_F(block_reward_and_last_block_weights, handles_block_weight_eq_2_medians)
231 {
232 do_test(2 * m_last_block_weights_median);
233 ASSERT_TRUE(m_block_not_too_big);
234 ASSERT_EQ(0, m_block_reward);
235 }
236
237 TEST_F(block_reward_and_last_block_weights, handles_block_weight_gt_2_medians)
238 {
239 do_test(2 * m_last_block_weights_median + 1);
240 ASSERT_FALSE(m_block_not_too_big);
241 }
242
243 TEST_F(block_reward_and_last_block_weights, calculates_correctly)
244 {
245 ASSERT_EQ(0, m_last_block_weights_median % 8);
246
247 do_test(m_last_block_weights_median * 9 / 8);
248 ASSERT_TRUE(m_block_not_too_big);
249 ASSERT_EQ(m_block_reward, m_standard_block_reward * 63 / 64);
250
251 // 3/2 = 12/8
252 do_test(m_last_block_weights_median * 3 / 2);
253 ASSERT_TRUE(m_block_not_too_big);
254 ASSERT_EQ(m_block_reward, m_standard_block_reward * 3 / 4);
255
256 do_test(m_last_block_weights_median * 15 / 8);
257 ASSERT_TRUE(m_block_not_too_big);
258 ASSERT_EQ(m_block_reward, m_standard_block_reward * 15 / 64);
259 }
260}
#define CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1
#define FINAL_SUBSIDY_PER_MINUTE
#define ETN_SUPPLY
#define TEST_F(test_fixture, test_name)
Definition gtest.h:2216
#define ASSERT_EQ(val1, val2)
Definition gtest.h:1956
#define ASSERT_FALSE(condition)
Definition gtest.h:1868
#define ASSERT_TRUE(condition)
Definition gtest.h:1865
#define ASSERT_LT(val1, val2)
Definition gtest.h:1968
Holds cryptonote related classes and helpers.
Definition ban.cpp:40
bool get_block_reward(size_t median_weight, size_t current_block_weight, uint64_t already_generated_coins, uint64_t &reward, uint8_t version, uint64_t current_block_height, network_type nettype)
type_vec_type median(std::vector< type_vec_type > &v)
#define UINT64_C(val)
Definition stdint.h:284
unsigned __int64 uint64_t
Definition stdint.h:136
#define TEST_ALREADY_GENERATED_COINS(already_generated_coins, expected_reward)