diff --git a/configure.ac b/configure.ac index 8dd93d44..7cbd31b0 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 9) define(_CLIENT_VERSION_REVISION, 2) -define(_CLIENT_VERSION_BUILD, 6) +define(_CLIENT_VERSION_BUILD, 7) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2014) AC_INIT([Myriadcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@bitcoin.org],[myriadcoin]) diff --git a/src/clientversion.h b/src/clientversion.h index 3ef980a7..6a332d55 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -12,7 +12,7 @@ #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 9 #define CLIENT_VERSION_REVISION 2 -#define CLIENT_VERSION_BUILD 6 +#define CLIENT_VERSION_BUILD 7 // Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/main.cpp b/src/main.cpp index 5b5f1f83..7dad16b8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1253,7 +1253,8 @@ static const int64_t nAveragingInterval = 10; // 10 blocks static const int64_t nAveragingTargetTimespan = nAveragingInterval * nTargetSpacing; // 25 minutes static const int64_t nMaxAdjustDown = 4; // 4% adjustment down -static const int64_t nMaxAdjustUp = 2; // 2% adjustment up +static const int64_t nMaxAdjustUpV1 = 2; // 2% adjustment up +static const int64_t nMaxAdjustUpV2 = 4; // 4% adjustment up static const int64_t nTargetTimespanAdjDown = nTargetTimespan * (100 + nMaxAdjustDown) / 100; @@ -1287,7 +1288,8 @@ unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime) return Params().ProofOfWorkLimit(ALGO_SHA256D).GetCompact(); } -static const int64_t nMinActualTimespan = nAveragingTargetTimespan * (100 - nMaxAdjustUp) / 100; +static const int64_t nMinActualTimespanV1 = nAveragingTargetTimespan * (100 - nMaxAdjustUpV1) / 100; +static const int64_t nMinActualTimespanV2 = nAveragingTargetTimespan * (100 - nMaxAdjustUpV2) / 100; static const int64_t nMaxActualTimespan = nAveragingTargetTimespan * (100 + nMaxAdjustDown) / 100; unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, int algo) @@ -1321,6 +1323,41 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead return nProofOfWorkLimit; const CBlockIndex* pindexFirst = NULL; + + if (pindexLast->nHeight >= nBlockTimeWarpPreventStart2) + { + // find first block in averaging interval + // Go back by what we want to be nAveragingInterval blocks + pindexFirst = pindexPrev; + for (int i = 0; pindexFirst && i < nAveragingInterval - 1; i++) + { + pindexFirst = pindexFirst->pprev; + pindexFirst = GetLastBlockIndexForAlgo(pindexFirst, algo); + } + if (pindexFirst == NULL) + return nProofOfWorkLimit; // not nAveragingInterval blocks of this algo available + + const CBlockIndex* pindexFirstPrev; + for ( ;; ) + { + // check blocks before first block for time warp + pindexFirstPrev = pindexFirst->pprev; + if (pindexFirstPrev == NULL) + return nProofOfWorkLimit; + pindexFirstPrev = GetLastBlockIndexForAlgo(pindexFirstPrev, algo); + if (pindexFirstPrev == NULL) + return nProofOfWorkLimit; + // take previous block if block times are out of order + if (pindexFirstPrev->GetBlockTime() > pindexFirst->GetBlockTime()) + { + LogPrintf(" First blocks out of order times, swapping: %d %d\n", pindexFirstPrev->GetBlockTime(), pindexFirst->GetBlockTime()); + pindexFirst = pindexFirstPrev; + } + else + break; + } + } + else if (pindexLast->nHeight >= nBlockTimeWarpPreventStart) { // find first block in averaging interval @@ -1368,7 +1405,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead LogPrintf(" nActualTimespan = %d before bounds %d %d\n", nActualTimespan, pindexPrev->GetBlockTime(), pindexFirst->GetBlockTime()); // Time warp mitigation: Don't adjust difficulty if time is negative - if (pindexLast->nHeight >= nBlockTimeWarpPreventStart) + if ( (pindexLast->nHeight >= nBlockTimeWarpPreventStart) && + (pindexLast->nHeight < nBlockTimeWarpPreventStart2) ) { if (nActualTimespan < 0) { @@ -1378,6 +1416,12 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead } } + int64_t nMinActualTimespan; + if (pindexLast->nHeight >= nBlockDiffAdjustV2) + nMinActualTimespan = nMinActualTimespanV2; + else + nMinActualTimespan = nMinActualTimespanV1; + if (nActualTimespan < nMinActualTimespan) nActualTimespan = nMinActualTimespan; if (nActualTimespan > nMaxActualTimespan) @@ -2507,6 +2551,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp) nAlgoCount++; piPrev = piPrev->pprev; } + if ((nHeight > nBlockSequentialAlgoRuleStart2) && (nAlgoCount > nBlockSequentialAlgoMaxCount2)) + { + return state.DoS(100, error("AcceptBlock() : too many blocks from same algo"), + REJECT_INVALID, "algo-toomany"); + } else if (nAlgoCount > nBlockSequentialAlgoMaxCount) { return state.DoS(100, error("AcceptBlock() : too many blocks from same algo"), diff --git a/src/main.h b/src/main.h index 45594150..5d04d1a0 100644 --- a/src/main.h +++ b/src/main.h @@ -690,8 +690,12 @@ enum BlockStatus { const int64_t nBlockAlgoWorkWeightStart = 142000; // block where algo work weighting starts const int64_t nBlockAlgoNormalisedWorkStart = 740000; // block where algo combined weight starts const int64_t nBlockSequentialAlgoRuleStart = 740000; // block where sequential algo rule starts +const int64_t nBlockSequentialAlgoRuleStart2 = 766000; // block where sequential algo rule starts const int nBlockSequentialAlgoMaxCount = 6; // maximum sequential blocks of same algo -const int64_t nBlockTimeWarpPreventStart = 740500; // block where sequential algo rule starts +const int nBlockSequentialAlgoMaxCount2 = 3; // maximum sequential blocks of same algo +const int64_t nBlockTimeWarpPreventStart = 740500; // block where time warp 1 prevention starts +const int64_t nBlockTimeWarpPreventStart2 = 766000; // block where time warp 2 prevention starts +const int64_t nBlockDiffAdjustV2 = 766000; // block where difficulty adjust V2 starts /** The block chain is a tree shaped structure starting with the * genesis block at the root, with each block potentially having multiple