From: Sunny King Date: Mon, 16 Apr 2012 22:11:12 +0000 (+0100) Subject: PPCoin: target adjustment for both proof-of-work and proof-of-stake X-Git-Tag: v0.4.0-unstable~192 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=32e6e50a33afc8ba023bb1b4e01ba9e868a3c884 PPCoin: target adjustment for both proof-of-work and proof-of-stake --- diff --git a/src/db.cpp b/src/db.cpp index 6eece05..d4dae8d 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -540,6 +540,8 @@ bool CTxDB::LoadBlockIndex() pindexNew->nBlockPos = diskindex.nBlockPos; pindexNew->nChainTrust = diskindex.nChainTrust; pindexNew->nHeight = diskindex.nHeight; + pindexNew->nCheckpoint = diskindex.nCheckpoint; + pindexNew->fProofOfStake = diskindex.fProofOfStake; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; pindexNew->nTime = diskindex.nTime; diff --git a/src/main.cpp b/src/main.cpp index 950b893..818c677 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -731,13 +731,27 @@ unsigned int ComputeMinWork(unsigned int nBase, int64 nTime) return bnResult.GetCompact(); } -unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast) +// ppcoin: find last block index up to pindex +const CBlockIndex* GetLastBlockIndex(const CBlockIndex* pindex, bool fProofOfStake) +{ + while (pindex && (pindex->IsProofOfStake() != fProofOfStake)) + pindex = pindex->pprev; + return pindex; +} + +unsigned int static GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake) { // Genesis block and first block if (pindexLast == NULL || pindexLast->pprev == NULL) return bnProofOfWorkLimit.GetCompact(); - int64 nActualSpacing = pindexLast->GetBlockTime() - pindexLast->pprev->GetBlockTime(); + const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake); + if (pindexPrev == NULL) + return bnProofOfWorkLimit.GetCompact(); + const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake); + if (pindexPrevPrev == NULL) + return bnProofOfWorkLimit.GetCompact(); + int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime(); // ppcoin: target change every block // ppcoin: retarget with exponential moving toward target spacing @@ -1527,8 +1541,8 @@ bool CBlock::AcceptBlock() int nHeight = pindexPrev->nHeight+1; // Check proof of work - if (nBits != GetNextWorkRequired(pindexPrev)) - return DoS(100, error("AcceptBlock() : incorrect proof of work")); + if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake())) + return DoS(100, error("AcceptBlock() : incorrect proof-of-work/proof-of-stake")); // Check timestamp against prev if (GetBlockTime() <= pindexPrev->GetMedianTimePast() || GetBlockTime() + nMaxClockDrift < pindexPrev->GetBlockTime()) @@ -2958,8 +2972,6 @@ CBlock* CreateNewBlock(CWallet* pwallet) if (!pblock.get()) return NULL; - pblock->nBits = GetNextWorkRequired(pindexPrev); - // Create coinbase tx CTransaction txNew; txNew.vin.resize(1); @@ -2971,9 +2983,12 @@ CBlock* CreateNewBlock(CWallet* pwallet) pblock->vtx.push_back(txNew); // ppcoin: if coinstake available add coinstake tx + pblock->nBits = GetNextTargetRequired(pindexPrev, true); CTransaction txCoinStake; if (pwallet->CreateCoinStake(txNew.vout[0].scriptPubKey, pblock->nBits, txCoinStake)) pblock->vtx.push_back(txCoinStake); + else + pblock->nBits = GetNextTargetRequired(pindexPrev, false); // Collect memory pool transactions into the block int64 nFees = 0; diff --git a/src/main.h b/src/main.h index ea73a0f..4e82e1b 100644 --- a/src/main.h +++ b/src/main.h @@ -1116,6 +1116,7 @@ public: uint64 nChainTrust;// ppcoin: trust score of chain, in the unit of coin-days int nHeight; int nCheckpoint; // ppcoin: chain auto checkpoint height + bool fProofOfStake; // ppcoin: is the block of proof-of-stake type // block header int nVersion; @@ -1135,6 +1136,7 @@ public: nHeight = 0; nChainTrust = 0; nCheckpoint = 0; + fProofOfStake = true; nVersion = 0; hashMerkleRoot = 0; @@ -1153,6 +1155,7 @@ public: nHeight = 0; nChainTrust = 0; nCheckpoint = 0; + fProofOfStake = block.IsProofOfStake(); nVersion = block.nVersion; hashMerkleRoot = block.hashMerkleRoot; @@ -1242,12 +1245,20 @@ public: return pindex->GetMedianTimePast(); } + bool IsProofOfWork() const + { + return !fProofOfStake; + } + bool IsProofOfStake() const + { + return fProofOfStake; + } std::string ToString() const { - return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nChainTrust=%"PRI64d" nHeight=%d, nCheckpoint=%d, merkle=%s, hashBlock=%s)", - pprev, pnext, nFile, nBlockPos, nChainTrust, nHeight, nCheckpoint, + return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nChainTrust=%"PRI64d" nHeight=%d, nCheckpoint=%d, fProofOfStake=%d merkle=%s, hashBlock=%s)", + pprev, pnext, nFile, nBlockPos, nChainTrust, nHeight, nCheckpoint, fProofOfStake, hashMerkleRoot.ToString().substr(0,10).c_str(), GetBlockHash().ToString().substr(0,20).c_str()); } @@ -1292,6 +1303,7 @@ public: READWRITE(nChainTrust); READWRITE(nHeight); READWRITE(nCheckpoint); + READWRITE(fProofOfStake); // block header READWRITE(this->nVersion);