Update difficulty retarget to KGW and DGWv3.

This commit is contained in:
vertoe 2014-12-04 12:47:48 +01:00
parent a63a38bed1
commit 3d65ce730c
2 changed files with 115 additions and 69 deletions

View File

@ -1387,7 +1387,7 @@ unsigned int static KimotoGravityWell(const CBlockIndex* pindexLast, const CBloc
return bnNew.GetCompact();
}
unsigned int static DarkGravityWave3(const CBlockIndex* pindexLast, const CBlockHeader *pblock) {
unsigned int static DarkGravityWave(const CBlockIndex* pindexLast, const CBlockHeader *pblock) {
/* current difficulty formula, darkcoin - DarkGravity v3, written by Evan Duffield - evan@darkcoin.io */
const CBlockIndex *BlockLastSolved = pindexLast;
const CBlockIndex *BlockReading = pindexLast;
@ -1427,16 +1427,16 @@ unsigned int static DarkGravityWave3(const CBlockIndex* pindexLast, const CBlock
CBigNum bnNew(PastDifficultyAverage);
int64_t nTargetTimespan = CountBlocks*nTargetSpacing;
int64_t _nTargetTimespan = CountBlocks*nTargetSpacing;
if (nActualTimespan < nTargetTimespan/3)
nActualTimespan = nTargetTimespan/3;
if (nActualTimespan > nTargetTimespan*3)
nActualTimespan = nTargetTimespan*3;
if (nActualTimespan < _nTargetTimespan/3)
nActualTimespan = _nTargetTimespan/3;
if (nActualTimespan > _nTargetTimespan*3)
nActualTimespan = _nTargetTimespan*3;
// Retarget
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
bnNew /= _nTargetTimespan;
if (bnNew > Params().ProofOfWorkLimit()){
bnNew = Params().ProofOfWorkLimit();
@ -1447,64 +1447,113 @@ unsigned int static DarkGravityWave3(const CBlockIndex* pindexLast, const CBlock
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
uint retarget = DIFF_BTC;
// Genesis block
if (pindexLast == NULL)
return nProofOfWorkLimit;
// Only change once per interval
if ((pindexLast->nHeight+1) % nInterval != 0)
{
if (TestNet())
{
// 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 (pblock->nTime > pindexLast->nTime + nTargetSpacing*2)
return nProofOfWorkLimit;
else
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex* pindex = pindexLast;
while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
pindex = pindex->pprev;
return pindex->nBits;
}
if (TestNet()) {
if (pindexLast->nHeight + 1 >= 256) retarget = DIFF_DGW;
}
else {
if (pindexLast->nHeight + 1 >= 34140) retarget = DIFF_DGW;
else if (pindexLast->nHeight + 1 >= 15200) retarget = DIFF_KGW;
}
return pindexLast->nBits;
}
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
for (int i = 0; pindexFirst && i < nInterval-1; i++)
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);
// Default Bitcoin style retargeting
if (retarget == DIFF_BTC)
{
unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();
// Limit adjustment step
int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < nTargetTimespan/4)
nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
nActualTimespan = nTargetTimespan*4;
// Genesis block
if (pindexLast == NULL)
return nProofOfWorkLimit;
// Retarget
CBigNum bnNew;
bnNew.SetCompact(pindexLast->nBits);
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
// Only change once per interval
if ((pindexLast->nHeight+1) % nInterval != 0)
{
// Special difficulty rule for testnet:
if (TestNet())
{
// If the new block's timestamp is more than 2* 10 minutes
// then allow mining of a min-difficulty block.
if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2)
return nProofOfWorkLimit;
else
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex* pindex = pindexLast;
while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
pindex = pindex->pprev;
return pindex->nBits;
}
}
return pindexLast->nBits;
}
if (bnNew > Params().ProofOfWorkLimit())
bnNew = Params().ProofOfWorkLimit();
// Darkcoin: This fixes an issue where a 51% attack can change difficulty at will.
// Go back the full period unless it's the first retarget after genesis.
// Code courtesy of Art Forz.
int blockstogoback = nInterval-1;
if ((pindexLast->nHeight+1) != nInterval)
blockstogoback = nInterval;
/// debug print
LogPrintf("GetNextWorkRequired RETARGET\n");
LogPrintf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
LogPrintf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString());
LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString());
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
for (int i = 0; pindexFirst && i < blockstogoback; i++)
//for (int i = 0; pindexFirst && i < nInterval-1; i++)
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);
return bnNew.GetCompact();
// Limit adjustment step
//int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
//LogPrintf(" nActualTimespan = %"PRI64d" before bounds\n", nActualTimespan);
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < nTargetTimespan/4)
nActualTimespan = nTargetTimespan/4;
if (nActualTimespan > nTargetTimespan*4)
nActualTimespan = nTargetTimespan*4;
// Retarget
CBigNum bnNew;
bnNew.SetCompact(pindexLast->nBits);
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;
if (bnNew > Params().ProofOfWorkLimit())
bnNew = Params().ProofOfWorkLimit();
/// debug print
LogPrintf("GetNextWorkRequired RETARGET\n");
//LogPrintf("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
LogPrintf("nTargetTimespan = %d nActualTimespan = %d\n", nTargetTimespan, nActualTimespan);
//LogPrintf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
LogPrintf("Before: %08x %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString());
//LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());
LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString());
return bnNew.GetCompact();
}
// Retarget using Kimoto Gravity Wave
else if (retarget == DIFF_KGW)
{
static const uint64_t blocksTargetSpacing = 2.5 * 60; // 2.5 minutes
static const unsigned int timeDaySeconds = 60 * 60 * 24;
uint64_t pastSecondsMin = timeDaySeconds * 0.025;
uint64_t pastSecondsMax = timeDaySeconds * 7;
uint64_t pastBlocksMin = pastSecondsMin / blocksTargetSpacing;
uint64_t pastBlocksMax = pastSecondsMax / blocksTargetSpacing;
return KimotoGravityWell(pindexLast, pblock, blocksTargetSpacing, pastBlocksMin, pastBlocksMax);
}
// Retarget using Dark Gravity Wave 3
else if (retarget == DIFF_DGW)
{
return DarkGravityWave(pindexLast, pblock);
}
return DarkGravityWave(pindexLast, pblock);
}
bool CheckProofOfWork(uint256 hash, unsigned int nBits)
@ -1685,16 +1734,6 @@ void UpdateTime(CBlockHeader& block, const CBlockIndex* pindexPrev)
block.nBits = GetNextWorkRequired(pindexPrev, &block);
}
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight, const uint256 &txhash)
{
bool ret;
@ -1813,8 +1852,6 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, CCoinsViewCach
return true;
}
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
{
assert(pindex->GetBlockHash() == view.GetBestBlock());

View File

@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014 vertoe & the Darkcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -32,6 +33,14 @@
#define START_MASTERNODE_PAYMENTS_TESTNET 1403568776 //Tue, 24 Jun 2014 00:12:56 GMT
#define START_MASTERNODE_PAYMENTS 1403728576 //Wed, 25 Jun 2014 20:36:16 GMT
// Define difficulty retarget algorithms
enum DiffMode {
DIFF_DEFAULT = 0, // Default to invalid 0
DIFF_BTC = 1, // Retarget every x blocks (Bitcoin style)
DIFF_KGW = 2, // Retarget using Kimoto Gravity Well
DIFF_DGW = 3, // Retarget using Dark Gravity Wave v3
};
class CBlockIndex;
class CBloomFilter;
class CInv;