From b4458b34362433758542a3d20e0551a28584a6d2 Mon Sep 17 00:00:00 2001 From: Sunny King Date: Thu, 7 Jun 2012 23:17:24 +0100 Subject: [PATCH] PPCoin: Include coinstake timestamp in duplicate-stake check --- src/db.cpp | 2 +- src/main.cpp | 10 +++++----- src/main.h | 19 ++++++++++++++----- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index a51c217..89f8b16 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -568,7 +568,7 @@ bool CTxDB::LoadBlockIndex() // ppcoin: build setStakeSeen if (pindexNew->fProofOfStake) - setStakeSeen.insert(pindexNew->prevoutStake); + setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); } else { diff --git a/src/main.cpp b/src/main.cpp index e1bdac6..6839725 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,7 +29,7 @@ unsigned int nTransactionsUpdated = 0; map mapNextTx; map mapBlockIndex; -set setStakeSeen; +set > setStakeSeen; uint256 hashGenesisBlock("0x000000006d52486334316794cc38ffeb7ebf35a7ebd661fd39f5f46b0d001575"); static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32); const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download" @@ -45,7 +45,7 @@ CMedianFilter cPeerBlockCounts(5, 0); // Amount of blocks that other nodes map mapOrphanBlocks; multimap mapOrphanBlocksByPrev; -set setStakeSeenOrphan; +set > setStakeSeenOrphan; map mapOrphanTransactions; multimap mapOrphanTransactionsByPrev; @@ -1429,7 +1429,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) return error("AddToBlockIndex() : new CBlockIndex failed"); map::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; if (pindexNew->fProofOfStake) - setStakeSeen.insert(pindexNew->prevoutStake); + setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime)); pindexNew->phashBlock = &((*mi).first); map::iterator miPrev = mapBlockIndex.find(hashPrevBlock); @@ -1611,7 +1611,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // Limited duplicity on stake: prevents block flood attack // Duplicate stake allowed only when there is orphan child block if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash)) - return error("ProcessBlock() : duplicate proof-of-stake (%s) for block %s", pblock->GetProofOfStake().ToString().c_str(), hash.ToString().c_str()); + return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str()); // Preliminary checks if (!pblock->CheckBlock()) @@ -1650,7 +1650,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) // Limited duplicity on stake: prevents block flood attack // Duplicate stake allowed only when there is orphan child block if (setStakeSeenOrphan.count(pblock2->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash)) - return error("ProcessBlock() : duplicate proof-of-stake (%s) for orphan block %s", pblock2->GetProofOfStake().ToString().c_str(), hash.ToString().c_str()); + return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for orphan block %s", pblock2->GetProofOfStake().first.ToString().c_str(), pblock2->GetProofOfStake().second, hash.ToString().c_str()); else setStakeSeenOrphan.insert(pblock2->GetProofOfStake()); } diff --git a/src/main.h b/src/main.h index f6db3b3..3e60fb9 100644 --- a/src/main.h +++ b/src/main.h @@ -53,7 +53,7 @@ static const int fHaveUPnP = false; extern CCriticalSection cs_main; extern std::map mapBlockIndex; -extern std::set setStakeSeen; +extern std::set > setStakeSeen; extern uint256 hashGenesisBlock; extern CBlockIndex* pindexGenesisBlock; extern int nBestHeight; @@ -897,9 +897,9 @@ public: return !IsProofOfStake(); } - COutPoint GetProofOfStake() const + std::pair GetProofOfStake() const { - return IsProofOfStake()? vtx[1].vin[0].prevout : COutPoint(); + return IsProofOfStake()? std::make_pair(vtx[1].vin[0].prevout, vtx[1].nTime) : std::make_pair(COutPoint(), (unsigned int)0); } // ppcoin: get max transaction timestamp @@ -1133,6 +1133,7 @@ public: int nCheckpoint; // ppcoin: chain auto checkpoint height bool fProofOfStake; // ppcoin: is the block of proof-of-stake type COutPoint prevoutStake; + unsigned int nStakeTime; // block header int nVersion; @@ -1154,6 +1155,7 @@ public: nCheckpoint = 0; fProofOfStake = true; prevoutStake.SetNull(); + nStakeTime = 0; nVersion = 0; hashMerkleRoot = 0; @@ -1174,9 +1176,15 @@ public: nCheckpoint = 0; fProofOfStake = block.IsProofOfStake(); if (fProofOfStake) + { prevoutStake = block.vtx[1].vin[0].prevout; + nStakeTime = block.vtx[1].nTime; + } else + { prevoutStake.SetNull(); + nStakeTime = 0; + } nVersion = block.nVersion; hashMerkleRoot = block.hashMerkleRoot; @@ -1278,9 +1286,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 prevoutStake=(%s) merkle=%s, hashBlock=%s)", + return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nChainTrust=%"PRI64d" nHeight=%d, nCheckpoint=%d, fProofOfStake=%d prevoutStake=(%s), nStakeTime=%d merkle=%s, hashBlock=%s)", pprev, pnext, nFile, nBlockPos, nChainTrust, nHeight, nCheckpoint, - fProofOfStake, prevoutStake.ToString().c_str(), + fProofOfStake, prevoutStake.ToString().c_str(), nStakeTime, hashMerkleRoot.ToString().substr(0,10).c_str(), GetBlockHash().ToString().substr(0,20).c_str()); } @@ -1327,6 +1335,7 @@ public: READWRITE(nCheckpoint); READWRITE(fProofOfStake); READWRITE(prevoutStake); + READWRITE(nStakeTime); // block header READWRITE(this->nVersion); -- 1.7.1