From: Sunny King Date: Fri, 6 Jan 2012 03:09:03 +0000 (+0000) Subject: PPCoin: Additional block/coinbase timestamp rules; various minor cleanups X-Git-Tag: v0.4.0-unstable~215 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=36f387a8006ad1ba91d19eff7ed78a1fbf4b658a PPCoin: Additional block/coinbase timestamp rules; various minor cleanups --- diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 8898ca1..69024e2 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -59,13 +59,13 @@ namespace Checkpoints return error("Checkpoints: failed to find any ancestor on main chain for the new block - internal error"); } - // ppcoin: get next auto checkpoint in the chain + // ppcoin: get next chain checkpoint int GetNextChainCheckpoint(const CBlockIndex *pindexLast) { CBigNum bnTarget; CBigNum bnTargetMax = 0; // max target of all blocks since checkpoint CBigNum bnTargetMin = 0; // min target of all candidate checkpoints - int nMinTargetHeight = 0; // min target height since checkpoint + int nMinTargetHeight = 0; // min target height of candidate checkpoints int nCheckpointMin = 0; // minimum candidate checkpoint int nCheckpointMax = 0; // maximum candidate checkpoint int nDepth = pindexLast->nHeight - pindexLast->nCheckpoint; @@ -103,15 +103,21 @@ namespace Checkpoints if (bnTargetMin * 100 > bnTargetMax * 90) return nCheckpointMax; if (bnTarget * 100 > bnTargetMax * 90) - return std::min(nCheckpointMax, nMinTargetHeight); + return nMinTargetHeight; else return nCheckpointMin; } + // ppcoin: get next auto checkpoint from the new chain checkpoint + int GetNextAutoCheckpoint(int nCheckpoint) + { + return (std::max(nAutoCheckpoint, nCheckpoint)); + } + // ppcoin: advance to next automatic checkpoint void AdvanceAutoCheckpoint(int nCheckpoint) { - nAutoCheckpoint = std::max(nAutoCheckpoint, nCheckpoint); + nAutoCheckpoint = GetNextAutoCheckpoint(nCheckpoint); printf("Checkpoints: auto checkpoint now at height=%d\n", nAutoCheckpoint); } diff --git a/src/checkpoints.h b/src/checkpoints.h index 21a4b4a..241039d 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -29,6 +29,7 @@ namespace Checkpoints bool CheckAuto(const CBlockIndex *pindex); int GetNextChainCheckpoint(const CBlockIndex *pindex); + int GetNextAutoCheckpoint(int nCheckpoint); void AdvanceAutoCheckpoint(int nCheckpoint); // Return conservative estimate of total number of blocks, 0 if unknown diff --git a/src/main.cpp b/src/main.cpp index f44e7f5..38f2a93 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -668,7 +668,7 @@ int64 static GetBlockValue(unsigned int nBits, int64 nFees) CBigNum bnMidValue = (bnLowerBound + bnUpperBound) / 2; if (fDebug && GetBoolArg("-printcreation")) printf("GetBlockValue() : lower=%d upper=%d mid=%d\n", bnLowerBound.getint(), bnUpperBound.getint(), bnMidValue.getint()); - if (bnMidValue * bnMidValue * bnMidValue * bnMidValue > bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnTarget / bnTargetLimit) + if (bnMidValue * bnMidValue * bnMidValue * bnMidValue * bnTargetLimit > bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnSubsidyLimit * bnTarget) bnUpperBound = bnMidValue; else bnLowerBound = bnMidValue; @@ -685,6 +685,7 @@ int64 static GetBlockValue(unsigned int nBits, int64 nFees) static const int64 nTargetTimespan = 7 * 24 * 60 * 60; // one week static const int64 nTargetSpacing = 10 * 60; static const int64 nInterval = nTargetTimespan / nTargetSpacing; +static const int64 nMaxClockDrift = 2 * 60 * 60; // 2 hours // // minimum amount of work that could possibly be required nTime after @@ -1124,7 +1125,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) } if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) return error("Reorganize() : WriteHashBestChain failed"); - if (!txdb.WriteAutoCheckpoint(pindexNew->nCheckpoint)) + if (!txdb.WriteAutoCheckpoint(Checkpoints::GetNextAutoCheckpoint(pindexNew->nCheckpoint))) return error("Reorganize() : WriteAutoCheckpoint failed"); // Make sure it's successfully written to disk before changing memory structure @@ -1161,7 +1162,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) if (pindexGenesisBlock == NULL && hash == hashGenesisBlock) { txdb.WriteHashBestChain(hash); - txdb.WriteAutoCheckpoint(pindexNew->nCheckpoint); + txdb.WriteAutoCheckpoint(Checkpoints::GetNextAutoCheckpoint(pindexNew->nCheckpoint)); if (!txdb.TxnCommit()) return error("SetBestChain() : TxnCommit failed"); pindexGenesisBlock = pindexNew; @@ -1169,7 +1170,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) else if (hashPrevBlock == hashBestChain) { // Adding to current best branch - if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash) || !txdb.WriteAutoCheckpoint(pindexNew->nCheckpoint)) + if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash) || !txdb.WriteAutoCheckpoint(Checkpoints::GetNextAutoCheckpoint(pindexNew->nCheckpoint))) { txdb.TxnAbort(); InvalidChainFound(pindexNew); @@ -1340,7 +1341,7 @@ bool CBlock::CheckBlock() const return DoS(50, error("CheckBlock() : proof of work failed")); // Check timestamp - if (GetBlockTime() > GetAdjustedTime() + 2 * 60 * 60) + if (GetBlockTime() > GetAdjustedTime() + nMaxClockDrift) return error("CheckBlock() : block timestamp too far in the future"); // First transaction must be coinbase, the rest must not be @@ -1350,6 +1351,10 @@ bool CBlock::CheckBlock() const if (vtx[i].IsCoinBase()) return DoS(100, error("CheckBlock() : more than one coinbase")); + // Check coinbase timestamp + if (GetBlockTime() > (int64)vtx[0].nTime + nMaxClockDrift) + return DoS(50, error("CheckBlock() : coinbase timestamp is too early")); + // Check transactions BOOST_FOREACH(const CTransaction& tx, vtx) { @@ -1390,7 +1395,7 @@ bool CBlock::AcceptBlock() return DoS(100, error("AcceptBlock() : incorrect proof of work")); // Check timestamp against prev - if (GetBlockTime() <= pindexPrev->GetMedianTimePast()) + if (GetBlockTime() <= pindexPrev->GetMedianTimePast() || GetBlockTime() + nMaxClockDrift < pindexPrev->GetBlockTime()) return error("AcceptBlock() : block's timestamp is too early"); // Check that all transactions are finalized @@ -1610,7 +1615,7 @@ bool LoadBlockIndex(bool fAllowNew) txNew.vin.resize(1); txNew.vout.resize(1); txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(4) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); - txNew.vout[0].nValue = 9999 * COIN; + txNew.vout[0].nValue = GetBlockValue(bnProofOfWorkLimit.GetCompact(), 0); txNew.vout[0].scriptPubKey = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; CBlock block; block.vtx.push_back(txNew); @@ -2948,6 +2953,7 @@ CBlock* CreateNewBlock(CReserveKey& reservekey) pblock->hashMerkleRoot = pblock->BuildMerkleTree(); pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); pblock->nTime = max(pblock->GetBlockTime(), pblock->GetMaxTransactionTime()); + pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift); pblock->nNonce = 0; return pblock.release(); @@ -3191,7 +3197,10 @@ void static BitcoinMiner(CWallet *pwallet) // Update nTime every few seconds pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); pblock->nTime = max(pblock->GetBlockTime(), pblock->GetMaxTransactionTime()); + pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift); nBlockTime = ByteReverse(pblock->nTime); + if (pblock->GetBlockTime() >= (int64)pblock->vtx[0].nTime + nMaxClockDrift) + break; // need to update coinbase timestamp } } }