Skip to content

Commit

Permalink
Add Zawy's LWMA difficulty adjustment algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
h4x3rotab committed Mar 7, 2018
1 parent d2b252b commit 8fd3da7
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 3 deletions.
14 changes: 14 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "base58.h"
#include <assert.h>
#include <boost/assign/list_of.hpp>
#include <limits>

#include "chainparamsseeds.h"

Expand Down Expand Up @@ -99,6 +100,7 @@ class CMainParams : public CChainParams {
consensus.BIP66Height = 363725; // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931
consensus.BTGHeight = 491407; // Around 10/25/2017 12:00 UTC
consensus.BTGPremineWindow = 8000;
consensus.BTGZawyLWMAHeight = std::numeric_limits<int>::max(); // Not activated on mainnet
consensus.BTGPremineEnforceWhitelist = true;
consensus.powLimit = uint256S("0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.powLimitStart = uint256S("0000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
Expand All @@ -108,6 +110,9 @@ class CMainParams : public CChainParams {
assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nDigishieldAveragingWindow);
consensus.nDigishieldMaxAdjustDown = 32;
consensus.nDigishieldMaxAdjustUp = 16;

consensus.nZawyLwmaAveragingWindow = 45;
consensus.nZawyLwmaAjustedWeight = 13632;

consensus.nPowTargetTimespanLegacy = 14 * 24 * 60 * 60;; // 10 minutes
consensus.nPowTargetSpacing = 10 * 60;
Expand Down Expand Up @@ -224,6 +229,7 @@ class CTestNetParams : public CChainParams {
consensus.BIP65Height = 581885; // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
consensus.BIP66Height = 330776; // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
consensus.BTGHeight = 1210320;
consensus.BTGZawyLWMAHeight = -1; // Activated on testnet
consensus.BTGPremineWindow = 50;
consensus.BTGPremineEnforceWhitelist = false;
consensus.powLimit = uint256S("0007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
Expand All @@ -234,6 +240,9 @@ class CTestNetParams : public CChainParams {
assert(maxUint/UintToArith256(consensus.powLimit) >= consensus.nDigishieldAveragingWindow);
consensus.nDigishieldMaxAdjustDown = 32;
consensus.nDigishieldMaxAdjustUp = 16;

consensus.nZawyLwmaAveragingWindow = 45;
consensus.nZawyLwmaAjustedWeight = 13632;

consensus.nPowTargetTimespanLegacy = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
Expand Down Expand Up @@ -325,6 +334,7 @@ class CRegTestParams : public CChainParams {
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
consensus.BTGHeight = 3000;
consensus.BTGZawyLWMAHeight = -1; // Activated on regtest
consensus.BTGPremineWindow = 10;
consensus.BTGPremineEnforceWhitelist = false;
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
Expand All @@ -334,6 +344,10 @@ class CRegTestParams : public CChainParams {
consensus.nDigishieldAveragingWindow = 30;
consensus.nDigishieldMaxAdjustDown = 32;
consensus.nDigishieldMaxAdjustUp = 16;

consensus.nZawyLwmaAveragingWindow = 45;
consensus.nZawyLwmaAjustedWeight = 13632;

consensus.nPowTargetTimespanLegacy = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
Expand Down
8 changes: 7 additions & 1 deletion src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ struct Params {
int BIP66Height;
/** Block height at which Bitcoin GPU hard fork becomes active */
int BTGHeight;
/** Block height at which Zawy's LWMA difficulty algorithm becomes active */
int BTGZawyLWMAHeight;
/** Premining blocks for Bitcoin GPU hard fork **/
int BTGPremineWindow;
bool BTGPremineEnforceWhitelist;
Expand Down Expand Up @@ -84,7 +86,11 @@ struct Params {
int64_t DigishieldMaxActualTimespan() const {
return (DigishieldAveragingWindowTimespan() * (100 + nDigishieldMaxAdjustDown)) / 100;
}


// Params for Zawy's LWMA difficulty adjustment algorithm. (Used by testnet and regtest)
int64_t nZawyLwmaAveragingWindow; // N
int64_t nZawyLwmaAjustedWeight; // k = (N+1)/2 * 0.9989^(500/N) * T


};
} // namespace Consensus
Expand Down
65 changes: 63 additions & 2 deletions src/pow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,70 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
// Pow limit start for warm-up period.
return UintToArith256(params.powLimitStart).GetCompact();
}
else if (nHeight < params.BTGZawyLWMAHeight) {
// Regular Digishield v3.
return DigishieldGetNextWorkRequired(pindexLast, pblock, params);
} else {
// Zawy's LWMA.
return LwmaGetNextWorkRequired(pindexLast, pblock, params);
}
}

unsigned int LwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
// Special difficulty rule for testnet:
// If the new block's timestamp is more than 2 * 10 minutes
// then allow mining of a min-difficulty block.
if (params.fPowAllowMinDifficultyBlocks &&
pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing * 2) {
return UintToArith256(params.PowLimit(true)).GetCompact();
}
return LwmaCalculateNextWorkRequired(pindexLast, params);
}

unsigned int LwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params)
{
if (params.fPowNoRetargeting) {
return pindexLast->nBits;
}

const int T = params.nPowTargetSpacing;
const int N = params.nZawyLwmaAveragingWindow;
const int k = params.nZawyLwmaAjustedWeight;
const int height = pindexLast->nHeight + 1;
assert(height > N);

arith_uint256 sum_target;
int t = 0, j = 0;

// Loop through N most recent blocks.
for (int i = height - N; i < height; i++) {
const CBlockIndex* block = pindexLast->GetAncestor(i);
const CBlockIndex* block_Prev = block->GetAncestor(i - 1);
int64_t solvetime = block->GetBlockTime() - block_Prev->GetBlockTime();

if (solvetime > 6 * T) { solvetime = 6 * T; }
if (solvetime < -5 * T) { solvetime = -5 * T; }

j++;
t += solvetime * j;

arith_uint256 target;
target.SetCompact(block->nBits);
sum_target += target / k;
}
// Keep t reasonable in case strange solvetimes occurred.
if (t < N * k / 3) {
t = N * k / 3;
}

const arith_uint256 pow_limit = UintToArith256(params.PowLimit(true));
arith_uint256 next_target = t * sum_target;
if (next_target > pow_limit) {
next_target = pow_limit;
}

// Regular Digishield v3.
return DigishieldGetNextWorkRequired(pindexLast, pblock, params);
return next_target.GetCompact();
}

unsigned int DigishieldGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock,
Expand Down
4 changes: 4 additions & 0 deletions src/pow.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class uint256;
/** PoW algorithm entry. */
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);

/** Zawy's LWMA - next generation algorithm for testnet currently */
unsigned int LwmaGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
unsigned int LwmaCalculateNextWorkRequired(const CBlockIndex* pindexLast, const Consensus::Params& params);

/** Digishield v3 - used in Bitcoin Gold mainnet currently */
unsigned int DigishieldGetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
unsigned int DigishieldCalculateNextWorkRequired(arith_uint256 bnAvg, const CBlockIndex* pindexLast, const CBlockIndex* pindexFirst, const Consensus::Params& params);
Expand Down

0 comments on commit 8fd3da7

Please sign in to comment.