X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=8405d163ad47690d4560f22732365899c7280f64;hb=b3a022069bb4209f07eff94e1b1e075c1182bc79;hp=28babdb3e2c8a778a7d63771e0557e2bec86a7eb;hpb=94f778bdebe1438fbe0206621ce44b4e25196e59;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index 28babdb..8405d16 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1,5 +1,6 @@ -// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2011 Satoshi Nakamoto // Copyright (c) 2011 The Bitcoin developers +// Copyright (c) 2011-2012 The PPCoin developers // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. @@ -214,7 +215,7 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx) CWalletTx& wtx = (*mi).second; if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n])) { - printf("WalletUpdateSpent found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + printf("WalletUpdateSpent found spent coin %sppc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); wtx.MarkSpent(txin.prevout.n); wtx.WriteToDisk(); vWalletUpdated.push_back(txin.prevout.hash); @@ -376,7 +377,7 @@ int CWalletTx::GetRequestCount() const int nRequests = -1; CRITICAL_BLOCK(pwallet->cs_wallet) { - if (IsCoinBase()) + if (IsCoinBase() || IsCoinStake()) { // Generated block if (hashBlock != 0) @@ -417,7 +418,7 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l listSent.clear(); strSentAccount = strFromAccount; - if (IsCoinBase()) + if (IsCoinBase() || IsCoinStake()) { if (GetBlocksToMaturity() > 0) nGeneratedImmature = pwallet->GetCredit(*this); @@ -597,7 +598,7 @@ void CWallet::ReacceptWalletTransactions() BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) { CWalletTx& wtx = item.second; - if (wtx.IsCoinBase() && wtx.IsSpent(0)) + if ((wtx.IsCoinBase() && wtx.IsSpent(0)) || (wtx.IsCoinStake() && wtx.IsSpent(1))) continue; CTxIndex txindex; @@ -623,7 +624,7 @@ void CWallet::ReacceptWalletTransactions() } if (fUpdated) { - printf("ReacceptWalletTransactions found spent coin %sbc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); + printf("ReacceptWalletTransactions found spent coin %sppc %s\n", FormatMoney(wtx.GetCredit()).c_str(), wtx.GetHash().ToString().c_str()); wtx.MarkDirty(); wtx.WriteToDisk(); } @@ -631,7 +632,7 @@ void CWallet::ReacceptWalletTransactions() else { // Reaccept any txes of ours that aren't already in a block - if (!wtx.IsCoinBase()) + if (!(wtx.IsCoinBase() || wtx.IsCoinStake())) wtx.AcceptWalletTransaction(txdb, false); } } @@ -648,14 +649,14 @@ void CWalletTx::RelayWalletTransaction(CTxDB& txdb) { BOOST_FOREACH(const CMerkleTx& tx, vtxPrev) { - if (!tx.IsCoinBase()) + if (!(tx.IsCoinBase() || tx.IsCoinStake())) { uint256 hash = tx.GetHash(); if (!txdb.ContainsTx(hash)) RelayMessage(CInv(MSG_TX, hash), (CTransaction)tx); } } - if (!IsCoinBase()) + if (!(IsCoinBase() || IsCoinStake())) { uint256 hash = GetHash(); if (!txdb.ContainsTx(hash)) @@ -757,7 +758,23 @@ int64 CWallet::GetUnconfirmedBalance() const return nTotal; } -bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, set >& setCoinsRet, int64& nValueRet) const +// ppcoin: total coins staked (non-spendable until maturity) +int64 CWallet::GetStake() const +{ + int64 nTotal = 0; + CRITICAL_BLOCK(cs_wallet) + { + for (map::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) + nTotal += CWallet::GetCredit(*pcoin); + } + } + return nTotal; +} + +bool CWallet::SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, set >& setCoinsRet, int64& nValueRet) const { setCoinsRet.clear(); nValueRet = 0; @@ -782,7 +799,7 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe if (!pcoin->IsFinal() || !pcoin->IsConfirmed()) continue; - if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0) + if ((pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetBlocksToMaturity() > 0) continue; int nDepth = pcoin->GetDepthInMainChain(); @@ -794,6 +811,9 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe if (pcoin->IsSpent(i) || !IsMine(pcoin->vout[i])) continue; + if (pcoin->nTime > nSpendTime) + continue; // ppcoin: timestamp must not exceed spend time + int64 n = pcoin->vout[i].nValue; if (n <= 0) @@ -902,11 +922,11 @@ bool CWallet::SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfThe return true; } -bool CWallet::SelectCoins(int64 nTargetValue, set >& setCoinsRet, int64& nValueRet) const +bool CWallet::SelectCoins(int64 nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64& nValueRet) const { - return (SelectCoinsMinConf(nTargetValue, 1, 6, setCoinsRet, nValueRet) || - SelectCoinsMinConf(nTargetValue, 1, 1, setCoinsRet, nValueRet) || - SelectCoinsMinConf(nTargetValue, 0, 1, setCoinsRet, nValueRet)); + return (SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 6, setCoinsRet, nValueRet) || + SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 1, setCoinsRet, nValueRet) || + SelectCoinsMinConf(nTargetValue, nSpendTime, 0, 1, setCoinsRet, nValueRet)); } @@ -948,7 +968,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW // Choose coins to use set > setCoins; int64 nValueIn = 0; - if (!SelectCoins(nTotalValue, setCoins, nValueIn)) + if (!SelectCoins(nTotalValue, wtxNew.nTime, setCoins, nValueIn)) return false; BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) { @@ -1011,8 +1031,7 @@ bool CWallet::CreateTransaction(const vector >& vecSend, CW // Check that enough fee is included int64 nPayFee = nTransactionFee * (1 + (int64)nBytes / 1000); - bool fAllowFree = CTransaction::AllowFree(dPriority); - int64 nMinFee = wtxNew.GetMinFee(1, fAllowFree); + int64 nMinFee = wtxNew.GetMinFee(1, false); if (nFeeRet < max(nPayFee, nMinFee)) { nFeeRet = max(nPayFee, nMinFee); @@ -1037,6 +1056,62 @@ bool CWallet::CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& w return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet); } +// ppcoin: create coin stake transaction +bool CWallet::CreateCoinStake(CScript scriptPubKey, CTransaction& txNew) +{ + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_wallet) + { + txNew.vin.clear(); + txNew.vout.clear(); + // Mark coin stake transaction + CScript scriptEmpty; + scriptEmpty.clear(); + txNew.vout.push_back(CTxOut(0, scriptEmpty)); + // Choose coins to use + set > setCoins; + int64 nValueIn = 0; + if (!SelectCoins(GetBalance(), txNew.nTime, setCoins, nValueIn)) + return false; + 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; + } + // 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; + CTxDB txdb("r"); + if (!txNew.GetCoinAge(txdb, nCoinAge)) + return false; + nCredit += GetProofOfStakeReward(nCoinAge); + } + // Fill vout + txNew.vout.push_back(CTxOut(nCredit, scriptPubKey)); + + + // Sign + int nIn = 0; + BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins) + { + if (!SignSignature(*this, *coin.first, txNew, nIn++)) + return false; + // Only spend one tx for now + break; + } + } + return true; +} + // Call after CreateTransaction unless you want to abort bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey) {