return pblockOrphan->hashPrevBlock;
}
-int64 static GetProofOfWorkReward(unsigned int nBits)
+int64 GetProofOfWorkReward(unsigned int nBits)
{
CBigNum bnSubsidyLimit = MAX_MINT_PROOF_OF_WORK;
CBigNum bnTarget;
// 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.
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
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();
}
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;