extern CCriticalSection cs_main;
extern std::map<uint256, CBlockIndex*> mapBlockIndex;
+extern std::set<std::pair<COutPoint, unsigned int> > setStakeSeen;
extern uint256 hashGenesisBlock;
extern CBlockIndex* pindexGenesisBlock;
extern int nBestHeight;
int GetNumBlocksOfPeers();
bool IsInitialBlockDownload();
std::string GetWarnings(std::string strFor);
+bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew);
return (nValue == -1);
}
- bool IsCoinStake() const
+ bool SetEmpty()
+ {
+ nValue = 0;
+ scriptPubKey.clear();
+ }
+
+ bool IsEmpty() const
{
return (nValue == 0 && scriptPubKey.empty());
}
std::string ToString() const
{
- if (IsCoinStake()) return "CTxOut(coinstake)";
+ if (IsEmpty()) return "CTxOut(empty)";
if (scriptPubKey.size() < 6)
return "CTxOut(error)";
return strprintf("CTxOut(nValue=%s, scriptPubKey=%s)", FormatMoney(nValue).c_str(), scriptPubKey.ToString().substr(0,30).c_str());
bool IsCoinStake() const
{
// ppcoin: the coin stake transaction is marked with the first output empty
- return (vout.size() == 2 && vout[0].IsCoinStake());
+ return (vin.size() > 0 && vout.size() == 2 && vout[0].IsEmpty());
}
int GetSigOpCount() const
std::string ToString() const
{
std::string str;
- str += strprintf("CTransaction(hash=%s, nTime=%d, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
+ str += IsCoinBase()? "Coinbase" : (IsCoinStake()? "Coinstake" : "CTransaction");
+ str += strprintf("(hash=%s, nTime=%d, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
GetHash().ToString().substr(0,10).c_str(),
nTime,
nVersion,
public:
bool RemoveFromMemoryPool();
bool GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const; // ppcoin: get transaction coin age
- bool CheckProofOfStake(CTxDB& txdb, unsigned int nBits) const;
+ bool CheckProofOfStake(unsigned int nBits) const;
};
return !IsProofOfStake();
}
+ std::pair<COutPoint, unsigned int> GetProofOfStake() const
+ {
+ 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
int64 GetMaxTransactionTime() const
{
bool SignBlock(const CKeyStore& keystore)
{
std::vector<std::pair<opcodetype, valtype> > vSolution;
+ const CTxOut& txout = IsProofOfStake()? vtx[1].vout[1] : vtx[0].vout[0];
- if (!Solver(vtx[0].vout[0].scriptPubKey, vSolution))
+ if (!Solver(txout.scriptPubKey, vSolution))
return false;
BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
{
return vchBlockSig.empty();
std::vector<std::pair<opcodetype, valtype> > vSolution;
+ const CTxOut& txout = IsProofOfStake()? vtx[1].vout[1] : vtx[0].vout[0];
- if (!Solver(vtx[0].vout[0].scriptPubKey, vSolution))
+ if (!Solver(txout.scriptPubKey, vSolution))
return false;
BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
{
int nHeight;
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;
nChainTrust = 0;
nCheckpoint = 0;
fProofOfStake = true;
+ prevoutStake.SetNull();
+ nStakeTime = 0;
nVersion = 0;
hashMerkleRoot = 0;
nChainTrust = 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 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), nStakeTime=%d merkle=%s, hashBlock=%s)",
+ pprev, pnext, nFile, nBlockPos, nChainTrust, nHeight, nCheckpoint,
+ fProofOfStake, prevoutStake.ToString().c_str(), nStakeTime,
hashMerkleRoot.ToString().substr(0,10).c_str(),
GetBlockHash().ToString().substr(0,20).c_str());
}
READWRITE(nHeight);
READWRITE(nCheckpoint);
READWRITE(fProofOfStake);
+ if (fProofOfStake)
+ {
+ READWRITE(prevoutStake);
+ READWRITE(nStakeTime);
+ }
+ else if (fRead)
+ {
+ const_cast<CDiskBlockIndex*>(this)->prevoutStake.SetNull();
+ const_cast<CDiskBlockIndex*>(this)->nStakeTime = 0;
+ }
// block header
READWRITE(this->nVersion);