X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=dc1000c0bc3454d60f6cc3f38e143327e834ed4f;hb=9958f531a04f41133dfb10ff14c1422164ec1080;hp=22659dae499633670446cee81b15ec3619c5644e;hpb=ca78b9e6a859e32fbe36e7afb12c9c9403e8a5b0;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index 22659da..dc1000c 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -13,8 +13,10 @@ #include "coincontrol.h" #include +#include "main.h" + using namespace std; -extern int nStakeMaxAge; + bool fCoinsDataActual; @@ -1153,7 +1155,7 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed, const } } -void CWallet::AvailableCoinsMinConf(vector& vCoins, int nConf) const +void CWallet::AvailableCoinsMinConf(vector& vCoins, int nConf, int64 nMinValue, int64 nMaxValue) const { vCoins.clear(); @@ -1172,7 +1174,12 @@ void CWallet::AvailableCoinsMinConf(vector& vCoins, int nConf) const for (unsigned int i = 0; i < pcoin->vout.size(); i++) { isminetype mine = IsMine(pcoin->vout[i]); - if (!(pcoin->IsSpent(i)) && mine != MINE_NO && pcoin->vout[i].nValue >= nMinimumInputValue) + // ignore coin if it was already spent or we don't own it + if (pcoin->IsSpent(i) || mine == MINE_NO) + continue; + + // if coin value is between required limits then add new item to vector + if (pcoin->vout[i].nValue >= nMinValue && pcoin->vout[i].nValue < nMaxValue) vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain(), mine == MINE_SPENDABLE)); } } @@ -1402,10 +1409,10 @@ bool CWallet::SelectCoins(int64 nTargetValue, unsigned int nSpendTime, set >& setCoinsRet, int64& nValueRet) const +bool CWallet::SelectCoinsSimple(int64 nTargetValue, int64 nMinValue, int64 nMaxValue, unsigned int nSpendTime, int nMinConf, set >& setCoinsRet, int64& nValueRet) const { vector vCoins; - AvailableCoinsMinConf(vCoins, nMinConf); + AvailableCoinsMinConf(vCoins, nMinConf, nMinValue, nMaxValue); setCoinsRet.clear(); nValueRet = 0; @@ -1620,10 +1627,66 @@ void CWallet::GetStakeWeightFromValue(const int64& nTime, const int64& nValue, u // NovaCoin: get current stake weight bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight) { - if (mapMeta.size() == 0 || !fCoinsDataActual) + // Choose coins to use + int64 nBalance = GetBalance(); + int64 nReserveBalance = 0; + + if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) + return error("CreateCoinStake : invalid reserve balance amount"); + + if (nBalance <= nReserveBalance) return false; - // txid => ((txindex, (tx, vout.n)), (block, modifier)) + CTxDB txdb("r"); + { + LOCK2(cs_main, cs_wallet); + // Cache outputs unless best block or wallet transaction set changed + if (!fCoinsDataActual) + { + mapMeta.clear(); + int64 nValueIn = 0; + CoinsSet setCoins; + if (!SelectCoinsSimple(nBalance - nReserveBalance, MIN_TX_FEE, MAX_MONEY, GetAdjustedTime(), nCoinbaseMaturity * 10, setCoins, nValueIn)) + return false; + + if (setCoins.empty()) + return false; + + { + CTxIndex txindex; + CBlock block; + for(CoinsSet::iterator pcoin = setCoins.begin(); pcoin != setCoins.end(); pcoin++) + { + // Load transaction index item + if (!txdb.ReadTxIndex(pcoin->first->GetHash(), txindex)) + continue; + + // Read block header + if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false)) + continue; + + uint64 nStakeModifier = 0; + if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier)) + continue; + + // Add meta record + // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier)) + mapMeta[make_pair(pcoin->first->GetHash(), pcoin->second)] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier)); + + if (fDebug) + printf("Load coin: %s\n", pcoin->first->GetHash().GetHex().c_str()); + } + } + + if (fDebug) + printf("Get stake weight: %zu meta items loaded for %zu coins\n", mapMeta.size(), setCoins.size()); + + fCoinsDataActual = true; + } + } + + + // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier)) for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++) { // Get coin @@ -1654,7 +1717,7 @@ bool CWallet::GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint return true; } -bool CWallet::MergeCoins(const int64& nAmount, const int64& nMaxValue, const int64& nOutputValue, list& listMerged) +bool CWallet::MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nOutputValue, list& listMerged) { int64 nBalance = GetBalance(); @@ -1666,7 +1729,7 @@ bool CWallet::MergeCoins(const int64& nAmount, const int64& nMaxValue, const int set > setCoins; // Simple coins selection - no randomization - if (!SelectCoinsSimple(nAmount, GetTime(), 1, setCoins, nValueIn)) + if (!SelectCoinsSimple(nAmount, nMinValue, nOutputValue, GetTime(), 1, setCoins, nValueIn)) return false; if (setCoins.empty()) @@ -1691,10 +1754,6 @@ bool CWallet::MergeCoins(const int64& nAmount, const int64& nMaxValue, const int { int64 nCredit = pcoin.first->vout[pcoin.second].nValue; - // Ignore coin if credit is too high - if (nCredit >= nMaxValue) - continue; - // Add current coin to inputs list and add its credit to transaction output wtxNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); wtxNew.vout[0].nValue += nCredit; @@ -1820,7 +1879,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int mapMeta.clear(); int64 nValueIn = 0; CoinsSet setCoins; - if (!SelectCoinsSimple(nBalance - nReserveBalance, txNew.nTime, nCoinbaseMaturity * 10, setCoins, nValueIn)) + if (!SelectCoinsSimple(nBalance - nReserveBalance, MIN_TX_FEE, MAX_MONEY, txNew.nTime, nCoinbaseMaturity * 10, setCoins, nValueIn)) return false; if (setCoins.empty()) @@ -1845,7 +1904,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int // Add meta record // txid => ((txindex, (tx, vout.n)), (block, modifier)) - mapMeta[pcoin->first->GetHash()] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier)); + mapMeta[make_pair(pcoin->first->GetHash(), pcoin->second)] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier)); if (fDebug) printf("Load coin: %s\n", pcoin->first->GetHash().GetHex().c_str()); @@ -1941,7 +2000,7 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (nCredit == 0 || nCredit > nBalance - nReserveBalance) return false; - // txid => ((txindex, (tx, vout.n)), (block, modifier)) + // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier)) for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++) { // Get coin