diff --git a/configure.ac b/configure.ac index 59710b6..37fb02d 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 1) define(_CLIENT_VERSION_MINOR, 1) -define(_CLIENT_VERSION_REVISION, 1) -define(_CLIENT_VERSION_BUILD, 1) +define(_CLIENT_VERSION_REVISION, 2) +define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2018) AC_INIT([Aegeus Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[www.aegeus.io],[aegeus]) diff --git a/src/clientversion.h b/src/clientversion.h index d40b973..8ddc99a 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -16,8 +16,8 @@ //! These need to be macros, as clientversion.cpp's and aegeus*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 1 #define CLIENT_VERSION_MINOR 1 -#define CLIENT_VERSION_REVISION 1 -#define CLIENT_VERSION_BUILD 1 +#define CLIENT_VERSION_REVISION 2 +#define CLIENT_VERSION_BUILD 0 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/wallet.cpp b/src/wallet.cpp index fcbd0c9..67192cd 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -21,6 +21,7 @@ #include "timedata.h" #include "util.h" #include "utilmoneystr.h" +#include #include @@ -2211,11 +2212,25 @@ bool CWallet::CreateTransaction(const vector >& vecSend, // TODO: pass in scriptChange instead of reservekey so // change transaction isn't always pay-to-aegeus-address CScript scriptChange; + bool combineChange = false; // coin control: send change to custom address - if (coinControl && !boost::get(&coinControl->destChange)) + if (coinControl && !boost::get(&coinControl->destChange)) { scriptChange = GetScriptForDestination(coinControl->destChange); + vector::iterator it = txNew.vout.begin(); + while (it != txNew.vout.end()) { + if (scriptChange == it->scriptPubKey) { + it->nValue += nChange; + nChange = 0; + reservekey.ReturnKey(); + combineChange = true; + break; + } + ++it; + } + } + // no coin control: send change to newly generated address else { // Note: We use a new key here to keep it from being obvious which side is the change. @@ -2235,17 +2250,20 @@ bool CWallet::CreateTransaction(const vector >& vecSend, } CTxOut newTxOut(nChange, scriptChange); - - // Never create dust outputs; if we would, just - // add the dust to the fee. - if (newTxOut.IsDust(::minRelayTxFee)) { - nFeeRet += nChange; - nChange = 0; - reservekey.ReturnKey(); - } else { - // Insert change txn at random position: - vector::iterator position = txNew.vout.begin() + GetRandInt(txNew.vout.size() + 1); - txNew.vout.insert(position, newTxOut); + if (!combineChange) { + CTxOut newTxOut(nChange, scriptChange); + + // Never create dust outputs; if we would, just + // add the dust to the fee. + if (newTxOut.IsDust(::minRelayTxFee)) { + nFeeRet += nChange; + nChange = 0; + reservekey.ReturnKey(); + } else { + // Insert change txn at random position: + vector::iterator position = txNew.vout.begin() + GetRandInt(txNew.vout.size() + 1); + txNew.vout.insert(position, newTxOut); + } } } else reservekey.ReturnKey(); @@ -3329,6 +3347,7 @@ bool CWallet::GetDestData(const CTxDestination& dest, const std::string& key, st void CWallet::AutoCombineDust() { + if (IsInitialBlockDownload() || IsLocked()) { return; } @@ -3340,6 +3359,8 @@ void CWallet::AutoCombineDust() vector vCoins, vRewardCoins; vCoins = it->second; + unsigned int txSizeEstimate = 90; + //find masternode rewards that need to be combined CCoinControl* coinControl = new CCoinControl(); CAmount nTotalRewardsValue = 0; @@ -3355,6 +3376,10 @@ void CWallet::AutoCombineDust() coinControl->Select(outpt); vRewardCoins.push_back(out); nTotalRewardsValue += out.Value(); + + txSizeEstimate += 190; + if (txSizeEstimate >= MAX_STANDARD_TX_SIZE - 200) + break; } //if no inputs found then return @@ -3369,16 +3394,22 @@ void CWallet::AutoCombineDust() CScript scriptPubKey = GetScriptForDestination(it->first.Get()); vecSend.push_back(make_pair(scriptPubKey, nTotalRewardsValue)); + //Send change to same address + CTxDestination destMyAddress; + if (!ExtractDestination(scriptPubKey, destMyAddress)) { + LogPrintf("AutoCombineDust: failed to extract destination\n"); + continue; + } + coinControl->destChange = destMyAddress; + // Create the transaction and commit it to the network CWalletTx wtx; CReserveKey keyChange(this); // this change address does not end up being used, because change is returned with coin control switch string strErr; CAmount nFeeRet = 0; - //get the fee amount - CWalletTx wtxdummy; - CreateTransaction(vecSend, wtxdummy, keyChange, nFeeRet, strErr, coinControl, ALL_COINS, false, CAmount(0)); - vecSend[0].second = nTotalRewardsValue - nFeeRet - 500; + // 10% safety margin to avoid "Insufficient funds" errors + vecSend[0].second = nTotalRewardsValue - (nTotalRewardsValue / 10); if (!CreateTransaction(vecSend, wtx, keyChange, nFeeRet, strErr, coinControl, ALL_COINS, false, CAmount(0))) { LogPrintf("AutoCombineDust createtransaction failed, reason: %s\n", strErr);