diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/init.cpp | 46 | ||||
-rw-r--r-- | src/main.cpp | 74 | ||||
-rw-r--r-- | src/miner.cpp | 4 | ||||
-rw-r--r-- | src/net.cpp | 12 | ||||
-rw-r--r-- | src/net.h | 1 | ||||
-rw-r--r-- | src/qt/forms/debugwindow.ui | 96 | ||||
-rw-r--r-- | src/qt/rpcconsole.cpp | 7 | ||||
-rw-r--r-- | src/qt/transactiontablemodel.cpp | 28 | ||||
-rw-r--r-- | src/qt/transactiontablemodel.h | 2 | ||||
-rw-r--r-- | src/qt/transactionview.cpp | 16 | ||||
-rw-r--r-- | src/qt/transactionview.h | 1 | ||||
-rw-r--r-- | src/test/mempool_tests.cpp | 22 | ||||
-rw-r--r-- | src/torcontrol.cpp | 15 | ||||
-rw-r--r-- | src/txmempool.cpp | 6 | ||||
-rw-r--r-- | src/txmempool.h | 8 | ||||
-rw-r--r-- | src/version.h | 4 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 39 | ||||
-rw-r--r-- | src/wallet/wallet.h | 5 |
18 files changed, 200 insertions, 186 deletions
diff --git a/src/init.cpp b/src/init.cpp index 048843a4c1..6973574cf1 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -72,7 +72,6 @@ static const bool DEFAULT_REST_ENABLE = false; static const bool DEFAULT_DISABLE_SAFEMODE = false; static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; -static const char * const DEFAULT_WALLET_DAT = "wallet.dat"; #if ENABLE_ZMQ static CZMQNotificationInterface* pzmqNotificationInterface = NULL; @@ -395,26 +394,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-maxuploadtarget=<n>", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET)); #ifdef ENABLE_WALLET - strUsage += HelpMessageGroup(_("Wallet options:")); - strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); - strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE)); - strUsage += HelpMessageOpt("-fallbackfee=<amt>", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); - strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); - strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), - CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); - strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat on startup")); - strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); - strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); - strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); - strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); - strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); - strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); - strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + - " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); + strUsage += CWallet::GetWalletHelpString(showDebug); #endif #if ENABLE_ZMQ @@ -432,16 +412,10 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-checkblockindex", strprintf("Do a full consistency check for mapBlockIndex, setBlockIndexCandidates, chainActive and mapBlocksUnlinked occasionally. Also sets -checkmempool (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); strUsage += HelpMessageOpt("-checkmempool=<n>", strprintf("Run checks every <n> transactions (default: %u)", Params(CBaseChainParams::MAIN).DefaultConsistencyChecks())); strUsage += HelpMessageOpt("-checkpoints", strprintf("Disable expensive verification for known chain history (default: %u)", DEFAULT_CHECKPOINTS_ENABLED)); -#ifdef ENABLE_WALLET - strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); -#endif strUsage += HelpMessageOpt("-disablesafemode", strprintf("Disable safemode, override a real safe mode event (default: %u)", DEFAULT_DISABLE_SAFEMODE)); strUsage += HelpMessageOpt("-testsafemode", strprintf("Force safe mode (default: %u)", DEFAULT_TESTSAFEMODE)); strUsage += HelpMessageOpt("-dropmessagestest=<n>", "Randomly drop 1 of every <n> network messages"); strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages"); -#ifdef ENABLE_WALLET - strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); -#endif strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", DEFAULT_STOPAFTERBLOCKIMPORT)); strUsage += HelpMessageOpt("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT)); strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT)); @@ -477,9 +451,6 @@ std::string HelpMessage(HelpMessageMode mode) if (showDebug) { strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY)); -#ifdef ENABLE_WALLET - strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); -#endif } strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)")); @@ -1091,14 +1062,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (fPrintToDebugLog) OpenDebugLog(); -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - LogPrintf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION)); -#elif defined OPENSSL_VERSION - LogPrintf("Using OpenSSL version %s\n", OpenSSL_version(OPENSSL_VERSION)); -#elif defined LIBRESSL_VERSION_TEXT - LogPrintf("Using %s\n", LIBRESSL_VERSION_TEXT); -#endif - #ifdef ENABLE_WALLET LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); #endif @@ -1199,6 +1162,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) // -proxy sets a proxy for all outgoing network traffic // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default std::string proxyArg = GetArg("-proxy", ""); + SetLimited(NET_TOR); if (proxyArg != "" && proxyArg != "0") { proxyType addrProxy = proxyType(CService(proxyArg, 9050), proxyRandomize); if (!addrProxy.IsValid()) @@ -1208,7 +1172,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) SetProxy(NET_IPV6, addrProxy); SetProxy(NET_TOR, addrProxy); SetNameProxy(addrProxy); - SetReachable(NET_TOR); // by default, -proxy sets onion as reachable, unless -noonion later + SetLimited(NET_TOR, false); // by default, -proxy sets onion as reachable, unless -noonion later } // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses @@ -1217,13 +1181,13 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) std::string onionArg = GetArg("-onion", ""); if (onionArg != "") { if (onionArg == "0") { // Handle -noonion/-onion=0 - SetReachable(NET_TOR, false); // set onions as unreachable + SetLimited(NET_TOR); // set onions as unreachable } else { proxyType addrOnion = proxyType(CService(onionArg, 9050), proxyRandomize); if (!addrOnion.IsValid()) return InitError(strprintf(_("Invalid -onion address: '%s'"), onionArg)); SetProxy(NET_TOR, addrOnion); - SetReachable(NET_TOR); + SetLimited(NET_TOR, false); } } diff --git a/src/main.cpp b/src/main.cpp index babdff54ef..027a36394c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -947,7 +947,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C *pfMissingInputs = false; if (!CheckTransaction(tx, state)) - return error("%s: CheckTransaction: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); + return false; // state filled in by CheckTransaction // Coinbase is only valid in a block, not as a loose transaction if (tx.IsCoinBase()) @@ -1160,10 +1160,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C const uint256 &hashAncestor = ancestorIt->GetTx().GetHash(); if (setConflicts.count(hashAncestor)) { - return state.DoS(10, error("AcceptToMemoryPool: %s spends conflicting transaction %s", + return state.DoS(10, false, + REJECT_INVALID, "bad-txns-spends-conflicting-tx", false, + strprintf("%s spends conflicting transaction %s", hash.ToString(), - hashAncestor.ToString()), - REJECT_INVALID, "bad-txns-spends-conflicting-tx"); + hashAncestor.ToString())); } } @@ -1200,11 +1201,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // that we don't spend too much time walking descendants. // This should be rare. if (mi->IsDirty()) { - return state.DoS(0, - error("AcceptToMemoryPool: rejecting replacement %s; cannot replace tx %s with untracked descendants", + return state.DoS(0, false, + REJECT_NONSTANDARD, "too many potential replacements", false, + strprintf("too many potential replacements: rejecting replacement %s; cannot replace tx %s with untracked descendants", hash.ToString(), - mi->GetTx().GetHash().ToString()), - REJECT_NONSTANDARD, "too many potential replacements"); + mi->GetTx().GetHash().ToString())); } // Don't allow the replacement to reduce the feerate of the @@ -1226,12 +1227,12 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize()); if (newFeeRate <= oldFeeRate) { - return state.DoS(0, - error("AcceptToMemoryPool: rejecting replacement %s; new feerate %s <= old feerate %s", + return state.DoS(0, false, + REJECT_INSUFFICIENTFEE, "insufficient fee", false, + strprintf("rejecting replacement %s; new feerate %s <= old feerate %s", hash.ToString(), newFeeRate.ToString(), - oldFeeRate.ToString()), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + oldFeeRate.ToString())); } BOOST_FOREACH(const CTxIn &txin, mi->GetTx().vin) @@ -1255,12 +1256,12 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C nConflictingSize += it->GetTxSize(); } } else { - return state.DoS(0, - error("AcceptToMemoryPool: rejecting replacement %s; too many potential replacements (%d > %d)\n", + return state.DoS(0, false, + REJECT_NONSTANDARD, "too many potential replacements", false, + strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n", hash.ToString(), nConflictingCount, - maxDescendantsToVisit), - REJECT_NONSTANDARD, "too many potential replacements"); + maxDescendantsToVisit)); } for (unsigned int j = 0; j < tx.vin.size(); j++) @@ -1275,9 +1276,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // it's cheaper to just check if the new input refers to a // tx that's in the mempool. if (pool.mapTx.find(tx.vin[j].prevout.hash) != pool.mapTx.end()) - return state.DoS(0, error("AcceptToMemoryPool: replacement %s adds unconfirmed input, idx %d", - hash.ToString(), j), - REJECT_NONSTANDARD, "replacement-adds-unconfirmed"); + return state.DoS(0, false, + REJECT_NONSTANDARD, "replacement-adds-unconfirmed", false, + strprintf("replacement %s adds unconfirmed input, idx %d", + hash.ToString(), j)); } } @@ -1286,9 +1288,10 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // transactions would not be paid for. if (nModifiedFees < nConflictingFees) { - return state.DoS(0, error("AcceptToMemoryPool: rejecting replacement %s, less fees than conflicting txs; %s < %s", - hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + return state.DoS(0, false, + REJECT_INSUFFICIENTFEE, "insufficient fee", false, + strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s", + hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees))); } // Finally in addition to paying more fees than the conflicts the @@ -1296,19 +1299,19 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C CAmount nDeltaFees = nModifiedFees - nConflictingFees; if (nDeltaFees < ::minRelayTxFee.GetFee(nSize)) { - return state.DoS(0, - error("AcceptToMemoryPool: rejecting replacement %s, not enough additional fees to relay; %s < %s", + return state.DoS(0, false, + REJECT_INSUFFICIENTFEE, "insufficient fee", false, + strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s", hash.ToString(), FormatMoney(nDeltaFees), - FormatMoney(::minRelayTxFee.GetFee(nSize))), - REJECT_INSUFFICIENTFEE, "insufficient fee"); + FormatMoney(::minRelayTxFee.GetFee(nSize)))); } } // Check against previous transactions // This is done last to help prevent CPU exhaustion denial-of-service attacks. if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true)) - return error("%s: CheckInputs: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); + return false; // state filled in by CheckInputs // Check again against just the consensus-critical mandatory script // verification flags, in case of bugs in the standard flags that cause @@ -5064,13 +5067,18 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - // This asymmetric behavior for inbound and outbound connections was introduced - // to prevent a fingerprinting attack: an attacker can send specific fake addresses - // to users' AddrMan and later request them by sending getaddr messages. - // Making nodes which are behind NAT and can only make outgoing connections ignore - // the getaddr message mitigates the attack. - else if ((strCommand == NetMsgType::GETADDR) && (pfrom->fInbound)) + else if (strCommand == NetMsgType::GETADDR) { + // This asymmetric behavior for inbound and outbound connections was introduced + // to prevent a fingerprinting attack: an attacker can send specific fake addresses + // to users' AddrMan and later request them by sending getaddr messages. + // Making nodes which are behind NAT and can only make outgoing connections ignore + // the getaddr message mitigates the attack. + if (!pfrom->fInbound) { + LogPrint("net", "Ignoring \"getaddr\" from outbound connection. peer=%d\n", pfrom->id); + return true; + } + pfrom->vAddrToSend.clear(); vector<CAddress> vAddr = addrman.GetAddr(); BOOST_FOREACH(const CAddress &addr, vAddr) diff --git a/src/miner.cpp b/src/miner.cpp index c454c0279c..9281f7285c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -155,10 +155,10 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer); } - CTxMemPool::indexed_transaction_set::nth_index<3>::type::iterator mi = mempool.mapTx.get<3>().begin(); + CTxMemPool::indexed_transaction_set::index<mining_score>::type::iterator mi = mempool.mapTx.get<mining_score>().begin(); CTxMemPool::txiter iter; - while (mi != mempool.mapTx.get<3>().end() || !clearedTxs.empty()) + while (mi != mempool.mapTx.get<mining_score>().end() || !clearedTxs.empty()) { bool priorityTx = false; if (fPriorityBlock && !vecPriority.empty()) { // add a tx from priority queue to fill the blockprioritysize diff --git a/src/net.cpp b/src/net.cpp index e06e5255d6..b589692d1b 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -79,7 +79,6 @@ bool fListen = true; uint64_t nLocalServices = NODE_NETWORK; CCriticalSection cs_mapLocalHost; map<CNetAddr, LocalServiceInfo> mapLocalHost; -static bool vfReachable[NET_MAX] = {}; static bool vfLimited[NET_MAX] = {}; static CNode* pnodeLocalHost = NULL; uint64_t nLocalHostNonce = 0; @@ -226,14 +225,6 @@ void AdvertiseLocal(CNode *pnode) } } -void SetReachable(enum Network net, bool fFlag) -{ - LOCK(cs_mapLocalHost); - vfReachable[net] = fFlag; - if (net == NET_IPV6 && fFlag) - vfReachable[NET_IPV4] = true; -} - // learn a new local address bool AddLocal(const CService& addr, int nScore) { @@ -256,7 +247,6 @@ bool AddLocal(const CService& addr, int nScore) info.nScore = nScore + (fAlready ? 1 : 0); info.nPort = addr.GetPort(); } - SetReachable(addr.GetNetwork()); } return true; @@ -319,7 +309,7 @@ bool IsLocal(const CService& addr) bool IsReachable(enum Network net) { LOCK(cs_mapLocalHost); - return vfReachable[net] && !vfLimited[net]; + return !vfLimited[net]; } /** check whether a given address is in a network we can probably connect to */ @@ -146,7 +146,6 @@ bool IsLocal(const CService& addr); bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); bool IsReachable(enum Network net); bool IsReachable(const CNetAddr &addr); -void SetReachable(enum Network net, bool fFlag = true); CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index febbaeda1b..a5ac0a7d26 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>740</width> - <height>450</height> + <height>430</height> </rect> </property> <property name="windowTitle"> @@ -113,32 +113,6 @@ </widget> </item> <item row="4" column="0"> - <widget class="QLabel" name="label_14"> - <property name="text"> - <string>Using OpenSSL version</string> - </property> - <property name="indent"> - <number>10</number> - </property> - </widget> - </item> - <item row="4" column="1" colspan="2"> - <widget class="QLabel" name="openSSLVersion"> - <property name="cursor"> - <cursorShape>IBeamCursor</cursorShape> - </property> - <property name="text"> - <string>N/A</string> - </property> - <property name="textFormat"> - <enum>Qt::PlainText</enum> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="5" column="0"> <widget class="QLabel" name="label_berkeleyDBVersion"> <property name="text"> <string>Using BerkeleyDB version</string> @@ -148,7 +122,7 @@ </property> </widget> </item> - <item row="5" column="1" colspan="2"> + <item row="4" column="1" colspan="2"> <widget class="QLabel" name="berkeleyDBVersion"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -164,14 +138,14 @@ </property> </widget> </item> - <item row="6" column="0"> + <item row="5" column="0"> <widget class="QLabel" name="label_12"> <property name="text"> <string>Build date</string> </property> </widget> </item> - <item row="6" column="1" colspan="2"> + <item row="5" column="1" colspan="2"> <widget class="QLabel" name="buildDate"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -187,14 +161,14 @@ </property> </widget> </item> - <item row="7" column="0"> + <item row="6" column="0"> <widget class="QLabel" name="label_13"> <property name="text"> <string>Startup time</string> </property> </widget> </item> - <item row="7" column="1" colspan="2"> + <item row="6" column="1" colspan="2"> <widget class="QLabel" name="startupTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -210,14 +184,27 @@ </property> </widget> </item> - <item row="9" column="0"> + <item row="7" column="0"> + <widget class="QLabel" name="labelNetwork"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Network</string> + </property> + </widget> + </item> + <item row="8" column="0"> <widget class="QLabel" name="label_8"> <property name="text"> <string>Name</string> </property> </widget> </item> - <item row="9" column="1" colspan="2"> + <item row="8" column="1" colspan="2"> <widget class="QLabel" name="networkName"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -233,14 +220,14 @@ </property> </widget> </item> - <item row="10" column="0"> + <item row="9" column="0"> <widget class="QLabel" name="label_7"> <property name="text"> <string>Number of connections</string> </property> </widget> </item> - <item row="10" column="1" colspan="2"> + <item row="9" column="1" colspan="2"> <widget class="QLabel" name="numberOfConnections"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -256,7 +243,7 @@ </property> </widget> </item> - <item row="11" column="0"> + <item row="10" column="0"> <widget class="QLabel" name="label_10"> <property name="font"> <font> @@ -269,14 +256,14 @@ </property> </widget> </item> - <item row="12" column="0"> + <item row="11" column="0"> <widget class="QLabel" name="label_3"> <property name="text"> <string>Current number of blocks</string> </property> </widget> </item> - <item row="12" column="1" colspan="2"> + <item row="11" column="1" colspan="2"> <widget class="QLabel" name="numberOfBlocks"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -292,14 +279,14 @@ </property> </widget> </item> - <item row="13" column="0"> + <item row="12" column="0"> <widget class="QLabel" name="labelLastBlockTime"> <property name="text"> <string>Last block time</string> </property> </widget> </item> - <item row="13" column="1" colspan="2"> + <item row="12" column="1" colspan="2"> <widget class="QLabel" name="lastBlockTime"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -315,7 +302,7 @@ </property> </widget> </item> - <item row="14" column="0"> + <item row="13" column="0"> <widget class="QLabel" name="labelMempoolTitle"> <property name="font"> <font> @@ -328,14 +315,14 @@ </property> </widget> </item> - <item row="15" column="0"> + <item row="14" column="0"> <widget class="QLabel" name="labelNumberOfTransactions"> <property name="text"> <string>Current number of transactions</string> </property> </widget> </item> - <item row="15" column="1"> + <item row="14" column="1"> <widget class="QLabel" name="mempoolNumberTxs"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -351,27 +338,14 @@ </property> </widget> </item> - <item row="8" column="0"> - <widget class="QLabel" name="labelNetwork"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>Network</string> - </property> - </widget> - </item> - <item row="16" column="0"> + <item row="15" column="0"> <widget class="QLabel" name="labelMemoryUsage"> <property name="text"> <string>Memory usage</string> </property> </widget> </item> - <item row="16" column="1"> + <item row="15" column="1"> <widget class="QLabel" name="mempoolSize"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> @@ -387,7 +361,7 @@ </property> </widget> </item> - <item row="14" column="2" rowspan="3"> + <item row="13" column="2" rowspan="3"> <layout class="QVBoxLayout" name="verticalLayoutDebugButton"> <property name="spacing"> <number>3</number> @@ -427,7 +401,7 @@ </item> </layout> </item> - <item row="18" column="0"> + <item row="16" column="0"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index c18c405256..4e2530ffab 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -275,13 +275,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear())); // set library version labels - -#if (OPENSSL_VERSION_NUMBER < 0x10100000L) - ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION)); -#else - ui->openSSLVersion->setText(OpenSSL_version(OPENSSL_VERSION)); -#endif - #ifdef ENABLE_WALLET ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0)); #else diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 1647b2a6fe..d2a52b3022 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -609,6 +609,34 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const return QString::fromStdString(rec->hash.ToString()); case TxHexRole: return priv->getTxHex(rec); + case TxPlainTextRole: + { + QString details; + QDateTime date = QDateTime::fromTime_t(static_cast<uint>(rec->time)); + QString txLabel = walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address)); + + details.append(date.toString("M/d/yy HH:mm")); + details.append(" "); + details.append(formatTxStatus(rec)); + details.append(". "); + if(!formatTxType(rec).isEmpty()) { + details.append(formatTxType(rec)); + details.append(" "); + } + if(!rec->address.empty()) { + if(txLabel.isEmpty()) + details.append(tr("(no label)") + " "); + else { + details.append("("); + details.append(txLabel); + details.append(") "); + } + details.append(QString::fromStdString(rec->address)); + details.append(" "); + } + details.append(formatTxAmount(rec, false, BitcoinUnits::separatorNever)); + return details; + } case ConfirmedRole: return rec->status.countsForBalance; case FormattedAmountRole: diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index fe59a15f6a..6932646e1e 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -62,6 +62,8 @@ public: TxHashRole, /** Transaction data, hex-encoded */ TxHexRole, + /** Whole transaction as plain text */ + TxPlainTextRole, /** Is transaction confirmed? */ ConfirmedRole, /** Formatted amount, without brackets when unconfirmed */ diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 4a9a198216..a4d4c7a35f 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -142,6 +142,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa QAction *copyAmountAction = new QAction(tr("Copy amount"), this); QAction *copyTxIDAction = new QAction(tr("Copy transaction ID"), this); QAction *copyTxHexAction = new QAction(tr("Copy raw transaction"), this); + QAction *copyTxPlainText = new QAction(tr("Copy full transaction details"), this); QAction *editLabelAction = new QAction(tr("Edit label"), this); QAction *showDetailsAction = new QAction(tr("Show transaction details"), this); @@ -151,6 +152,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa contextMenu->addAction(copyAmountAction); contextMenu->addAction(copyTxIDAction); contextMenu->addAction(copyTxHexAction); + contextMenu->addAction(copyTxPlainText); contextMenu->addAction(editLabelAction); contextMenu->addAction(showDetailsAction); @@ -173,6 +175,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount())); connect(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID())); connect(copyTxHexAction, SIGNAL(triggered()), this, SLOT(copyTxHex())); + connect(copyTxPlainText, SIGNAL(triggered()), this, SLOT(copyTxPlainText())); connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel())); connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails())); } @@ -388,6 +391,11 @@ void TransactionView::copyTxHex() GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxHexRole); } +void TransactionView::copyTxPlainText() +{ + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxPlainTextRole); +} + void TransactionView::editLabel() { if(!transactionView->selectionModel() ||!model) @@ -526,12 +534,8 @@ bool TransactionView::eventFilter(QObject *obj, QEvent *event) QKeyEvent *ke = static_cast<QKeyEvent *>(event); if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier)) { - QModelIndex i = this->transactionView->currentIndex(); - if (i.isValid() && i.column() == TransactionTableModel::Amount) - { - GUIUtil::setClipboard(i.data(TransactionTableModel::FormattedAmountRole).toString()); - return true; - } + GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxPlainTextRole); + return true; } } return QWidget::eventFilter(obj, event); diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h index cf2b8fbcd4..2cfbd471b0 100644 --- a/src/qt/transactionview.h +++ b/src/qt/transactionview.h @@ -94,6 +94,7 @@ private Q_SLOTS: void copyAmount(); void copyTxID(); void copyTxHex(); + void copyTxPlainText(); void openThirdPartyTxUrl(QString url); void updateWatchOnlyColumn(bool fHaveWatchOnly); diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 1347d23656..fa352ace8f 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -102,13 +102,13 @@ BOOST_AUTO_TEST_CASE(MempoolRemoveTest) removed.clear(); } -template<int index> +template<typename name> void CheckSort(CTxMemPool &pool, std::vector<std::string> &sortedOrder) { BOOST_CHECK_EQUAL(pool.size(), sortedOrder.size()); - typename CTxMemPool::indexed_transaction_set::nth_index<index>::type::iterator it = pool.mapTx.get<index>().begin(); + typename CTxMemPool::indexed_transaction_set::index<name>::type::iterator it = pool.mapTx.get<name>().begin(); int count=0; - for (; it != pool.mapTx.get<index>().end(); ++it, ++count) { + for (; it != pool.mapTx.get<name>().end(); ++it, ++count) { BOOST_CHECK_EQUAL(it->GetTx().GetHash().ToString(), sortedOrder[count]); } } @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder[2] = tx1.GetHash().ToString(); // 10000 sortedOrder[3] = tx4.GetHash().ToString(); // 15000 sortedOrder[4] = tx2.GetHash().ToString(); // 20000 - CheckSort<1>(pool, sortedOrder); + CheckSort<descendant_score>(pool, sortedOrder); /* low fee but with high fee child */ /* tx6 -> tx7 -> tx8, tx9 -> tx10 */ @@ -176,7 +176,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) BOOST_CHECK_EQUAL(pool.size(), 6); // Check that at this point, tx6 is sorted low sortedOrder.insert(sortedOrder.begin(), tx6.GetHash().ToString()); - CheckSort<1>(pool, sortedOrder); + CheckSort<descendant_score>(pool, sortedOrder); CTxMemPool::setEntries setAncestors; setAncestors.insert(pool.mapTx.find(tx6.GetHash())); @@ -202,7 +202,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder.erase(sortedOrder.begin()); sortedOrder.push_back(tx6.GetHash().ToString()); sortedOrder.push_back(tx7.GetHash().ToString()); - CheckSort<1>(pool, sortedOrder); + CheckSort<descendant_score>(pool, sortedOrder); /* low fee child of tx7 */ CMutableTransaction tx8 = CMutableTransaction(); @@ -217,7 +217,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // Now tx8 should be sorted low, but tx6/tx both high sortedOrder.insert(sortedOrder.begin(), tx8.GetHash().ToString()); - CheckSort<1>(pool, sortedOrder); + CheckSort<descendant_score>(pool, sortedOrder); /* low fee child of tx7 */ CMutableTransaction tx9 = CMutableTransaction(); @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // tx9 should be sorted low BOOST_CHECK_EQUAL(pool.size(), 9); sortedOrder.insert(sortedOrder.begin(), tx9.GetHash().ToString()); - CheckSort<1>(pool, sortedOrder); + CheckSort<descendant_score>(pool, sortedOrder); std::vector<std::string> snapshotOrder = sortedOrder; @@ -274,7 +274,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder.insert(sortedOrder.begin()+5, tx9.GetHash().ToString()); sortedOrder.insert(sortedOrder.begin()+6, tx8.GetHash().ToString()); sortedOrder.insert(sortedOrder.begin()+7, tx10.GetHash().ToString()); // tx10 is just before tx6 - CheckSort<1>(pool, sortedOrder); + CheckSort<descendant_score>(pool, sortedOrder); // there should be 10 transactions in the mempool BOOST_CHECK_EQUAL(pool.size(), 10); @@ -282,7 +282,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) // Now try removing tx10 and verify the sort order returns to normal std::list<CTransaction> removed; pool.remove(pool.mapTx.find(tx10.GetHash())->GetTx(), removed, true); - CheckSort<1>(pool, snapshotOrder); + CheckSort<descendant_score>(pool, snapshotOrder); pool.remove(pool.mapTx.find(tx9.GetHash())->GetTx(), removed, true); pool.remove(pool.mapTx.find(tx8.GetHash())->GetTx(), removed, true); @@ -314,7 +314,7 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) sortedOrder.push_back(tx3.GetHash().ToString()); sortedOrder.push_back(tx6.GetHash().ToString()); } - CheckSort<3>(pool, sortedOrder); + CheckSort<mining_score>(pool, sortedOrder); } diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 10170dbcea..f755992a3e 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -398,6 +398,9 @@ TorController::TorController(struct event_base* base, const std::string& target) target(target), conn(base), reconnect(true), reconnect_ev(0), reconnect_timeout(RECONNECT_TIMEOUT_START) { + reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); + if (!reconnect_ev) + LogPrintf("tor: Failed to create event for reconnection: out of memory?\n"); // Start connection attempts immediately if (!conn.Connect(target, boost::bind(&TorController::connected_cb, this, _1), boost::bind(&TorController::disconnected_cb, this, _1) )) { @@ -413,8 +416,10 @@ TorController::TorController(struct event_base* base, const std::string& target) TorController::~TorController() { - if (reconnect_ev) - event_del(reconnect_ev); + if (reconnect_ev) { + event_free(reconnect_ev); + reconnect_ev = 0; + } if (service.IsValid()) { RemoveLocal(service); } @@ -459,7 +464,7 @@ void TorController::auth_cb(TorControlConnection& conn, const TorControlReply& r if (GetArg("-onion", "") == "") { proxyType addrOnion = proxyType(CService("127.0.0.1", 9050), true); SetProxy(NET_TOR, addrOnion); - SetReachable(NET_TOR); + SetLimited(NET_TOR, false); } // Finally - now create the service @@ -626,8 +631,8 @@ void TorController::disconnected_cb(TorControlConnection& conn) // Single-shot timer for reconnect. Use exponential backoff. struct timeval time = MillisToTimeval(int64_t(reconnect_timeout * 1000.0)); - reconnect_ev = event_new(base, -1, 0, reconnect_cb, this); - event_add(reconnect_ev, &time); + if (reconnect_ev) + event_add(reconnect_ev, &time); reconnect_timeout *= RECONNECT_TIMEOUT_EXP; } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 0b0f32e406..eee6cbf855 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -859,9 +859,9 @@ void CTxMemPool::RemoveStaged(setEntries &stage) { int CTxMemPool::Expire(int64_t time) { LOCK(cs); - indexed_transaction_set::nth_index<2>::type::iterator it = mapTx.get<2>().begin(); + indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get<entry_time>().begin(); setEntries toremove; - while (it != mapTx.get<2>().end() && it->GetTime() < time) { + while (it != mapTx.get<entry_time>().end() && it->GetTime() < time) { toremove.insert(mapTx.project<0>(it)); it++; } @@ -957,7 +957,7 @@ void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<uint256>* pvNoSpendsRe unsigned nTxnRemoved = 0; CFeeRate maxFeeRateRemoved(0); while (DynamicMemoryUsage() > sizelimit) { - indexed_transaction_set::nth_index<1>::type::iterator it = mapTx.get<1>().begin(); + indexed_transaction_set::index<descendant_score>::type::iterator it = mapTx.get<descendant_score>().begin(); // We set the new mempool min fee to the feerate of the removed set, plus the // "minimum reasonable fee rate" (ie some value under which we consider txn diff --git a/src/txmempool.h b/src/txmempool.h index 386cb26d25..7a2a1ef432 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -228,6 +228,11 @@ public: } }; +// Multi_index tag names +struct descendant_score {}; +struct entry_time {}; +struct mining_score {}; + class CBlockPolicyEstimator; /** An inpoint - a combination of a transaction and an index n into its vin */ @@ -350,16 +355,19 @@ public: boost::multi_index::ordered_unique<mempoolentry_txid>, // sorted by fee rate boost::multi_index::ordered_non_unique< + boost::multi_index::tag<descendant_score>, boost::multi_index::identity<CTxMemPoolEntry>, CompareTxMemPoolEntryByDescendantScore >, // sorted by entry time boost::multi_index::ordered_non_unique< + boost::multi_index::tag<entry_time>, boost::multi_index::identity<CTxMemPoolEntry>, CompareTxMemPoolEntryByEntryTime >, // sorted by score (for mining prioritization) boost::multi_index::ordered_unique< + boost::multi_index::tag<mining_score>, boost::multi_index::identity<CTxMemPoolEntry>, CompareTxMemPoolEntryByScore > diff --git a/src/version.h b/src/version.h index f7cf18d0b6..af2eb8eab6 100644 --- a/src/version.h +++ b/src/version.h @@ -24,10 +24,6 @@ static const int MIN_PEER_PROTO_VERSION = GETHEADERS_VERSION; //! if possible, avoid requesting addresses nodes older than this static const int CADDR_TIME_VERSION = 31402; -//! only request blocks from nodes outside this range of versions -static const int NOBLKS_VERSION_START = 32000; -static const int NOBLKS_VERSION_END = 32400; - //! BIP 0031, pong message, is enabled for all versions AFTER this one static const int BIP0031_VERSION = 60000; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 16653b9fd9..6ce7fcbb2b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -39,6 +39,8 @@ unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; +const char * DEFAULT_WALLET_DAT = "wallet.dat"; + /** * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) * Override with -mintxfee @@ -1263,7 +1265,7 @@ bool CWalletTx::RelayWalletTransaction() assert(pwallet->GetBroadcastTransactions()); if (!IsCoinBase()) { - if (GetDepthInMainChain() == 0 && !isAbandoned()) { + if (GetDepthInMainChain() == 0 && !isAbandoned() && InMempool()) { LogPrintf("Relaying wtx %s\n", GetHash().ToString()); RelayTransaction((CTransaction)*this); return true; @@ -2954,6 +2956,41 @@ bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, st return false; } +std::string CWallet::GetWalletHelpString(bool showDebug) +{ + std::string strUsage = HelpMessageGroup(_("Wallet options:")); + strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); + strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE)); + strUsage += HelpMessageOpt("-fallbackfee=<amt>", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); + strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); + strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), + CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); + strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat on startup")); + strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); + strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); + strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); + strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); + strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT)); + strUsage += HelpMessageOpt("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST)); + strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); + strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") + + " " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)")); + + if (showDebug) + { + strUsage += HelpMessageGroup(_("Wallet debugging/testing options:")); + + strUsage += HelpMessageOpt("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); + strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); + strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); + } + + return strUsage; +} + CKeyPool::CKeyPool() { nTime = GetTime(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 990b27c7ce..6312735c97 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -55,6 +55,8 @@ static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 2; static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const bool DEFAULT_WALLETBROADCAST = true; +extern const char * DEFAULT_WALLET_DAT; + class CBlockIndex; class CCoinControl; class COutput; @@ -869,6 +871,9 @@ public: /* Mark a transaction (and it in-wallet descendants) as abandoned so its inputs may be respent. */ bool AbandonTransaction(const uint256& hashTx); + + /* Returns the wallets help message */ + static std::string GetWalletHelpString(bool showDebug); }; /** A key allocated from the key pool. */ |