Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ BITCOIN_TESTS =\
test/timedata_tests.cpp \
test/torcontrol_tests.cpp \
test/transaction_tests.cpp \
test/txvalidation_tests.cpp \
test/txvalidationcache_tests.cpp \
test/versionbits_tests.cpp \
test/uint256_tests.cpp \
Expand Down
3 changes: 3 additions & 0 deletions src/dash-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ class GetinfoRequestHandler: public BaseRequestHandler
/** Create a simulated `getinfo` request. */
UniValue PrepareRequest(const std::string& method, const std::vector<std::string>& args) override
{
if (!args.empty()) {
throw std::runtime_error("-getinfo takes no arguments");
}
UniValue result(UniValue::VARR);
result.push_back(JSONRPCRequestObj("getnetworkinfo", NullUniValue, ID_NETWORKINFO));
result.push_back(JSONRPCRequestObj("getblockchaininfo", NullUniValue, ID_BLOCKCHAININFO));
Expand Down
24 changes: 16 additions & 8 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
_("If <category> is not supplied or if <category> = 1, output all debugging information.") + " " + _("<category> can be:") + " " + ListLogCategories() + ".");
strUsage += HelpMessageOpt("-debugexclude=<category>", strprintf(_("Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories.")));
if (showDebug)
strUsage += HelpMessageOpt("-nodebug", "Turn off debugging messages, same as -debug=0");
strUsage += HelpMessageOpt("-help-debug", _("Show all debugging options (usage: --help -help-debug)"));
strUsage += HelpMessageOpt("-logips", strprintf(_("Include IP addresses in debug output (default: %u)"), DEFAULT_LOGIPS));
strUsage += HelpMessageOpt("-logtimestamps", strprintf(_("Prepend debug output with timestamp (default: %u)"), DEFAULT_LOGTIMESTAMPS));
Expand Down Expand Up @@ -800,11 +798,13 @@ void ThreadImport(std::vector<fs::path> vImportFiles)
if (!ActivateBestChain(state, chainparams)) {
LogPrintf("Failed to connect best block (%s)\n", FormatStateMessage(state));
StartShutdown();
return;
}

if (gArgs.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
LogPrintf("Stopping after block import\n");
StartShutdown();
return;
}
} // End scope of CImportingNow

Expand Down Expand Up @@ -1110,12 +1110,12 @@ bool AppInitParameterInteraction()
InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections));

// ********************************************************* Step 3: parameter-to-internal-flags

if (gArgs.IsArgSet("-debug")) {
// Special-case: if -debug=0/-nodebug is set, turn off debugging messages
const std::vector<std::string> categories = gArgs.GetArgs("-debug");

if (!(gArgs.GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), std::string("0")) != categories.end())) {
if (std::none_of(categories.begin(), categories.end(),
[](std::string cat){return cat == "0" || cat == "none";})) {
for (const auto& cat : categories) {
uint64_t flag;
if (!GetLogCategory(&flag, &cat)) {
Expand Down Expand Up @@ -1807,9 +1807,15 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
pcoinsTip.reset();
pcoinsdbview.reset();
pcoinscatcher.reset();
// new CBlockTreeDB tries to delete the existing file, which
// fails if it's still open from the previous loop. Close it first:
pblocktree.reset();
pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, false, fReset));
llmq::DestroyLLMQSystem();
// Same logic as above with pblocktree
evoDb.reset();
evoDb.reset(new CEvoDB(nEvoDbCache, false, fReset || fReindexChainState));
deterministicMNManager.reset();
deterministicMNManager.reset(new CDeterministicMNManager(*evoDb));

llmq::InitLLMQSystem(*evoDb, &scheduler, false, fReset || fReindexChainState);
Expand Down Expand Up @@ -2193,16 +2199,18 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
// Wait for genesis block to be processed
{
WaitableLock lock(cs_GenesisWait);
while (!fHaveGenesis) {
condvar_GenesisWait.wait(lock);
// We previously could hang here if StartShutdown() is called prior to
// ThreadImport getting started, so instead we just wait on a timer to
// check ShutdownRequested() regularly.
while (!fHaveGenesis && !ShutdownRequested()) {
condvar_GenesisWait.wait_for(lock, std::chrono::milliseconds(500));
}
uiInterface.NotifyBlockTip.disconnect(BlockNotifyGenesisWait);
}

// As importing blocks can take several minutes, it's possible the user
// requested to kill the GUI during one of the last operations. If so, exit.
if (fRequestShutdown)
{
if (ShutdownRequested()) {
LogPrintf("Shutdown requested. Exiting.\n");
return false;
}
Expand Down
1 change: 1 addition & 0 deletions src/llmq/quorums_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "sync.h"
#include "univalue.h"

#include <functional>
#include <set>

class CDataStream;
Expand Down
15 changes: 9 additions & 6 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1711,7 +1711,8 @@ void static ProcessOrphanTx(CConnman* connman, std::set<uint256>& orphan_work_se
CValidationState stateDummy;

if (setMisbehaving.count(fromPeer)) continue;
if (AcceptToMemoryPool(mempool, stateDummy, porphanTx, true, &fMissingInputs2)) {
if (AcceptToMemoryPool(mempool, stateDummy, porphanTx, &fMissingInputs2 /* pfMissingInputs */,
false /* bypass_limits */, 0 /* nAbsurdFee */)) {
LogPrint(BCLog::MEMPOOL, " accepted orphan tx %s\n", orphanHash.ToString());
connman->RelayTransaction(orphanTx);
for (unsigned int i = 0; i < orphanTx.vout.size(); i++) {
Expand Down Expand Up @@ -2516,16 +2517,18 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
bool fMissingInputs = false;
CValidationState state;

if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, ptx, true, &fMissingInputs)) {
if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs /* pfMissingInputs */,
false /* bypass_limits */, 0 /* nAbsurdFee */)) {
// Process custom txes, this changes AlreadyHave to "true"
if (nInvType == MSG_DSTX) {
LogPrint(BCLog::PRIVATESEND, "DSTX -- Masternode transaction accepted, txid=%s, peer=%d\n",
tx.GetHash().ToString(), pfrom->GetId());
tx.GetHash().ToString(), pfrom->GetId());
CPrivateSend::AddDSTX(dstx);
}

mempool.check(pcoinsTip.get());
connman->RelayTransaction(tx);

for (unsigned int i = 0; i < tx.vout.size(); i++) {
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(inv.hash, i));
if (it_by_prev != mapOrphanTransactionsByPrev.end()) {
Expand All @@ -2538,9 +2541,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
pfrom->nLastTXTime = GetTime();

LogPrint(BCLog::MEMPOOL, "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n",
pfrom->GetId(),
tx.GetHash().ToString(),
mempool.size(), mempool.DynamicMemoryUsage() / 1000);
pfrom->GetId(),
tx.GetHash().ToString(),
mempool.size(), mempool.DynamicMemoryUsage() / 1000);

// Recursively process any orphan transactions that depended on this one
ProcessOrphanTx(connman, pfrom->orphan_work_set);
Expand Down
4 changes: 2 additions & 2 deletions src/privatesend/privatesend-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ void CPrivateSendServer::CommitFinalTransaction(CConnman& connman)
TRY_LOCK(cs_main, lockMain);
CValidationState validationState;
mempool.PrioritiseTransaction(hashTx, 0.1 * COIN);
if (!lockMain || !AcceptToMemoryPool(mempool, validationState, finalTransaction, false, nullptr, false, maxTxFee)) {
if (!lockMain || !AcceptToMemoryPool(mempool, validationState, finalTransaction, nullptr /* pfMissingInputs */, false /* bypass_limits */, maxTxFee /* nAbsurdFee */)) {
LogPrint(BCLog::PRIVATESEND, "CPrivateSendServer::CommitFinalTransaction -- AcceptToMemoryPool() error: Transaction not valid\n");
SetNull();
// not much we can do in this case, just notify clients
Expand Down Expand Up @@ -434,7 +434,7 @@ void CPrivateSendServer::ConsumeCollateral(CConnman& connman, const CTransaction
{
LOCK(cs_main);
CValidationState validationState;
if (!AcceptToMemoryPool(mempool, validationState, txref, false, nullptr)) {
if (!AcceptToMemoryPool(mempool, validationState, txref, nullptr /* pfMissingInputs */, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
LogPrint(BCLog::PRIVATESEND, "%s -- AcceptToMemoryPool failed\n", __func__);
} else {
connman.RelayTransaction(*txref);
Expand Down
2 changes: 1 addition & 1 deletion src/privatesend/privatesend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ bool CPrivateSend::IsCollateralValid(const CTransaction& txCollateral)
{
LOCK(cs_main);
CValidationState validationState;
if (!AcceptToMemoryPool(mempool, validationState, MakeTransactionRef(txCollateral), false, nullptr, false, maxTxFee, true)) {
if (!AcceptToMemoryPool(mempool, validationState, MakeTransactionRef(txCollateral), nullptr /* pfMissingInputs */, false /* bypass_limits */, maxTxFee /* nAbsurdFee */, true /* fDryRun */)) {
LogPrint(BCLog::PRIVATESEND, "CPrivateSend::IsCollateralValid -- didn't pass AcceptToMemoryPool()\n");
return false;
}
Expand Down
7 changes: 4 additions & 3 deletions src/qt/dash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,6 @@ void BitcoinApplication::createWindow(const NetworkStyle *networkStyle)

pollShutdownTimer = new QTimer(window);
connect(pollShutdownTimer, SIGNAL(timeout()), window, SLOT(detectShutdown()));
pollShutdownTimer->start(200);
}

void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle)
Expand Down Expand Up @@ -552,14 +551,16 @@ void BitcoinApplication::initializeResult(bool success)
window, SLOT(message(QString,QString,unsigned int)));
QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
#endif
pollShutdownTimer->start(200);
} else {
quit(); // Exit main loop
Q_EMIT splashFinished(window); // Make sure splash screen doesn't stick around during shutdown
quit(); // Exit first main loop invocation
}
}

void BitcoinApplication::shutdownResult()
{
quit(); // Exit main loop after shutdown finished
quit(); // Exit second main loop invocation after shutdown finished
}

void BitcoinApplication::handleRunawayException(const QString &message)
Expand Down
39 changes: 28 additions & 11 deletions src/rpc/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,9 @@ uint64_t getCategoryMask(UniValue cats) {
if (!GetLogCategory(&flag, &cat)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown logging category " + cat);
}
if (flag == BCLog::NONE) {
return 0;
}
mask |= flag;
}
return mask;
Expand All @@ -1142,20 +1145,34 @@ UniValue logging(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() > 2) {
throw std::runtime_error(
"logging [include,...] <exclude>\n"
"logging ( <include> <exclude> )\n"
"Gets and sets the logging configuration.\n"
"When called without an argument, returns the list of categories that are currently being debug logged.\n"
"When called with arguments, adds or removes categories from debug logging.\n"
"The valid logging categories are: " + ListLogCategories() + ".\n"
"libevent logging is configured on startup and cannot be modified by this RPC during runtime.\n"
"There are also a few meta-categories:\n"
" - \"all\", \"1\" and \"\" activate all categories at once;\n"
" - \"dash\" activates all Dash-specific categories at once.\n"
"When called without an argument, returns the list of categories with status that are currently being debug logged or not.\n"
"When called with arguments, adds or removes categories from debug logging and return the lists above.\n"
"The arguments are evaluated in order \"include\", \"exclude\".\n"
"If an item is both included and excluded, it will thus end up being excluded.\n"
"The valid logging categories are: " + ListLogCategories() + "\n"
"In addition, the following are available as category names with special meanings:\n"
" - \"all\", \"1\" : represent all logging categories.\n"
" - \"dash\" activates all Dash-specific categories at once.\n"
"To deactivate all categories at once you can specify \"all\" in <exclude>.\n"
" - \"none\", \"0\" : even if other logging categories are specified, ignore all of them.\n"
"\nArguments:\n"
"1. \"include\" (array of strings) add debug logging for these categories.\n"
"2. \"exclude\" (array of strings) remove debug logging for these categories.\n"
"\nResult: <categories> (string): a list of the logging categories that are active.\n"
"1. \"include\" (array of strings, optional) A json array of categories to add debug logging\n"
" [\n"
" \"category\" (string) the valid logging category\n"
" ,...\n"
" ]\n"
"2. \"exclude\" (array of strings, optional) A json array of categories to remove debug logging\n"
" [\n"
" \"category\" (string) the valid logging category\n"
" ,...\n"
" ]\n"
"\nResult:\n"
"{ (json object where keys are the logging categories, and values indicates its status\n"
" \"category\": 0|1, (numeric) if being debug logged or not. 0:inactive, 1:active\n"
" ...\n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"")
+ HelpExampleRpc("logging", "[\"all\"], \"[libevent]\"")
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ UniValue getpeerinfo(const JSONRPCRequest& request)
" \"pingtime\": n, (numeric) ping time (if available)\n"
" \"minping\": n, (numeric) minimum observed ping time (if any at all)\n"
" \"pingwait\": n, (numeric) ping wait (if non-zero)\n"
" \"version\": v, (numeric) The peer version, such as 7001\n"
" \"version\": v, (numeric) The peer version, such as 70001\n"
" \"subver\": \"/Dash Core:x.x.x/\", (string) The string version\n"
" \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
" \"addnode\": true|false, (boolean) Whether connection was due to addnode/-connect or if it was an automatic/inbound connection\n"
Expand Down
3 changes: 2 additions & 1 deletion src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,8 @@ UniValue sendrawtransaction(const JSONRPCRequest& request)
// push to local node and sync with wallets
CValidationState state;
bool fMissingInputs;
if (!AcceptToMemoryPool(mempool, state, std::move(tx), !fBypassLimits, &fMissingInputs, false, nMaxRawTxFee)) {
if (!AcceptToMemoryPool(mempool, state, std::move(tx), &fMissingInputs,
fBypassLimits /* bypass_limits */, nMaxRawTxFee)) {
if (state.IsInvalid()) {
throw JSONRPCError(RPC_TRANSACTION_REJECTED, strprintf("%i: %s", state.GetRejectCode(), state.GetRejectReason()));
} else {
Expand Down
60 changes: 60 additions & 0 deletions src/test/txvalidation_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <validation.h>
#include <txmempool.h>
#include <amount.h>
#include <consensus/validation.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <test/test_dash.h>

#include <boost/test/unit_test.hpp>


BOOST_AUTO_TEST_SUITE(txvalidation_tests)

/**
* Ensure that the mempool won't accept coinbase transactions.
*/
BOOST_FIXTURE_TEST_CASE(tx_mempool_reject_coinbase, TestChain100Setup)
{
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
CMutableTransaction coinbaseTx;

coinbaseTx.nVersion = 1;
coinbaseTx.vin.resize(1);
coinbaseTx.vout.resize(1);
coinbaseTx.vin[0].scriptSig = CScript() << OP_11 << OP_EQUAL;
coinbaseTx.vout[0].nValue = 1 * CENT;
coinbaseTx.vout[0].scriptPubKey = scriptPubKey;

assert(CTransaction(coinbaseTx).IsCoinBase());

CValidationState state;

LOCK(cs_main);

unsigned int initialPoolSize = mempool.size();

BOOST_CHECK_EQUAL(
false,
AcceptToMemoryPool(mempool, state, MakeTransactionRef(coinbaseTx),
nullptr /* pfMissingInputs */,
true /* bypass_limits */,
0 /* nAbsurdFee */));

// Check that the transaction hasn't been added to mempool.
BOOST_CHECK_EQUAL(mempool.size(), initialPoolSize);

// Check that the validation state reflects the unsuccesful attempt.
BOOST_CHECK(state.IsInvalid());
BOOST_CHECK_EQUAL(state.GetRejectReason(), "coinbase");

int nDoS;
BOOST_CHECK_EQUAL(state.IsInvalid(nDoS), true);
BOOST_CHECK_EQUAL(nDoS, 100);
}

BOOST_AUTO_TEST_SUITE_END()
3 changes: 2 additions & 1 deletion src/test/txvalidationcache_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ ToMemPool(CMutableTransaction& tx)
LOCK(cs_main);

CValidationState state;
return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), false, nullptr, true, 0);
return AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), nullptr /* pfMissingInputs */,
true /* bypass_limits */, 0 /* nAbsurdFee */);
}

BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
Expand Down
1 change: 1 addition & 0 deletions src/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ struct CLogCategoryDesc
const CLogCategoryDesc LogCategories[] =
{
{BCLog::NONE, "0"},
{BCLog::NONE, "none"},
{BCLog::NET, "net"},
{BCLog::TOR, "tor"},
{BCLog::MEMPOOL, "mempool"},
Expand Down
Loading