From: Sunny King Date: Sun, 29 Apr 2012 19:44:36 +0000 (+0100) Subject: PPCoin: Coin creation model - no coinbase reward in proof-of-stake block X-Git-Tag: v0.4.0-unstable~178 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=c03bef8c049b0dd4ef5b63fdfd64bff96e60cb25 PPCoin: Coin creation model - no coinbase reward in proof-of-stake block Coinbase output set to empty for proof-of-stake block --- diff --git a/src/main.cpp b/src/main.cpp index 9fd19e3..6116daa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -324,9 +324,11 @@ bool CTransaction::CheckTransaction() const // Check for negative or overflow output values int64 nValueOut = 0; - for (int i = (IsCoinStake()? 1 : 0); i < vout.size(); i++) + for (int i = 0; i < vout.size(); i++) { const CTxOut& txout = vout[i]; + if (txout.IsEmpty() && (!IsCoinBase()) && (!IsCoinStake())) + return DoS(100, error("CTransaction::CheckTransaction() : txout empty for user transaction")); if (txout.nValue < 0) return DoS(100, error("CTransaction::CheckTransaction() : txout.nValue negative")); if (txout.nValue > MAX_MONEY) @@ -1101,7 +1103,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex) // ppcoin: fees are not collected by miners as in bitcoin // ppcoin: fees are destroyed to compensate the entire network - if (vtx[0].GetValueOut() > GetProofOfWorkReward(nBits)) + if (IsProofOfWork() && vtx[0].GetValueOut() > GetProofOfWorkReward(nBits)) return false; if (fDebug && GetBoolArg("-printcreation")) printf("ConnectBlock() : destroy=%s nFees=%"PRI64d"\n", FormatMoney(nFees).c_str(), nFees); @@ -1496,6 +1498,10 @@ bool CBlock::CheckBlock() const if (vtx[i].IsCoinStake()) return DoS(100, error("CheckBlock() : coinstake in wrong position")); + // ppcoin: coinbase output should be empty if proof-of-stake block + if (IsProofOfStake() && !vtx[0].vout[0].IsEmpty()) + return error("CheckBlock() : coinbase output not empty for proof-of-stake block"); + // Check coinbase timestamp if (GetBlockTime() > (int64)vtx[0].nTime + nMaxClockDrift) return DoS(50, error("CheckBlock() : coinbase timestamp is too early")); @@ -3014,6 +3020,7 @@ CBlock* CreateNewBlock(CWallet* pwallet) if (pwallet->CreateCoinStake(txNew.vout[0].scriptPubKey, pblock->nBits, txCoinStake)) { pblock->vtx.push_back(txCoinStake); + pblock->vtx[0].vout[0].SetEmpty(); break; } } diff --git a/src/main.h b/src/main.h index bd07ceb..2790201 100644 --- a/src/main.h +++ b/src/main.h @@ -360,7 +360,13 @@ public: return (nValue == -1); } - bool IsCoinStake() const + bool SetEmpty() + { + nValue = 0; + scriptPubKey.clear(); + } + + bool IsEmpty() const { return (nValue == 0 && scriptPubKey.empty()); } @@ -383,7 +389,7 @@ public: 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()); @@ -504,7 +510,7 @@ public: bool IsCoinStake() const { // ppcoin: the coin stake transaction is marked with the first output empty - return (vout.size() == 2 && vout[0].IsCoinStake()); + return ((!IsCoinBase()) && vout.size() == 2 && vout[0].IsEmpty()); } int GetSigOpCount() const @@ -632,7 +638,8 @@ public: 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, @@ -1037,8 +1044,9 @@ public: bool SignBlock(const CKeyStore& keystore) { std::vector > 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) { @@ -1063,8 +1071,9 @@ public: return vchBlockSig.empty(); std::vector > 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) {