X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fwallet.cpp;h=2ea0ef929526a2927b4ed9ecf057ca4cda37f725;hb=7ee562be0d193150f2e57787744175d017540f9e;hp=104b16246204ce7fbabea7dd08992890c74d3bdf;hpb=642beb691d0ea6dfb101ff1bbbfdfc4f8d0289c0;p=novacoin.git diff --git a/src/wallet.cpp b/src/wallet.cpp index 104b162..2ea0ef9 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -1153,7 +1153,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 +1172,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 +1407,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,40 +1625,15 @@ 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) { - // Choose coins to use - int64 nBalance = GetBalance(); - int64 nReserveBalance = 0; - - if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance)) - { - error("GetStakeWeight : invalid reserve balance amount"); - return false; - } - - if (nBalance <= nReserveBalance) + if (mapMeta.size() == 0 || !fCoinsDataActual) return false; - vector vwtxPrev; - - static set > setCoins; - static uint256 hashPrevBlock; - - // Cache outputs unless best block or wallet transaction set changed - if (!fCoinsDataActual) + // txid => ((txindex, (tx, vout.n)), (block, modifier)) + for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++) { - int64 nValueIn = 0; - if (!SelectCoinsSimple(nBalance - nReserveBalance, GetAdjustedTime(), nCoinbaseMaturity * 10, setCoins, nValueIn)) - return false; + // Get coin + CoinsSet::value_type pcoin = meta_item->second.first.second; - if (setCoins.empty()) - return false; - - fCoinsDataActual = true; - } - - CTxDB txdb("r"); - BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins) - { int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)GetTime()); CBigNum bnCoinDayWeight = CBigNum(pcoin.first->vout[pcoin.second].nValue) * nTimeWeight / COIN / (24 * 60 * 60); @@ -1679,7 +1659,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(); @@ -1691,7 +1671,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()) @@ -1716,10 +1696,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; @@ -1836,20 +1812,16 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int vector vwtxPrev; - static CoinsSet setCoins; - static MetaMap mapMeta; - CTxDB txdb("r"); { LOCK2(cs_main, cs_wallet); // Cache outputs unless best block or wallet transaction set changed if (!fCoinsDataActual) { - setCoins.clear(); mapMeta.clear(); - int64 nValueIn = 0; - if (!SelectCoinsSimple(nBalance - nReserveBalance, txNew.nTime, nCoinbaseMaturity * 10, setCoins, nValueIn)) + CoinsSet setCoins; + if (!SelectCoinsSimple(nBalance - nReserveBalance, MIN_TX_FEE, MAX_MONEY, txNew.nTime, nCoinbaseMaturity * 10, setCoins, nValueIn)) return false; if (setCoins.empty()) @@ -1869,12 +1841,12 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int continue; uint64 nStakeModifier = 0; - if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier)) - return false; + continue; // Add meta record - mapMeta[pcoin->first->GetHash()] = make_pair(txindex, make_pair(block, nStakeModifier)); + // txid => ((txindex, (tx, vout.n)), (block, modifier)) + mapMeta[pcoin->first->GetHash()] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier)); if (fDebug) printf("Load coin: %s\n", pcoin->first->GetHash().GetHex().c_str()); @@ -1895,14 +1867,14 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int settings.nBits = nBits; settings.nTime = txNew.nTime; settings.nOffset = 0; - settings.nLimit = setCoins.size(); + settings.nLimit = mapMeta.size(); settings.nSearchInterval = nSearchInterval; unsigned int nTimeTx, nBlockTime; COutPoint prevoutStake; CoinsSet::value_type kernelcoin; - if (ScanForStakeKernelHash(setCoins, mapMeta, settings, kernelcoin, nTimeTx, nBlockTime)) + if (ScanForStakeKernelHash(mapMeta, settings, kernelcoin, nTimeTx, nBlockTime)) { // Found a kernel if (fDebug && GetBoolArg("-printcoinstake")) @@ -1970,14 +1942,18 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (nCredit == 0 || nCredit > nBalance - nReserveBalance) return false; - for(CoinsSet::const_iterator pcoin = setCoins.begin(); pcoin != setCoins.end(); pcoin++) + // txid => ((txindex, (tx, vout.n)), (block, modifier)) + for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++) { + // Get coin + CoinsSet::value_type pcoin = meta_item->second.first.second; + // Attempt to add more inputs // Only add coins of the same key/address as kernel - if (txNew.vout.size() == 2 && ((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) + if (txNew.vout.size() == 2 && ((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) { - int64 nTimeWeight = GetWeight((int64)pcoin->first->nTime, (int64)txNew.nTime); + int64 nTimeWeight = GetWeight((int64)pcoin.first->nTime, (int64)txNew.nTime); // Stop adding more inputs if already too many inputs if (txNew.vin.size() >= 100) @@ -1986,18 +1962,18 @@ bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int if (nCredit > nCombineThreshold) break; // Stop adding inputs if reached reserve limit - if (nCredit + pcoin->first->vout[pcoin->second].nValue > nBalance - nReserveBalance) + if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance) break; // Do not add additional significant input - if (pcoin->first->vout[pcoin->second].nValue > nCombineThreshold) + if (pcoin.first->vout[pcoin.second].nValue > nCombineThreshold) continue; // Do not add input that is still too young if (nTimeWeight < nStakeMaxAge) continue; - txNew.vin.push_back(CTxIn(pcoin->first->GetHash(), pcoin->second)); - nCredit += pcoin->first->vout[pcoin->second].nValue; - vwtxPrev.push_back(pcoin->first); + txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second)); + nCredit += pcoin.first->vout[pcoin.second].nValue; + vwtxPrev.push_back(pcoin.first); } }