Skip to content

Commit a2c93f6

Browse files
author
X-CASH-official
committed
Adjusted the new difficulty algorithm
Adjusted the new difficulty algorithm
1 parent 99c69c1 commit a2c93f6

File tree

7 files changed

+172
-119
lines changed

7 files changed

+172
-119
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ If you want to help out, see [CONTRIBUTING](CONTRIBUTING.md) for a set of guidel
4646
| 0 | 22-07-2018 | v1 | Genesis block |
4747
| 1 | 22-07-2018 | v7 | Start of the blockchain |
4848
| 95085 | 08-10-2018 | v8 | changing difficulty algorithm to [LWMA-2 developed by Zawy12](https://github.com/zawy12/difficulty-algorithms/issues/3) |
49-
| 145000 | 01-11-2018 | v9 | Adding public transactions, bullet proofs, increased and static ringsize and more! |
49+
| 106000 | 01-11-2018 | v9 | Adjusting the new difficulty algorithm |
50+
| 145000 | 01-11-2018 | v10 | Adding public transactions, bullet proofs, increased and static ringsize and more! |
5051

5152
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.
5253

src/cryptonote_basic/difficulty.cpp

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <cstddef>
3434
#include <cstdint>
3535
#include <vector>
36+
#include <boost/math/special_functions/round.hpp>
3637

3738
#include "common/int-util.h"
3839
#include "crypto/hash.h"
@@ -185,7 +186,6 @@ namespace cryptonote {
185186
// > 50% hash power. If this is too small, it can be increased to 1000 at a cost in protection.
186187
// Cryptonote clones: #define DIFFICULTY_BLOCKS_COUNT_V2 DIFFICULTY_WINDOW_V2 + 1
187188
// difficulty_type should be uint64_t
188-
189189
difficulty_type next_difficulty_V8(std::vector<std::uint64_t> timestamps,std::vector<difficulty_type> cumulative_difficulties, uint64_t block_height) {
190190
int64_t T = DIFFICULTY_TARGET_V8; // target solvetime seconds
191191
int64_t N = DIFFICULTY_WINDOW_V8; // N=45, 60, and 90 for T=600, 120, 60.
@@ -224,4 +224,78 @@ return static_cast<uint64_t>(next_D);
224224
// next_Target = sumTargets*L*2/0.998/T/(N+1)/N/N; // To show the difference.
225225
}
226226

227+
228+
229+
230+
231+
232+
233+
// LWMA difficulty algorithm
234+
// Background: https://github.com/zawy12/difficulty-algorithms/issues/3
235+
// Copyright (c) 2017-2018 Zawy (pseudocode)
236+
// MIT license http://www.opensource.org/licenses/mit-license.php
237+
// Copyright (c) 2018 The Stellite Project
238+
// Copyright (c) 2018 The Masari Project (10x for quicker recoveries, minimum to be symmetric with FTL)
239+
// Copyright (c) 2018 Wownero Inc., a Monero Enterprise Alliance partner company
240+
// Copyright (c) 2018 The Karbowanec developers (initial code)
241+
// Copyright (c) 2018 Haven Protocol (refinements)
242+
// Degnr8, Karbowanec, Masari, Bitcoin Gold, Bitcoin Candy, and Haven have contributed.
243+
// This algorithm is: next_difficulty = harmonic_mean(Difficulties) * T / LWMA(Solvetimes)
244+
// The harmonic_mean(Difficulties) = 1/average(Targets) so it is also:
245+
// next_target = avg(Targets) * LWMA(Solvetimes) / T.
246+
// This is "the best algorithm" because it has lowest root-mean-square error between
247+
// needed & actual difficulty during hash attacks while having the lowest standard
248+
// deviation during stable hashrate. That is, it's the fastest for a given stability and vice versa.
249+
// Do not use "if solvetime < 1 then solvetime = 1" which allows a catastrophic exploit.
250+
// Do not sort timestamps. "Solvetimes" and "LWMA" variables must allow negatives.
251+
// Do not use MTP as most recent block. Do not use (POW)Limits, filtering, or tempering.
252+
// Do not forget to set N (aka DIFFICULTY_WINDOW in Cryptonote) to recommendation below.
253+
// The nodes' future time limit (FTL) aka CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT needs to
254+
// be reduced from 60*60*2 to 500 seconds to prevent timestamp manipulation from miner's with
255+
// > 50% hash power. If this is too small, it can be increased to 1000 at a cost in protection.
256+
difficulty_type next_difficulty_V9(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds) {
257+
const int64_t T = static_cast<int64_t>(target_seconds);
258+
size_t N = DIFFICULTY_WINDOW_V9;
259+
int64_t FTL = static_cast<int64_t>(CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V9);
260+
// Return a difficulty of 1 for first 3 blocks if it's the start of the chain.
261+
if (timestamps.size() < 4) {
262+
return 1;
263+
}
264+
// Otherwise, use a smaller N if the start of the chain is less than N+1.
265+
else if ( timestamps.size() < N+1 ) {
266+
N = timestamps.size() - 1;
267+
}
268+
// Otherwise make sure timestamps and cumulative_difficulties are correct size.
269+
else {
270+
timestamps.resize(N+1);
271+
cumulative_difficulties.resize(N+1);
272+
}
273+
// To get an average solvetime to within +/- ~0.1%, use an adjustment factor.
274+
// adjust=0.998 for N = 60
275+
const double adjust = 0.998;
276+
// The divisor k normalizes the LWMA sum to a standard LWMA.
277+
const double k = N * (N + 1) / 2;
278+
double LWMA(0), sum_inverse_D(0), harmonic_mean_D(0), nextDifficulty(0);
279+
int64_t solveTime(0);
280+
uint64_t difficulty(0), next_difficulty(0);
281+
// Loop through N most recent blocks. N is most recently solved block.
282+
for (size_t i = 1; i <= N; i++) {
283+
solveTime = static_cast<int64_t>(timestamps[i]) - static_cast<int64_t>(timestamps[i - 1]);
284+
solveTime = std::min<int64_t>((T * 10), std::max<int64_t>(solveTime, -FTL));
285+
difficulty = cumulative_difficulties[i] - cumulative_difficulties[i - 1];
286+
LWMA += (int64_t)(solveTime * i) / k;
287+
sum_inverse_D += 1 / static_cast<double>(difficulty);
288+
}
289+
harmonic_mean_D = N / sum_inverse_D;
290+
// Limit LWMA same as Bitcoin's 1/4 in case something unforeseen occurs.
291+
if (static_cast<int64_t>(boost::math::round(LWMA)) < T / 4)
292+
LWMA = static_cast<double>(T / 4);
293+
nextDifficulty = harmonic_mean_D * T / LWMA * adjust;
294+
// No limits should be employed, but this is correct way to employ a 20% symmetrical limit:
295+
// nextDifficulty=max(previous_Difficulty*0.8,min(previous_Difficulty/0.8, next_Difficulty));
296+
next_difficulty = static_cast<uint64_t>(nextDifficulty);
297+
return next_difficulty;
298+
}
299+
300+
227301
}

src/cryptonote_basic/difficulty.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,5 @@ namespace cryptonote
5454
bool check_hash(const crypto::hash &hash, difficulty_type difficulty);
5555
difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
5656
difficulty_type next_difficulty_V8(std::vector<std::uint64_t> timestamps,std::vector<difficulty_type> cumulative_difficulties, uint64_t block_height);
57+
difficulty_type next_difficulty_V9(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
5758
}

src/cryptonote_config.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
#define PREMINE_BLOCK_HEIGHT 1
8585
#define PREMINE_BLOCK_REWARD ((uint64_t)(40000000000000000))
8686

87-
// LWMA difficulty
87+
// LWMA difficulty V8
8888
#define HF_VERSION_LWMA_DIFFICULTY 8
8989
#define HF_VERSION_LWMA_DIFFICULTY_BLOCK_HEIGHT 95085
9090
#define HF_VERSION_LWMA_STARTING_DIFFICULTY 30000000
@@ -94,6 +94,14 @@
9494
#define DIFFICULTY_WINDOW_V8 120 // (60)
9595
#define DIFFICULTY_BLOCKS_COUNT_V8 121 //DIFFICULTY_WINDOW_V8 + 1 has to be +1 so N = N
9696

97+
// LWMA difficulty V9
98+
#define DIFFICULTY_WINDOW_V9 120
99+
#define DIFFICULTY_BLOCKS_COUNT_V9 121
100+
#define CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V9 60*4
101+
#define BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V9 30
102+
#define DIFFICULTY_TARGET_V9 60 // seconds
103+
104+
97105
#define CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1 DIFFICULTY_TARGET_V1 * CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS
98106
#define CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 DIFFICULTY_TARGET_V2 * CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS
99107
#define CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS 1

0 commit comments

Comments
 (0)