Navigation Menu

Skip to content

Commit

Permalink
difficulty adjustment for PoS; mining & PoS validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Bitcoinx committed Jan 29, 2018
1 parent d62ee72 commit f66cb26
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 14 deletions.
3 changes: 3 additions & 0 deletions src/chainparams.cpp
Expand Up @@ -82,6 +82,7 @@ class CMainParams : public CChainParams {
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.nPosTargetSpacing = consensus.nPowTargetSpacing * 9 + 60;
consensus.nBtcPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
Expand Down Expand Up @@ -204,6 +205,7 @@ class CTestNetParams : public CChainParams {
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.nPosTargetSpacing = consensus.nPowTargetSpacing * 9 + 60;
consensus.nBtcPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = false;
Expand Down Expand Up @@ -315,6 +317,7 @@ class CRegTestParams : public CChainParams {
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 2.5 * 60;
consensus.nPosTargetSpacing = consensus.nPowTargetSpacing * 9 + 60;
consensus.nBtcPowTargetSpacing = 10 * 60;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = true;
Expand Down
1 change: 1 addition & 0 deletions src/consensus/params.h
Expand Up @@ -62,6 +62,7 @@ struct Params {
bool fPowAllowMinDifficultyBlocks;
bool fPowNoRetargeting;
int64_t nPowTargetSpacing;
int64_t nPosTargetSpacing;
int64_t nBtcPowTargetSpacing;
int64_t nPowTargetTimespan;
int64_t DifficultyAdjustmentInterval() const { return 1; }
Expand Down
14 changes: 7 additions & 7 deletions src/miner.cpp
Expand Up @@ -187,15 +187,15 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
pblock->nNonce = 0;
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);

CValidationState state;
if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) {
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state)));
}
int64_t nTime2 = GetTimeMicros();

if (nHeight > chainparams.GetConsensus().posHeight && !(nHeight % 10))
pblock->nVersion |= VERSIONBITS_POS;

else {
CValidationState state;
if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) {
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state)));
}
}
int64_t nTime2 = GetTimeMicros();

LogPrint(BCLog::BENCH, "CreateNewBlock() packages: %.2fms (%d packages, %d updated descendants), validity: %.2fms (total %.2fms)\n", 0.001 * (nTime1 - nTimeStart), nPackagesSelected, nDescendantsUpdated, 0.001 * (nTime2 - nTime1), 0.001 * (nTime2 - nTimeStart));

Expand Down
30 changes: 25 additions & 5 deletions src/pow.cpp
Expand Up @@ -12,10 +12,18 @@

static const int64_t DGWPastBlocksMax = 24;

const CBlockIndex* GetPrevPoS(const CBlockIndex* pindexLast, const Consensus::Params& params) {
auto cur = pindexLast;
while (cur != nullptr && cur->nHeight % 10) {
cur = cur->pprev;
}
return cur->nHeight > params.posHeight ? cur : nullptr;
}

static unsigned int DarkGravityWave(const CBlockIndex* pindexLast, const Consensus::Params& params, bool isHardfork) {
/* current difficulty formula, dash - DarkGravity v3, written by Evan Duffield - evan@dash.org */
if (pindexLast == nullptr) return UintToArith256(params.powLimit).GetCompact();
const CBlockIndex *BlockLastSolved = pindexLast;
const CBlockIndex *BlockReading = pindexLast;
int64_t nActualTimespan = 0;
int64_t LastBlockTime = 0;
int64_t PastBlocksMin = 24;
Expand All @@ -24,10 +32,19 @@ static unsigned int DarkGravityWave(const CBlockIndex* pindexLast, const Consens
arith_uint256 PastDifficultyAverage;
arith_uint256 PastDifficultyAveragePrev;

if (BlockLastSolved == NULL || BlockLastSolved->nHeight == 0 || BlockLastSolved->nHeight < PastBlocksMin) {
bool isNextPoS = !((pindexLast->nHeight + 1) % 10);
bool isPoSPeriod = (pindexLast->nHeight) > params.posHeight;

if (BlockLastSolved->nHeight == 0 || BlockLastSolved->nHeight < PastBlocksMin ||
(isPoSPeriod && isNextPoS && (BlockLastSolved->nHeight - params.posHeight) / 10 < PastBlocksMin)) {
return UintToArith256(params.powLimit).GetCompact();
}


if (isPoSPeriod && isNextPoS) {BlockLastSolved = GetPrevPoS(pindexLast, params); }
const CBlockIndex *BlockReading = BlockLastSolved;


for (unsigned int i = 1; BlockReading && BlockReading->nHeight > 0; i++) {
if (PastBlocksMax > 0 && i > PastBlocksMax) { break; }
CountBlocks++;
Expand All @@ -45,13 +62,16 @@ static unsigned int DarkGravityWave(const CBlockIndex* pindexLast, const Consens
LastBlockTime = BlockReading->GetBlockTime();

if (BlockReading->pprev == NULL) { assert(BlockReading); break; }
BlockReading = BlockReading->pprev;
BlockReading = isPoSPeriod ?
isNextPoS ? GetPrevPoS(BlockReading, params) :
BlockReading->pprev->IsProofOfStake() ? BlockReading->pprev->pprev : BlockReading->pprev
: BlockReading->pprev;
}

arith_uint256 bnNew(PastDifficultyAverage);

const auto powTargetSpacing = isHardfork ? params.nPowTargetSpacing : params.nBtcPowTargetSpacing;
int64_t _nTargetTimespan = CountBlocks * powTargetSpacing;
const auto targetSpacing = isHardfork ? isNextPoS && isPoSPeriod ? params.nPosTargetSpacing : params.nPowTargetSpacing : params.nBtcPowTargetSpacing;
int64_t _nTargetTimespan = (CountBlocks ? CountBlocks : 1) * targetSpacing;

if (nActualTimespan < _nTargetTimespan/3)
nActualTimespan = _nTargetTimespan/3;
Expand Down
5 changes: 3 additions & 2 deletions src/rpc/mining.cpp
Expand Up @@ -134,8 +134,9 @@ UniValue generateBlocks(std::shared_ptr<CReserveScript> coinbaseScript, int nGen
if (pwallet == nullptr)
throw JSONRPCError(RPC_INTERNAL_ERROR, "No wallet for staking");
--nMaxTries;
if (!CreatePoSBlock(pblock, *pwallet))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failed to create PoS block");
if (!CreatePoSBlock(pblock, *pwallet)) {
continue;
}
} else {
while (nMaxTries > 0 && pblock->nNonce < nInnerLoopCount && !CheckProofOfWork(pblock->GetHash(), pblock->nBits, Params().GetConsensus())) {
++pblock->nNonce;
Expand Down
5 changes: 5 additions & 0 deletions src/validation.cpp
Expand Up @@ -1841,6 +1841,11 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd
REJECT_INVALID, "bad-expected-pos");
}

if (pindex->nHeight % 10 && block.IsProofOfStake()) {
return state.DoS(1, error("ConnectBlock(): expected PoW block on height %d", pindex->nHeight),
REJECT_INVALID, "bad-expected-pos");
}

// verify that the view's current state corresponds to the previous block
uint256 hashPrevBlock = pindex->pprev == nullptr ? uint256() : pindex->pprev->GetBlockHash();
assert(hashPrevBlock == view.GetBestBlock());
Expand Down

0 comments on commit f66cb26

Please sign in to comment.