Skip to content

Instantly share code, notes, and snippets.

@itwysgsl
Last active October 25, 2018 18:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itwysgsl/f181dfc0de3a3fee8645ee886e2b0b44 to your computer and use it in GitHub Desktop.
Save itwysgsl/f181dfc0de3a3fee8645ee886e2b0b44 to your computer and use it in GitHub Desktop.
// Copyright (c) 2017-2018 The Bitcoin Gold developers
// Copyright (c) 2018 Zawy & MicroBitcoin (LWMA-3)
// Algorithm by zawy, a modification of WT-144 by Tom Harding
// https://github.com/zawy12/difficulty-algorithms/issues/3#issuecomment-388386175
// Updated to LWMA3 by iamstenman
// MIT License
unsigned int Lwma3CalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params)
{
const int64_t T = params.nPowTargetSpacing;
const int64_t N = params.lwmaAveragingWindow;
const int64_t k = N * (N + 1) * T / 2;
const int64_t height = pindexLast->nHeight;
const arith_uint256 powLimit = UintToArith256(params.powLimit);
if (height < N) { return powLimit.GetCompact(); }
arith_uint256 sumTarget, previousDiff, nextTarget;
int64_t thisTimestamp, previousTimestamp;
int64_t t = 0, j = 0, solvetimeSum = 0;
const CBlockIndex* blockPreviousTimestamp = pindexLast->GetAncestor(height - N);
previousTimestamp = blockPreviousTimestamp->GetBlockTime();
// Loop through N most recent blocks.
for (int64_t i = height - N + 1; i <= height; i++) {
const CBlockIndex* block = pindexLast->GetAncestor(i);
thisTimestamp = (block->GetBlockTime() > previousTimestamp) ? block->GetBlockTime() : previousTimestamp + 1;
int64_t solvetime = std::min(6 * T, thisTimestamp - previousTimestamp);
previousTimestamp = thisTimestamp;
j++;
t += solvetime * j; // Weighted solvetime sum.
arith_uint256 target;
target.SetCompact(block->nBits);
sumTarget += target / (k * N);
if (i > height - 3) { solvetimeSum += solvetime; }
if (i == height) { previousDiff = target.SetCompact(block->nBits); }
}
nextTarget = t * sumTarget;
if (nextTarget > (previousDiff * 150) / 100) { nextTarget = (previousDiff * 150) / 100; }
if ((previousDiff * 67) / 100 > nextTarget) { nextTarget = (previousDiff * 67); }
if (solvetimeSum < (8 * T) / 10) { nextTarget = previousDiff * 100 / 106; }
if (nextTarget > powLimit) { nextTarget = powLimit; }
return nextTarget.GetCompact();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment