for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx* pcoin = &(*it).second;
- if ((pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
+ if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
nTotal += CWallet::GetCredit(*pcoin);
}
}
return nTotal;
}
+int64 CWallet::GetNewMint() const
+{
+ int64 nTotal = 0;
+ CRITICAL_BLOCK(cs_wallet)
+ {
+ for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ {
+ const CWalletTx* pcoin = &(*it).second;
+ if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
+ nTotal += CWallet::GetCredit(*pcoin);
+ }
+ }
+ return nTotal;
+}
+
+
bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
{
setCoinsRet.clear();
}
// ppcoin: create coin stake transaction
-bool CWallet::CreateCoinStake(CScript scriptPubKey, unsigned int nBits, CTransaction& txNew)
+bool CWallet::CreateCoinStake(unsigned int nBits, CTransaction& txNew)
{
CBigNum bnTargetPerCoinDay;
bnTargetPerCoinDay.SetCompact(nBits);
if (nBalance <= nBalanceReserve)
return false;
set<pair<const CWalletTx*,unsigned int> > setCoins;
+ vector<const CWalletTx*> vwtxPrev;
int64 nValueIn = 0;
if (!SelectCoins(nBalance - nBalanceReserve, txNew.nTime, setCoins, nValueIn))
return false;
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;
+ ss << nBits << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << pcoin.first->nTime << pcoin.second << 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
+ vwtxPrev.push_back(pcoin.first);
+ // Set output scriptPubKey
+ txNew.vout.push_back(CTxOut(0, pcoin.first->vout[pcoin.second].scriptPubKey));
break;
}
}
if (nCredit == 0 || nCredit > nBalance - nBalanceReserve)
return false;
+ BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
+ {
+ if (pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey && pcoin.first->GetHash() != txNew.vin[0].prevout.hash)
+ {
+ if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nBalanceReserve)
+ break;
+ txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
+ nCredit += pcoin.first->vout[pcoin.second].nValue;
+ vwtxPrev.push_back(pcoin.first);
+ }
+ }
// Calculate coin age reward
{
uint64 nCoinAge;
CTxDB txdb("r");
if (!txNew.GetCoinAge(txdb, nCoinAge))
- return false;
+ return error("CreateCoinStake : failed to calculate coin age");
nCredit += GetProofOfStakeReward(nCoinAge);
}
- // Fill vout
- txNew.vout.push_back(CTxOut(nCredit, scriptPubKey));
-
+ // Set output amount
+ txNew.vout[1].nValue = nCredit;
// Sign
int nIn = 0;
- BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
+ BOOST_FOREACH(const CWalletTx* pcoin, vwtxPrev)
{
- if (!SignSignature(*this, *coin.first, txNew, nIn++))
- return false;
- // Only spend one tx for now
- break;
+ if (!SignSignature(*this, *pcoin, txNew, nIn++))
+ return error("CreateCoinStake : failed to sign coinstake");
}
}
return true;