if (!pblock.get())
return NULL;
+ pblock->nBits = GetNextWorkRequired(pindexPrev);
+
// Create coinbase tx
CTransaction txNew;
txNew.vin.resize(1);
// ppcoin: if coinstake available add coinstake tx
CTransaction txCoinStake;
- if (pwallet->CreateCoinStake(txNew.vout[0].scriptPubKey, txCoinStake))
+ if (pwallet->CreateCoinStake(txNew.vout[0].scriptPubKey, pblock->nBits, txCoinStake))
pblock->vtx.push_back(txCoinStake);
// Collect memory pool transactions into the block
}
}
}
- pblock->nBits = GetNextWorkRequired(pindexPrev);
pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pblock->nBits);
// Fill in header
#include "headers.h"
#include "db.h"
#include "crypter.h"
+#include "checkpoints.h"
using namespace std;
}
// ppcoin: create coin stake transaction
-bool CWallet::CreateCoinStake(CScript scriptPubKey, CTransaction& txNew)
+bool CWallet::CreateCoinStake(CScript scriptPubKey, unsigned int nBits, CTransaction& txNew)
{
+ CBigNum bnTargetPerCoinDay;
+ bnTargetPerCoinDay.SetCompact(nBits);
+
CRITICAL_BLOCK(cs_main)
CRITICAL_BLOCK(cs_wallet)
{
int64 nCredit = 0;
BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
{
- nCredit += pcoin.first->vout[pcoin.second].nValue;
- // Only spend one tx for now
- break;
+ CTxDB txdb("r");
+ CTxIndex txindex;
+ if (!txdb.ReadTxIndex(pcoin.first->GetHash(), txindex))
+ continue;
+
+ // Read block header
+ CBlock block;
+ if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
+ continue;
+ if (block.GetBlockTime() + AUTO_CHECKPOINT_TRUST_SPAN > txNew.nTime)
+ continue; // only count coins from at least one week ago
+
+ int64 nValueIn = pcoin.first->vout[pcoin.second].nValue;
+ CBigNum bnCoinDay = CBigNum(nValueIn) * (txNew.nTime-pcoin.first->nTime) / COIN / (24 * 60 * 60);
+ // Calculate hash
+ CDataStream ss(SER_GETHASH, VERSION);
+ ss << nBits << block.nTime << pcoin.first->nTime << txNew.nTime;
+ if (CBigNum(Hash(ss.begin(), ss.end())) <= bnCoinDay * bnTargetPerCoinDay)
+ {
+ txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
+ nCredit += pcoin.first->vout[pcoin.second].nValue;
+ // Only spend one tx for now
+ break;
+ }
}
if (nCredit > nBalance - nBalanceReserve)
return false;
- // Fill vin
- BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
- {
- txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
- // Only spend one tx for now
- break;
- }
// Calculate coin age reward
{
uint64 nCoinAge;
int64 GetStake() const;
bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
- bool CreateCoinStake(CScript scriptPubKey, CTransaction& txNew);
+ bool CreateCoinStake(CScript scriptPubKey, unsigned int nBits, CTransaction& txNew);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
bool BroadcastTransaction(CWalletTx& wtxNew);
std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);