RPC: modify mergecoins
authorCryptoManiac <balthazar@yandex.ru>
Thu, 28 Aug 2014 22:29:53 +0000 (02:29 +0400)
committerCryptoManiac <balthazar@yandex.ru>
Thu, 28 Aug 2014 22:29:53 +0000 (02:29 +0400)
* Parameter set changes (implement minimum coin credit and use output credit as a maximum value of coin credit);
* Handle of maximum and minimum coin credit while selecting available inputs.

src/rpcwallet.cpp
src/wallet.cpp
src/wallet.h

index ed024a5..5da0a3b 100644 (file)
@@ -259,40 +259,39 @@ Value mergecoins(const Array& params, bool fHelp)
 {
     if (fHelp || params.size() != 3)
         throw runtime_error(
-            "mergecoins <amount> <outputvalue> <maxvalue>\n"
+            "mergecoins <amount> <minvalue> <outputvalue>\n"
             "<amount> is resulting inputs sum\n"
+            "<minvalue> is minimum value of inputs which are used in join process\n"
             "<outputvalue> is resulting value of inputs which will be created\n"
-            "<maxvalue> is maximum value of inputs which are used in join process\n"
             "All values are real and and rounded to the nearest " + FormatMoney(MIN_TXOUT_AMOUNT)
             + HelpRequiringPassphrase());
 
     if (pwalletMain->IsLocked())
         throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
 
-    // Amount
+    // Total amount
     int64 nAmount = AmountFromValue(params[0]);
 
-    // Amount
-    int64 nOutputValue = AmountFromValue(params[1]);
+    // Min input amount
+    int64 nMinValue = AmountFromValue(params[1]);
 
-    // Amount
-    int64 nMaxValue = AmountFromValue(params[2]);
+    // Output amount
+    int64 nOutputValue = AmountFromValue(params[2]);
 
     if (nAmount < MIN_TXOUT_AMOUNT)
         throw JSONRPCError(-101, "Send amount too small");
 
-    if (nOutputValue < MIN_TXOUT_AMOUNT)
-        throw JSONRPCError(-101, "Output value too small");
-
-    if (nMaxValue < MIN_TXOUT_AMOUNT)
+    if (nMinValue < MIN_TXOUT_AMOUNT)
         throw JSONRPCError(-101, "Max value too small");
 
-    if (nOutputValue < nMaxValue)
-        throw JSONRPCError(-101, "Output value is lower than max value");
+    if (nOutputValue < MIN_TXOUT_AMOUNT)
+        throw JSONRPCError(-101, "Output value too small");
 
+    if (nOutputValue < nMinValue)
+        throw JSONRPCError(-101, "Output value is lower than min value");
 
     list<uint256> listMerged;
-    if (!pwalletMain->MergeCoins(nAmount, nMaxValue, nOutputValue, listMerged))
+    if (!pwalletMain->MergeCoins(nAmount, nMinValue, nOutputValue, listMerged))
         return Value::null;
 
     Array mergedHashes;
index 22659da..2ea0ef9 100644 (file)
@@ -1153,7 +1153,7 @@ void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const
     }
 }
 
-void CWallet::AvailableCoinsMinConf(vector<COutput>& vCoins, int nConf) const
+void CWallet::AvailableCoinsMinConf(vector<COutput>& vCoins, int nConf, int64 nMinValue, int64 nMaxValue) const
 {
     vCoins.clear();
 
@@ -1172,7 +1172,12 @@ void CWallet::AvailableCoinsMinConf(vector<COutput>& 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<pair<
 }
 
 // Select some coins without random shuffle or best subset approximation
-bool CWallet::SelectCoinsSimple(int64 nTargetValue, unsigned int nSpendTime, int nMinConf, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
+bool CWallet::SelectCoinsSimple(int64 nTargetValue, int64 nMinValue, int64 nMaxValue, unsigned int nSpendTime, int nMinConf, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const
 {
     vector<COutput> vCoins;
-    AvailableCoinsMinConf(vCoins, nMinConf);
+    AvailableCoinsMinConf(vCoins, nMinConf, nMinValue, nMaxValue);
 
     setCoinsRet.clear();
     nValueRet = 0;
@@ -1654,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<uint256>& listMerged)
+bool CWallet::MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nOutputValue, list<uint256>& listMerged)
 {
     int64 nBalance = GetBalance();
 
@@ -1666,7 +1671,7 @@ bool CWallet::MergeCoins(const int64& nAmount, const int64& nMaxValue, const int
     set<pair<const CWalletTx*,unsigned int> > 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 +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;
@@ -1820,7 +1821,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())
index 195a6ce..e838834 100644 (file)
@@ -69,7 +69,7 @@ public:
 class CWallet : public CCryptoKeyStore
 {
 private:
-    bool SelectCoinsSimple(int64 nTargetValue, unsigned int nSpendTime, int nMinConf, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
+    bool SelectCoinsSimple(int64 nTargetValue, int64 nMinValue, int64 nMaxValue, unsigned int nSpendTime, int nMinConf, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
     bool SelectCoins(int64 nTargetValue, unsigned int nSpendTime, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet, const CCoinControl *coinControl=NULL) const;
 
     CWalletDB *pwalletdbEncryption;
@@ -129,7 +129,7 @@ public:
     // check whether we are allowed to upgrade (or already support) to the named feature
     bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
 
-    void AvailableCoinsMinConf(std::vector<COutput>& vCoins, int nConf) const;
+    void AvailableCoinsMinConf(std::vector<COutput>& vCoins, int nConf, int64 nMinValue, int64 nMaxValue) const;
     void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl=NULL) const;
     bool SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
     // keystore implementation
@@ -203,7 +203,7 @@ public:
     bool GetStakeWeight(const CKeyStore& keystore, uint64& nMinWeight, uint64& nMaxWeight, uint64& nWeight);
     void GetStakeWeightFromValue(const int64& nTime, const int64& nValue, uint64& nWeight);
     bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew, CKey& key);
-    bool MergeCoins(const int64& nAmount, const int64& nMaxValue, const int64& nOutputValue, list<uint256>& listMerged);
+    bool MergeCoins(const int64& nAmount, const int64& nMinValue, const int64& nMaxValue, list<uint256>& listMerged);
 
     std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
     std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);