From: Sunny King Date: Sat, 25 Aug 2012 18:19:09 +0000 (+0100) Subject: PPCoin: Lower coinstake combine threshold to improve security X-Git-Tag: v0.4.0-unstable~82 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=85016efc6ded9a0b4467625a4fab047a5a4f299b PPCoin: Lower coinstake combine threshold to improve security --- diff --git a/src/main.cpp b/src/main.cpp index c4d7404..0390b9c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -822,7 +822,7 @@ uint256 WantedByOrphan(const CBlock* pblockOrphan) return pblockOrphan->hashPrevBlock; } -int64 static GetProofOfWorkReward(unsigned int nBits) +int64 GetProofOfWorkReward(unsigned int nBits) { CBigNum bnSubsidyLimit = MAX_MINT_PROOF_OF_WORK; CBigNum bnTarget; @@ -1673,7 +1673,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) // ppcoin: coinstake must meet hash target according to the protocol: -// input 0 must meet the formula +// kernel (input 0) must meet the formula // hash(nBits + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget * nCoinDay // this ensures that the chance of getting a coinstake is proportional to the // amount of coin age one owns. @@ -1700,7 +1700,7 @@ bool CTransaction::CheckProofOfStake(unsigned int nBits) const if (!IsCoinStake()) return true; - // Input 0 must match the stake hash target per coin age (nBits) + // Kernel (input 0) must match the stake hash target per coin age (nBits) const CTxIn& txin = vin[0]; // First try finding the previous transaction in database diff --git a/src/main.h b/src/main.h index 5232a93..c7f518a 100644 --- a/src/main.h +++ b/src/main.h @@ -105,6 +105,7 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& void FormatHashBuffers(CBlock* pblock, char* pmidstate, char* pdata, char* phash1); bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); bool CheckProofOfWork(uint256 hash, unsigned int nBits); +int64 GetProofOfWorkReward(unsigned int nBits); int64 GetProofOfStakeReward(int64 nCoinAge); unsigned int ComputeMinWork(unsigned int nBase, int64 nTime); int GetNumBlocksOfPeers(); diff --git a/src/wallet.cpp b/src/wallet.cpp index c5178d2..4dbc6af 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1299,20 +1299,24 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, CTr } if (nCredit == 0 || nCredit > nBalance - nReserveBalance) return false; + // The following combine threshold is important to network security + // Should not be adjusted if you don't understand the consequences + int64 nCombineThreshold = GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits); BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { // Attempt to add more inputs // Only add coins of the same key/address as kernel - if (pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel && pcoin.first->GetHash() != txNew.vin[0].prevout.hash) + if ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey) + && pcoin.first->GetHash() != txNew.vin[0].prevout.hash) { // Stop adding more inputs if value is already pretty significant - if (nCredit > MAX_MINT_PROOF_OF_WORK) + if (nCredit > nCombineThreshold) break; // Stop adding inputs if reached reserve limit if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance) break; // Do not add additional significant input - if (pcoin.first->vout[pcoin.second].nValue > MAX_MINT_PROOF_OF_WORK) + if (pcoin.first->vout[pcoin.second].nValue > nCombineThreshold) continue; txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); nCredit += pcoin.first->vout[pcoin.second].nValue;