From: Scott Nadal Date: Wed, 2 May 2012 14:53:33 +0000 (+0100) Subject: PPCoin: Preliminary checks on proof-of-stake duplicates X-Git-Tag: v0.4.0-unstable~174 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=80cc04c8aca5ce6ca38dca0e5dc2bf422e570f2d PPCoin: Preliminary checks on proof-of-stake duplicates --- diff --git a/src/main.cpp b/src/main.cpp index 111c2ff..a857edc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,6 +45,7 @@ CMedianFilter cPeerBlockCounts(5, 0); // Amount of blocks that other nodes map mapOrphanBlocks; multimap mapOrphanBlocksByPrev; +set setStakeSeenOrphan; map mapOrphanTransactions; multimap mapOrphanTransactionsByPrev; @@ -1286,7 +1287,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) // ppcoin: coinstake must meet hash target according to the protocol: -// at least one input must meet the formula +// input 0 must meet the formula // hash(nBits + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget * nCoinDay // this ensures that the chance of getting a coinstake is proportional to the // amount of coin age one owns. @@ -1423,6 +1424,8 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) if (!pindexNew) return error("AddToBlockIndex() : new CBlockIndex failed"); map::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + if (pindexNew->fProofOfStake) + setStakeSeen.insert(pindexNew->prevoutStake); pindexNew->phashBlock = &((*mi).first); map::iterator miPrev = mapBlockIndex.find(hashPrevBlock); @@ -1612,6 +1615,10 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) if (mapOrphanBlocks.count(hash)) return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str()); + // ppcoin: check proof-of-stake + if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake())) + return error("ProcessBlock() : duplicate proof-of-stake (%s) for block %s", pblock->GetProofOfStake().ToString().c_str(), hash.ToString().c_str()); + // Preliminary checks if (!pblock->CheckBlock()) return error("ProcessBlock() : CheckBlock FAILED"); @@ -1643,6 +1650,14 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) { printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str()); CBlock* pblock2 = new CBlock(*pblock); + // ppcoin: check proof-of-stake + if (pblock2->IsProofOfStake()) + { + if (setStakeSeenOrphan.count(pblock2->GetProofOfStake())) + return error("ProcessBlock() : duplicate proof-of-stake (%s) for orphan block %s", pblock2->GetProofOfStake().ToString().c_str(), hash.ToString().c_str()); + else + setStakeSeenOrphan.insert(pblock2->GetProofOfStake()); + } mapOrphanBlocks.insert(make_pair(hash, pblock2)); mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2)); @@ -1670,6 +1685,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) if (pblockOrphan->AcceptBlock()) vWorkQueue.push_back(pblockOrphan->GetHash()); mapOrphanBlocks.erase(pblockOrphan->GetHash()); + setStakeSeenOrphan.erase(pblockOrphan->GetProofOfStake()); delete pblockOrphan; } mapOrphanBlocksByPrev.erase(hashPrev); diff --git a/src/main.h b/src/main.h index a7843b5..6d2ead4 100644 --- a/src/main.h +++ b/src/main.h @@ -897,6 +897,11 @@ public: return !IsProofOfStake(); } + COutPoint GetProofOfStake() const + { + return IsProofOfStake()? vtx[1].vin[0].prevout : COutPoint(); + } + // ppcoin: get max transaction timestamp int64 GetMaxTransactionTime() const { @@ -1273,8 +1278,9 @@ public: std::string ToString() const { - 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, + return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nChainTrust=%"PRI64d" nHeight=%d, nCheckpoint=%d, fProofOfStake=%d prevoutStake=(%s) merkle=%s, hashBlock=%s)", + pprev, pnext, nFile, nBlockPos, nChainTrust, nHeight, nCheckpoint, + fProofOfStake, prevoutStake.ToString().c_str(), hashMerkleRoot.ToString().substr(0,10).c_str(), GetBlockHash().ToString().substr(0,20).c_str()); }