Skip to content

Commit 70e1ef2

Browse files
committed
Cryptonight HeavyX and 2 minute block times HF
Changed the algorithm to Cryptonight HeavyX (2MB scratchpad with 1 << 21 Iterations) to be ASIC, FPGA and Nicehash resistant. Changed the block time to 2 minutes, in preparation for X-CASH Proof of Stake. Changed the hardfork version to 12. Changed the version to 1.5.0
1 parent 85dfb6f commit 70e1ef2

File tree

14 files changed

+268
-68
lines changed

14 files changed

+268
-68
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,17 @@ Portions Copyright (c) 2012-2013 The Cryptonote developers.
1919

2020
## Introduction
2121

22-
X-CASH is a cryptocurrency built using the Cryptonight v8 (CNv2) algorithm, with the aim to become and standard in digital payment and transaction settlement. We believe privacy is very important when it comes to managing personal finances, but at the same time banks and institutions need to know the source of the funds for KYC purposes. Therefore, we plan on leaving the users the choice of whether or not they want their transaction to be public. Because we are implementing a worldwide network of dedicated servers, we hope to make the synchronization of the blockchain faster than other cryptocurrencies as well as reducing transaction latency. We believe this network will be a key component in the deployment of the future improvements we plan on adding to the core code. The main characteristics of X-CASH are detailed below:
22+
X-CASH is a cryptocurrency built using the Cryptonight v8 (CNv2) algorithm, using a variation called CN/DOUBLE, with the aim to become and standard in digital payment and transaction settlement. We believe privacy is very important when it comes to managing personal finances, but at the same time banks and institutions need to know the source of the funds for KYC purposes. Therefore, we plan on leaving the users the choice of whether or not they want their transaction to be public. Because we are implementing a worldwide network of dedicated servers, we hope to make the synchronization of the blockchain faster than other cryptocurrencies as well as reducing transaction latency. We believe this network will be a key component in the deployment of the future improvements we plan on adding to the core code. The main characteristics of X-CASH are detailed below:
2323

2424
- Total Supply: 100,000,000,000
2525

26-
- Block Time: 1 minute
26+
- Block Time: 2 minute
2727

28-
- Algorithm: Cryptonight v8 (CNv2)
28+
- Algorithm: CN/DOUBLE (Cryptonight v8 (scratchpad of 2MB) with double the iterations, and some minor changes)
2929

3030
- Reward: ~100,000 XCA at inception
3131

32-
- Emission structure: logarithmic until max supply is reached in 2020. For more information: https://www.x-cash.org
32+
- Emission structure: logarithmic until max supply is reached in 2022. For more information: https://www.x-cash.org
3333

3434
We developed the FlexPrivacy feature, giving the opportunity to the user to chose between sending their transaction privately or publicly, from the same account, on the same blockchain, and on a per transaction basis. This is the first Cryptonight coin showing this hybrid feature, resembling the current cash system:
3535
- make a transaction using a check, credit card, bank transfer etc… and leave a transaction trail (public transaction)
@@ -54,6 +54,7 @@ If you want to help out, see [CONTRIBUTING](CONTRIBUTING.md) for a set of guidel
5454
| 106000 | 16-10-2018 | v9 | Adjusting the new difficulty algorithm |
5555
| 136000 | 06-11-2018 | v10 | Adding public transactions, bullet proofs, fixed ring size of 21 and more! |
5656
| 137000 | 07-11-2018 | v11 | This version makes sure that all non bullet proof transactions are confirmed before bullet proofs transactions are required. |
57+
| 281000 | 15-02-2019 | v12 | This version changes the proof of work algorithm to CN/DOUBLE, and changes the block time to 2 minutes. |
5758

5859
Note future releases block heights and dates may change, so make sure to frequently check github, our website, the forums, etc. for the most up to date information.
5960

src/crypto/slow-hash.c

Lines changed: 111 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
#include "variant2_int_sqrt.h"
4242

4343
#define MEMORY (1 << 21) // 2MB scratchpad
44-
#define ITER (1 << 20)
44+
#define ITER(variant) (variant >= 3 ? (1 << 21) : (1 << 20))
4545
#define AES_BLOCK_SIZE 16
4646
#define AES_KEY_SIZE 32
4747
#define INIT_SIZE_BLK 8
@@ -109,8 +109,16 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp
109109
memcpy(b + AES_BLOCK_SIZE, state.hs.b + 64, AES_BLOCK_SIZE); \
110110
xor64(b + AES_BLOCK_SIZE, state.hs.b + 80); \
111111
xor64(b + AES_BLOCK_SIZE + 8, state.hs.b + 88); \
112-
division_result = state.hs.w[12]; \
113-
sqrt_result = state.hs.w[13]; \
112+
if (variant == 2) \
113+
{ \
114+
division_result = state.hs.w[12]; \
115+
sqrt_result = state.hs.w[13]; \
116+
} \
117+
else if (variant == 3) \
118+
{ \
119+
division_result = SWAP64LE(state.hs.w[12]); \
120+
sqrt_result = SWAP64LE(state.hs.w[13]); \
121+
} \
114122
} while (0)
115123

116124
#define VARIANT2_SHUFFLE_ADD_SSE2(base_ptr, offset) \
@@ -145,30 +153,66 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp
145153
const uint64_t chunk1_old[2] = { chunk1[0], chunk1[1] }; \
146154
\
147155
uint64_t b1[2]; \
148-
memcpy(b1, b + 16, 16); \
149-
chunk1[0] = chunk3[0] + b1[0]; \
150-
chunk1[1] = chunk3[1] + b1[1]; \
151-
\
152-
uint64_t a0[2]; \
153-
memcpy(a0, a, 16); \
154-
chunk3[0] = chunk2[0] + a0[0]; \
155-
chunk3[1] = chunk2[1] + a0[1]; \
156-
\
157-
uint64_t b0[2]; \
158-
memcpy(b0, b, 16); \
159-
chunk2[0] = chunk1_old[0] + b0[0]; \
160-
chunk2[1] = chunk1_old[1] + b0[1]; \
156+
if (variant == 2) \
157+
{ \
158+
memcpy(b1, b + 16, 16); \
159+
chunk1[0] = chunk3[0] + b1[0]; \
160+
chunk1[1] = chunk3[1] + b1[1]; \
161+
\
162+
uint64_t a0[2]; \
163+
memcpy(a0, a, 16); \
164+
chunk3[0] = chunk2[0] + a0[0]; \
165+
chunk3[1] = chunk2[1] + a0[1]; \
166+
\
167+
uint64_t b0[2]; \
168+
memcpy(b0, b, 16); \
169+
chunk2[0] = chunk1_old[0] + b0[0]; \
170+
chunk2[1] = chunk1_old[1] + b0[1]; \
171+
} \
172+
else if (variant == 3) \
173+
{ \
174+
memcpy_swap64le(b1, b + 16, 2); \
175+
chunk1[0] = SWAP64LE(SWAP64LE(chunk3[0]) + b1[0]); \
176+
chunk1[1] = SWAP64LE(SWAP64LE(chunk3[1]) + b1[1]); \
177+
\
178+
uint64_t a0[2]; \
179+
memcpy_swap64le(a0, a, 2); \
180+
chunk3[0] = SWAP64LE(SWAP64LE(chunk2[0]) + a0[0]); \
181+
chunk3[1] = SWAP64LE(SWAP64LE(chunk2[1]) + a0[1]); \
182+
\
183+
uint64_t b0[2]; \
184+
memcpy_swap64le(b0, b, 2); \
185+
chunk2[0] = SWAP64LE(SWAP64LE(chunk1_old[0]) + b0[0]); \
186+
chunk2[1] = SWAP64LE(SWAP64LE(chunk1_old[1]) + b0[1]); \
187+
} \
161188
} while (0)
162189

163190
#define VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr) \
164-
((uint64_t*)(b))[0] ^= division_result ^ (sqrt_result << 32); \
191+
uint64_t sqrt_input_result = 0; \
192+
if (variant <= 2) \
165193
{ \
166-
const uint64_t dividend = ((uint64_t*)(ptr))[1]; \
167-
const uint32_t divisor = (((uint64_t*)(ptr))[0] + (uint32_t)(sqrt_result << 1)) | 0x80000001UL; \
168-
division_result = ((uint32_t)(dividend / divisor)) + \
194+
((uint64_t*)(b))[0] ^= division_result ^ (sqrt_result << 32); \
195+
{ \
196+
const uint64_t dividend = ((uint64_t*)(ptr))[1]; \
197+
const uint32_t divisor = (((uint64_t*)(ptr))[0] + (uint32_t)(sqrt_result << 1)) | 0x80000001UL; \
198+
division_result = ((uint32_t)(dividend / divisor)) + \
169199
(((uint64_t)(dividend % divisor)) << 32); \
200+
} \
201+
sqrt_input_result = ((uint64_t*)(ptr))[0] + division_result; \
170202
} \
171-
const uint64_t sqrt_input = ((uint64_t*)(ptr))[0] + division_result
203+
else if (variant == 3) \
204+
{ \
205+
uint64_t tmpx = division_result ^ (sqrt_result << 32); \
206+
((uint64_t*)(b))[0] ^= SWAP64LE(tmpx); \
207+
{ \
208+
const uint64_t dividend = SWAP64LE(((uint64_t*)(ptr))[1]); \
209+
const uint32_t divisor = (SWAP64LE(((uint64_t*)(ptr))[0]) + (uint32_t)(sqrt_result << 1)) | 0x80000001UL; \
210+
division_result = ((uint32_t)(dividend / divisor)) + \
211+
(((uint64_t)(dividend % divisor)) << 32); \
212+
} \
213+
sqrt_input_result = SWAP64LE(((uint64_t*)(ptr))[0]) + division_result; \
214+
} \
215+
const uint64_t sqrt_input = sqrt_input_result
172216

173217
#define VARIANT2_INTEGER_MATH_SSE2(b, ptr) \
174218
do if (variant >= 2) \
@@ -205,12 +249,19 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp
205249
}
206250

207251
#define VARIANT2_2() \
208-
do if (variant >= 2) \
252+
do if (variant == 2) \
209253
{ \
210254
*U64(hp_state + (j ^ 0x10)) ^= hi; \
211255
*(U64(hp_state + (j ^ 0x10)) + 1) ^= lo; \
212256
hi ^= *U64(hp_state + (j ^ 0x20)); \
213257
lo ^= *(U64(hp_state + (j ^ 0x20)) + 1); \
258+
} while (0); \
259+
do if (variant == 3) \
260+
{ \
261+
*U64(hp_state + (j ^ 0x10)) ^= SWAP64LE(hi); \
262+
*(U64(hp_state + (j ^ 0x10)) + 1) ^= SWAP64LE(lo); \
263+
hi ^= SWAP64LE(*U64(hp_state + (j ^ 0x20))); \
264+
lo ^= SWAP64LE(*(U64(hp_state + (j ^ 0x20)) + 1)); \
214265
} while (0)
215266

216267

@@ -772,7 +823,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
772823
// the useAes test is only performed once, not every iteration.
773824
if(useAes)
774825
{
775-
for(i = 0; i < ITER / 2; i++)
826+
for(i = 0; i < ITER(variant) / 2; i++)
776827
{
777828
pre_aes();
778829
_c = _mm_aesenc_si128(_c, _a);
@@ -781,7 +832,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
781832
}
782833
else
783834
{
784-
for(i = 0; i < ITER / 2; i++)
835+
for(i = 0; i < ITER(variant) / 2; i++)
785836
{
786837
pre_aes();
787838
aesb_single_round((uint8_t *) &_c, (uint8_t *) &_c, (uint8_t *) &_a);
@@ -1124,7 +1175,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
11241175
_b = vld1q_u8((const uint8_t *)b);
11251176
_b1 = vld1q_u8(((const uint8_t *)b) + AES_BLOCK_SIZE);
11261177

1127-
for(i = 0; i < ITER / 2; i++)
1178+
for(i = 0; i < ITER(variant) / 2; i++)
11281179
{
11291180
pre_aes();
11301181
_c = vaeseq_u8(_c, zero);
@@ -1331,7 +1382,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
13311382
U64(b)[0] = U64(&state.k[16])[0] ^ U64(&state.k[48])[0];
13321383
U64(b)[1] = U64(&state.k[16])[1] ^ U64(&state.k[48])[1];
13331384

1334-
for(i = 0; i < ITER / 2; i++)
1385+
for(i = 0; i < ITER(variant) / 2; i++)
13351386
{
13361387
#define MASK ((uint32_t)(((MEMORY / AES_BLOCK_SIZE) - 1) << 4))
13371388
#define state_index(x) ((*(uint32_t *) x) & MASK)
@@ -1412,6 +1463,7 @@ extern int aesb_single_round(const uint8_t *in, uint8_t*out, const uint8_t *expa
14121463
extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey);
14131464

14141465
static size_t e2i(const uint8_t* a, size_t count) { return (*((uint64_t*)a) / AES_BLOCK_SIZE) & (count - 1); }
1466+
static size_t e2i_3(const uint8_t* a, size_t count) { return (SWAP64LE(*((uint64_t*)a)) / AES_BLOCK_SIZE) & (count - 1); }
14151467

14161468
static void mul(const uint8_t* a, const uint8_t* b, uint8_t* res) {
14171469
uint64_t a0, b0;
@@ -1521,22 +1573,43 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
15211573
b[i] = state.k[AES_BLOCK_SIZE + i] ^ state.k[AES_BLOCK_SIZE * 3 + i];
15221574
}
15231575

1524-
for (i = 0; i < ITER / 2; i++) {
1576+
for (i = 0; i < ITER(variant) / 2; i++) {
15251577
/* Dependency chain: address -> read value ------+
15261578
* written value <-+ hard function (AES or MUL) <+
15271579
* next address <-+
15281580
*/
15291581
/* Iteration 1 */
1530-
j = e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
1582+
if (variant <= 2)
1583+
{
1584+
j = e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
1585+
}
1586+
else if (variant == 3)
1587+
{
1588+
j = e2i_3(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
1589+
}
15311590
copy_block(c1, &long_state[j]);
15321591
aesb_single_round(c1, c1, a);
15331592
VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j);
15341593
copy_block(&long_state[j], c1);
15351594
xor_blocks(&long_state[j], b);
1536-
assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
1595+
if (variant <= 2)
1596+
{
1597+
assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
1598+
}
1599+
else if (variant == 3)
1600+
{
1601+
assert(j == e2i_3(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
1602+
}
15371603
VARIANT1_1(&long_state[j]);
15381604
/* Iteration 2 */
1539-
j = e2i(c1, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
1605+
if (variant <= 2)
1606+
{
1607+
j = e2i(c1, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
1608+
}
1609+
else if (variant == 3)
1610+
{
1611+
j = e2i_3(c1, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
1612+
}
15401613
copy_block(c2, &long_state[j]);
15411614
VARIANT2_PORTABLE_INTEGER_MATH(c2, c1);
15421615
mul(c1, c2, d);
@@ -1548,7 +1621,14 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
15481621
xor_blocks(c1, c2);
15491622
VARIANT1_2(c2 + 8);
15501623
copy_block(&long_state[j], c2);
1551-
assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
1624+
if (variant <= 2)
1625+
{
1626+
assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
1627+
}
1628+
else if (variant == 3)
1629+
{
1630+
assert(j == e2i_3(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE);
1631+
}
15521632
if (variant >= 2) {
15531633
copy_block(b + AES_BLOCK_SIZE, b);
15541634
}

src/cryptonote_basic/cryptonote_basic_impl.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ namespace cryptonote {
8787
}
8888
//-----------------------------------------------------------------------------------------------
8989
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 height) {
90-
static_assert(DIFFICULTY_TARGET_V2%60==0&&DIFFICULTY_TARGET_V1%60==0,"difficulty targets must be a multiple of 60");
91-
const int target = version < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
92-
const int target_minutes = target / 60;
90+
static_assert(DIFFICULTY_TARGET_V1%60==0&&DIFFICULTY_TARGET_V2%60==0&&DIFFICULTY_TARGET_V8%60==0&&DIFFICULTY_TARGET_V9%60==0&&DIFFICULTY_TARGET_V10%60==0&&DIFFICULTY_TARGET_V12%60==0,"difficulty targets must be a multiple of 60");
91+
const int target = version < HF_VERSION_TWO_MINUTE_BLOCK_TIME ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V12;
92+
const int target_minutes = 1; // set it to always 1, so we dont increase the block reward when changing the block time
9393
const int emission_speed_factor = EMISSION_SPEED_FACTOR_PER_MINUTE - (target_minutes-1);
9494

9595
uint64_t base_reward;

src/cryptonote_basic/cryptonote_format_utils.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,10 +1033,14 @@ namespace cryptonote
10331033
{
10341034
cn_variant = 1;
10351035
}
1036-
else
1036+
else if (b.major_version == 10 || b.major_version == 11)
10371037
{
10381038
cn_variant = 2;
10391039
}
1040+
else
1041+
{
1042+
cn_variant = 3;
1043+
}
10401044
crypto::cn_slow_hash(bd.data(), bd.size(), res, cn_variant);
10411045
return true;
10421046
}

src/cryptonote_basic/difficulty.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,4 +369,78 @@ difficulty_type next_difficulty_V10(std::vector<std::uint64_t> timestamps, std::
369369
return next_difficulty;
370370
}
371371

372+
373+
374+
375+
376+
377+
378+
379+
380+
// LWMA difficulty algorithm
381+
// Background: https://github.com/zawy12/difficulty-algorithms/issues/3
382+
// Copyright (c) 2017-2018 Zawy (pseudocode)
383+
// MIT license http://www.opensource.org/licenses/mit-license.php
384+
// Copyright (c) 2018 The Stellite Project
385+
// Copyright (c) 2018 The Masari Project (10x for quicker recoveries, minimum to be symmetric with FTL)
386+
// Copyright (c) 2018 Wownero Inc., a Monero Enterprise Alliance partner company
387+
// Copyright (c) 2018 The Karbowanec developers (initial code)
388+
// Copyright (c) 2018 Haven Protocol (refinements)
389+
// Degnr8, Karbowanec, Masari, Bitcoin Gold, Bitcoin Candy, and Haven have contributed.
390+
// This algorithm is: next_difficulty = harmonic_mean(Difficulties) * T / LWMA(Solvetimes)
391+
// The harmonic_mean(Difficulties) = 1/average(Targets) so it is also:
392+
// next_target = avg(Targets) * LWMA(Solvetimes) / T.
393+
// This is "the best algorithm" because it has lowest root-mean-square error between
394+
// needed & actual difficulty during hash attacks while having the lowest standard
395+
// deviation during stable hashrate. That is, it's the fastest for a given stability and vice versa.
396+
// Do not use "if solvetime < 1 then solvetime = 1" which allows a catastrophic exploit.
397+
// Do not sort timestamps. "Solvetimes" and "LWMA" variables must allow negatives.
398+
// Do not use MTP as most recent block. Do not use (POW)Limits, filtering, or tempering.
399+
// Do not forget to set N (aka DIFFICULTY_WINDOW in Cryptonote) to recommendation below.
400+
// The nodes' future time limit (FTL) aka CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT needs to
401+
// be reduced from 60*60*2 to 500 seconds to prevent timestamp manipulation from miner's with
402+
// > 50% hash power. If this is too small, it can be increased to 1000 at a cost in protection.
403+
difficulty_type next_difficulty_V12(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds) {
404+
const int64_t T = static_cast<int64_t>(target_seconds);
405+
size_t N = DIFFICULTY_WINDOW_V12;
406+
// Return a difficulty of 1 for first 3 blocks if it's the start of the chain.
407+
if (timestamps.size() < 4) {
408+
return 1;
409+
}
410+
// Otherwise, use a smaller N if the start of the chain is less than N+1.
411+
else if ( timestamps.size() < N+1 ) {
412+
N = timestamps.size() - 1;
413+
}
414+
// Otherwise make sure timestamps and cumulative_difficulties are correct size.
415+
else {
416+
timestamps.resize(N+1);
417+
cumulative_difficulties.resize(N+1);
418+
}
419+
// To get an average solvetime to within +/- ~0.1%, use an adjustment factor.
420+
// adjust=0.998 for N = 60
421+
const double adjust = 0.998;
422+
// The divisor k normalizes the LWMA sum to a standard LWMA.
423+
const double k = N * (N + 1) / 2;
424+
double LWMA(0), sum_inverse_D(0), harmonic_mean_D(0), nextDifficulty(0);
425+
int64_t solveTime(0);
426+
uint64_t difficulty(0), next_difficulty(0);
427+
// Loop through N most recent blocks. N is most recently solved block.
428+
for (size_t i = 1; i <= N; i++) {
429+
solveTime = static_cast<int64_t>(timestamps[i]) - static_cast<int64_t>(timestamps[i - 1]);
430+
solveTime = std::min<int64_t>((T * 10), solveTime);
431+
difficulty = cumulative_difficulties[i] - cumulative_difficulties[i - 1];
432+
LWMA += (int64_t)(solveTime * i) / k;
433+
sum_inverse_D += 1 / static_cast<double>(difficulty);
434+
}
435+
harmonic_mean_D = N / sum_inverse_D;
436+
// Limit LWMA same as Bitcoin's 1/4 in case something unforeseen occurs.
437+
if (static_cast<int64_t>(boost::math::round(LWMA)) < T / 4)
438+
LWMA = static_cast<double>(T / 4);
439+
nextDifficulty = harmonic_mean_D * T / LWMA * adjust;
440+
// No limits should be employed, but this is correct way to employ a 20% symmetrical limit:
441+
// nextDifficulty=max(previous_Difficulty*0.8,min(previous_Difficulty/0.8, next_Difficulty));
442+
next_difficulty = static_cast<uint64_t>(nextDifficulty);
443+
return next_difficulty;
444+
}
445+
372446
}

src/cryptonote_basic/difficulty.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,5 @@ namespace cryptonote
5656
difficulty_type next_difficulty_V8(std::vector<std::uint64_t> timestamps,std::vector<difficulty_type> cumulative_difficulties, uint64_t block_height);
5757
difficulty_type next_difficulty_V9(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
5858
difficulty_type next_difficulty_V10(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
59+
difficulty_type next_difficulty_V12(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
5960
}

0 commit comments

Comments
 (0)