// ppcoin: build setStakeSeen
if (pindexNew->fProofOfStake)
- setStakeSeen.insert(pindexNew->prevoutStake);
+ setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime));
}
else
{
map<COutPoint, CInPoint> mapNextTx;
map<uint256, CBlockIndex*> mapBlockIndex;
-set<COutPoint> setStakeSeen;
+set<pair<COutPoint, unsigned int> > setStakeSeen;
uint256 hashGenesisBlock("0x000000006d52486334316794cc38ffeb7ebf35a7ebd661fd39f5f46b0d001575");
static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download"
map<uint256, CBlock*> mapOrphanBlocks;
multimap<uint256, CBlock*> mapOrphanBlocksByPrev;
-set<COutPoint> setStakeSeenOrphan;
+set<pair<COutPoint, unsigned int> > setStakeSeenOrphan;
map<uint256, CDataStream*> mapOrphanTransactions;
multimap<uint256, CDataStream*> mapOrphanTransactionsByPrev;
return error("AddToBlockIndex() : new CBlockIndex failed");
map<uint256, CBlockIndex*>::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<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
// 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())
// 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());
}
extern CCriticalSection cs_main;
extern std::map<uint256, CBlockIndex*> mapBlockIndex;
-extern std::set<COutPoint> setStakeSeen;
+extern std::set<std::pair<COutPoint, unsigned int> > setStakeSeen;
extern uint256 hashGenesisBlock;
extern CBlockIndex* pindexGenesisBlock;
extern int nBestHeight;
return !IsProofOfStake();
}
- COutPoint GetProofOfStake() const
+ std::pair<COutPoint, unsigned int> 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
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;
nCheckpoint = 0;
fProofOfStake = true;
prevoutStake.SetNull();
+ nStakeTime = 0;
nVersion = 0;
hashMerkleRoot = 0;
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;
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());
}
READWRITE(nCheckpoint);
READWRITE(fProofOfStake);
READWRITE(prevoutStake);
+ READWRITE(nStakeTime);
// block header
READWRITE(this->nVersion);