From 2db43142bc9d4febd7946488489fd3fa0e1590f2 Mon Sep 17 00:00:00 2001 From: coblee Date: Fri, 17 May 2013 01:03:38 -1000 Subject: [PATCH] Litecoin: Add mininput to deal with dust spam. By default, mininput is set to 0.0001. This means that create transaction will ignore any transactions with an output value less than 0.0001. You can override the default by passing in -mininput on startup or by calling setmininput. Historically this patch allowed wallets to perform without delay after the dust spam attack during November 2011. --- src/bitcoinrpc.cpp | 2 ++ src/bitcoinrpc.h | 1 + src/init.cpp | 7 +++++++ src/main.cpp | 2 +- src/main.h | 1 + src/rpcwallet.cpp | 19 +++++++++++++++++++ src/wallet.cpp | 2 +- src/wallet.h | 2 +- 8 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 9741b3389..c772da012 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -249,6 +249,7 @@ static const CRPCCommand vRPCCommands[] = { "settxfee", &settxfee, false, false }, { "getblocktemplate", &getblocktemplate, true, false }, { "submitblock", &submitblock, false, false }, + { "setmininput", &setmininput, false, false }, { "listsinceblock", &listsinceblock, false, false }, { "dumpprivkey", &dumpprivkey, true, false }, { "importprivkey", &importprivkey, false, false }, @@ -1149,6 +1150,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 0) ConvertTo(params[0]); if (strMethod == "sendtoaddress" && n > 1) ConvertTo(params[1]); if (strMethod == "settxfee" && n > 0) ConvertTo(params[0]); + if (strMethod == "setmininput" && n > 0) ConvertTo(params[0]); if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo(params[1]); if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo(params[1]); if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo(params[0]); diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 5c0cae66e..8134a117f 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -193,6 +193,7 @@ extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, b extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value setmininput(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); diff --git a/src/init.cpp b/src/init.cpp index ae8f03eaa..d9d6dd7a7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -324,6 +324,7 @@ std::string HelpMessage() #endif #endif " -paytxfee= " + _("Fee per KB to add to transactions you send") + "\n" + + " -mininput= " + _("When creating transactions, ignore inputs with value less than this (default: 0.0001)") + "\n" + #ifdef QT_GUI " -server " + _("Accept command line and JSON-RPC commands") + "\n" + #endif @@ -615,6 +616,12 @@ bool AppInit2(boost::thread_group& threadGroup) InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction.")); } + if (mapArgs.count("-mininput")) + { + if (!ParseMoney(mapArgs["-mininput"], nMinimumInputValue)) + return InitError(strprintf(_("Invalid amount for -mininput=: '%s'"), mapArgs["-mininput"].c_str())); + } + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log std::string strDataDir = GetDataDir().string(); diff --git a/src/main.cpp b/src/main.cpp index c316a4ab1..e9e79fb15 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -71,7 +71,7 @@ int64 nHPSTimerStart = 0; // Settings int64 nTransactionFee = 0; - +int64 nMinimumInputValue = CENT / 100; ////////////////////////////////////////////////////////////////////////////// diff --git a/src/main.h b/src/main.h index 8c222646b..929f05575 100644 --- a/src/main.h +++ b/src/main.h @@ -97,6 +97,7 @@ extern unsigned int nCoinCacheSize; // Settings extern int64 nTransactionFee; +extern int64 nMinimumInputValue; // Minimum disk space required - used in CheckDiskSpace() static const uint64 nMinDiskSpace = 52428800; diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 5fd400c6b..2c942c1cb 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -83,6 +83,7 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize())); obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); + obj.push_back(Pair("mininput", ValueFromAmount(nMinimumInputValue))); if (pwalletMain->IsCrypted()) obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000)); obj.push_back(Pair("errors", GetWarnings("statusbar"))); @@ -247,6 +248,24 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) return ret; } + +Value setmininput(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 1) + throw runtime_error( + "setmininput \n" + " is a real and is rounded to the nearest 0.00000001"); + + // Amount + int64 nAmount = 0; + if (params[0].get_real() != 0.0) + nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts + + nMinimumInputValue = nAmount; + return true; +} + + Value sendtoaddress(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 4) diff --git a/src/wallet.cpp b/src/wallet.cpp index c70ea20e8..bf7439a24 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -976,7 +976,7 @@ void CWallet::AvailableCoins(vector& vCoins, bool fOnlyConfirmed) const for (unsigned int i = 0; i < pcoin->vout.size(); i++) { if (!(pcoin->IsSpent(i)) && IsMine(pcoin->vout[i]) && - !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0) + !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue >= nMinimumInputValue) vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain())); } } diff --git a/src/wallet.h b/src/wallet.h index dcba4675e..6924e8f0f 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -221,7 +221,7 @@ public: bool IsMine(const CTransaction& tx) const { BOOST_FOREACH(const CTxOut& txout, tx.vout) - if (IsMine(txout)) + if (IsMine(txout) && txout.nValue >= nMinimumInputValue) return true; return false; }