pindexNew->nHeight = diskindex.nHeight;
pindexNew->nCheckpoint = diskindex.nCheckpoint;
pindexNew->fProofOfStake = diskindex.fProofOfStake;
+ pindexNew->prevoutStake = diskindex.prevoutStake;
pindexNew->nVersion = diskindex.nVersion;
pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
pindexNew->nTime = diskindex.nTime;
if (!pindexNew->CheckIndex())
return error("LoadBlockIndex() : CheckIndex failed at %d", pindexNew->nHeight);
+
+ // ppcoin: build setStakeSeen
+ if (pindexNew->fProofOfStake)
+ setStakeSeen.insert(pindexNew->prevoutStake);
}
else
{
map<COutPoint, CInPoint> mapNextTx;
map<uint256, CBlockIndex*> mapBlockIndex;
+set<COutPoint> setStakeSeen;
uint256 hashGenesisBlock("0x000000006d52486334316794cc38ffeb7ebf35a7ebd661fd39f5f46b0d001575");
static CBigNum bnProofOfWorkLimit(~uint256(0) >> 32);
const int nInitialBlockThreshold = 120; // Regard blocks up until N-threshold as "initial download"
if (!IsCoinStake())
return true;
- BOOST_FOREACH(const CTxIn& txin, vin)
- {
- // First try finding the previous transaction in database
- CTransaction txPrev;
- CTxIndex txindex;
- if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
- continue; // previous transaction not in main chain
- if (nTime < txPrev.nTime)
- return false; // Transaction timestamp violation
-
- // Read block header
- CBlock block;
- if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
- return false; // unable to read block of previous transaction
- if (block.GetBlockTime() + AUTO_CHECKPOINT_TRUST_SPAN > nTime)
- continue; // only count coins from at least one week ago
+ // Input 0 must match the stake hash target per coin age (nBits)
+ const CTxIn& txin = vin[0];
- int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
- CBigNum bnCoinDay = CBigNum(nValueIn) * (nTime-txPrev.nTime) / COIN / (24 * 60 * 60);
- // Calculate hash
- CDataStream ss(SER_GETHASH, VERSION);
- ss << nBits << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << txPrev.nTime << txin.prevout.n << nTime;
- if (CBigNum(Hash(ss.begin(), ss.end())) <= bnCoinDay * bnTargetPerCoinDay)
- return true;
- }
+ // First try finding the previous transaction in database
+ CTransaction txPrev;
+ CTxIndex txindex;
+ if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
+ return false; // previous transaction not in main chain
+ if (nTime < txPrev.nTime)
+ return false; // Transaction timestamp violation
- return false;
+ // Read block header
+ CBlock block;
+ if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
+ return false; // unable to read block of previous transaction
+ if (block.GetBlockTime() + AUTO_CHECKPOINT_TRUST_SPAN > nTime)
+ return false; // only count coins from at least one week ago
+
+ int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
+ CBigNum bnCoinDay = CBigNum(nValueIn) * (nTime-txPrev.nTime) / COIN / (24 * 60 * 60);
+ // Calculate hash
+ CDataStream ss(SER_GETHASH, VERSION);
+ ss << nBits << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << txPrev.nTime << txin.prevout.n << nTime;
+ if (CBigNum(Hash(ss.begin(), ss.end())) <= bnCoinDay * bnTargetPerCoinDay)
+ return true;
+ else
+ return false;
}
// ppcoin: total coin age spent in transaction, in the unit of coin-days.
extern CCriticalSection cs_main;
extern std::map<uint256, CBlockIndex*> mapBlockIndex;
+extern std::set<COutPoint> setStakeSeen;
extern uint256 hashGenesisBlock;
extern CBlockIndex* pindexGenesisBlock;
extern int nBestHeight;
bool IsCoinStake() const
{
// ppcoin: the coin stake transaction is marked with the first output empty
- return (vout.size() == 2 && vout[0].IsEmpty());
+ return (vin.size() > 0 && vout.size() == 2 && vout[0].IsEmpty());
}
int GetSigOpCount() const
int nHeight;
int nCheckpoint; // ppcoin: chain auto checkpoint height
bool fProofOfStake; // ppcoin: is the block of proof-of-stake type
+ COutPoint prevoutStake;
// block header
int nVersion;
nChainTrust = 0;
nCheckpoint = 0;
fProofOfStake = true;
+ prevoutStake.SetNull();
nVersion = 0;
hashMerkleRoot = 0;
nChainTrust = 0;
nCheckpoint = 0;
fProofOfStake = block.IsProofOfStake();
+ if (fProofOfStake)
+ prevoutStake = block.vtx[1].vin[0].prevout;
+ else
+ prevoutStake.SetNull();
nVersion = block.nVersion;
hashMerkleRoot = block.hashMerkleRoot;
READWRITE(nHeight);
READWRITE(nCheckpoint);
READWRITE(fProofOfStake);
+ READWRITE(prevoutStake);
// block header
READWRITE(this->nVersion);