From 094848baf01ae7f2ab8dbac4a625a8c956f2a760 Mon Sep 17 00:00:00 2001 From: jnewbery Date: Tue, 27 Sep 2016 13:40:16 -0400 Subject: log block size and weight correctly. Github-Pull: #8838 Rebased-From: 5f274a1749acfdf331bc2931e25ac80c346e5faa --- src/miner.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/miner.cpp b/src/miner.cpp index 9575858840..6cb40dae8d 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -168,7 +168,6 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) nLastBlockTx = nBlockTx; nLastBlockSize = nBlockSize; nLastBlockWeight = nBlockWeight; - LogPrintf("CreateNewBlock(): total size %u txs: %u fees: %ld sigops %d\n", nBlockSize, nBlockTx, nFees, nBlockSigOpsCost); // Create coinbase transaction. CMutableTransaction coinbaseTx; @@ -182,6 +181,9 @@ CBlockTemplate* BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) pblocktemplate->vchCoinbaseCommitment = GenerateCoinbaseCommitment(*pblock, pindexPrev, chainparams.GetConsensus()); pblocktemplate->vTxFees[0] = -nFees; + uint64_t nSerializeSize = GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION); + LogPrintf("CreateNewBlock(): total size: %u block weight: %u txs: %u fees: %ld sigops %d\n", nSerializeSize, GetBlockWeight(*pblock), nBlockTx, nFees, nBlockSigOpsCost); + // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev); -- cgit v1.2.3 From da5a16b11dca8f61d75f92bb08f1dd19a7800158 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 22 Nov 2016 02:50:24 +0000 Subject: Always drop the least preferred HB peer when adding a new one. When a BIP152 HB-mode peer is in the least preferred position and disconnects, they will not be by ForNode on the next loop. They will continue to sit in that position and prevent deactivating HB mode for peers that are still connected. There is no reason for them to stay in the list if already gone, so drop the first element unconditionally if there are too many. Fixes issue #9163. Github-Pull: #9199 Rebased-From: ca8549d2bd32f17f8b69d1edbe3f2976fba504b4 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 191bcff4cc..6ad4304287 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -510,8 +510,8 @@ void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pf CNode* pnodeStop = FindNode(lNodesAnnouncingHeaderAndIDs.front()); if (pnodeStop) { pnodeStop->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); - lNodesAnnouncingHeaderAndIDs.pop_front(); } + lNodesAnnouncingHeaderAndIDs.pop_front(); } fAnnounceUsingCMPCTBLOCK = true; pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); -- cgit v1.2.3 From 99477c71c4cdb5127e0fd6e12f29507320432d9f Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 18 Nov 2016 12:15:01 -0800 Subject: Always add default_witness_commitment with GBT client support Github-Pull: #9189 Rebased-From: ad04d1cb35b9612d36078c62213bdbb13f56d73d --- src/main.cpp | 9 +-------- src/rpc/mining.cpp | 4 +++- src/test/miner_tests.cpp | 1 + 3 files changed, 5 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 6ad4304287..addc0f93a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3503,15 +3503,8 @@ std::vector GenerateCoinbaseCommitment(CBlock& block, const CBloc { std::vector commitment; int commitpos = GetWitnessCommitmentIndex(block); - bool fHaveWitness = false; - for (size_t t = 1; t < block.vtx.size(); t++) { - if (!block.vtx[t].wit.IsNull()) { - fHaveWitness = true; - break; - } - } std::vector ret(32, 0x00); - if (fHaveWitness && IsWitnessEnabled(pindexPrev, consensusParams)) { + if (consensusParams.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) { if (commitpos == -1) { uint256 witnessroot = BlockWitnessMerkleRoot(block, NULL); CHash256().Write(witnessroot.begin(), 32).Write(&ret[0], 32).Finalize(witnessroot.begin()); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index e6901bc77e..ba48079c05 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -683,7 +683,9 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("curtime", pblock->GetBlockTime())); result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight+1))); - if (!pblocktemplate->vchCoinbaseCommitment.empty()) { + + const struct BIP9DeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT]; + if (!pblocktemplate->vchCoinbaseCommitment.empty() && setClientRules.find(segwit_info.name) != setClientRules.end()) { result.push_back(Pair("default_witness_commitment", HexStr(pblocktemplate->vchCoinbaseCommitment.begin(), pblocktemplate->vchCoinbaseCommitment.end()))); } diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 70ba707795..f2bd082cba 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -213,6 +213,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) txCoinbase.vin[0].scriptSig = CScript(); txCoinbase.vin[0].scriptSig.push_back(blockinfo[i].extranonce); txCoinbase.vin[0].scriptSig.push_back(chainActive.Height()); + txCoinbase.vout.resize(1); // Ignore the (optional) segwit commitment added by CreateNewBlock (as the hardcoded nonces don't account for this) txCoinbase.vout[0].scriptPubKey = CScript(); pblock->vtx[0] = CTransaction(txCoinbase); if (txFirst.size() == 0) -- cgit v1.2.3 From ca1fd7521e86b016f2aa92048a13a297bab3c074 Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Fri, 18 Nov 2016 19:11:08 +0000 Subject: Make orphan parent fetching ask for witnesses. In 0.13 orphan transactions began being treated as implicit INVs for their parents. But the resulting getdata were not getting the witness flag. This fixes issue #9182 reported by chjj and roasbeef on IRC. Github-Pull: #9188 Rebased-From: 5b0150a060208faf436c09b0ca9463407a869c72 --- src/main.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index addc0f93a6..962960a150 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5586,10 +5586,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } } if (!fRejectedParents) { + uint32_t nFetchFlags = GetFetchFlags(pfrom, chainActive.Tip(), chainparams.GetConsensus()); BOOST_FOREACH(const CTxIn& txin, tx.vin) { - CInv inv(MSG_TX, txin.prevout.hash); - pfrom->AddInventoryKnown(inv); - if (!AlreadyHave(inv)) pfrom->AskFor(inv); + CInv _inv(MSG_TX | nFetchFlags, txin.prevout.hash); + pfrom->AddInventoryKnown(_inv); + if (!AlreadyHave(_inv)) pfrom->AskFor(_inv); } AddOrphanTx(tx, pfrom->GetId()); -- cgit v1.2.3 From 3a3bcbf775840be34b27523bba9e5ab6321b4ffb Mon Sep 17 00:00:00 2001 From: Gregory Maxwell Date: Tue, 1 Nov 2016 00:08:47 +0000 Subject: Use RelevantServices instead of node_network in AttemptToEvict. Use of node_network here is really meant to be a proxy of "likely to send us blocks in the future". RelevantServices is the right criteria now. Github-Pull: #9052 Rebased-From: d32036a47d9ccdc38628a7a75bb8b711af462e4f --- src/net.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/net.cpp b/src/net.cpp index faa7b00281..7cb612ee96 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -877,7 +877,7 @@ struct NodeEvictionCandidate int64_t nMinPingUsecTime; int64_t nLastBlockTime; int64_t nLastTXTime; - bool fNetworkNode; + bool fRelevantServices; bool fRelayTxes; bool fBloomFilter; CAddress addr; @@ -902,7 +902,7 @@ static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvict { // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block. if (a.nLastBlockTime != b.nLastBlockTime) return a.nLastBlockTime < b.nLastBlockTime; - if (a.fNetworkNode != b.fNetworkNode) return b.fNetworkNode; + if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices; return a.nTimeConnected > b.nTimeConnected; } @@ -936,7 +936,8 @@ static bool AttemptToEvictConnection() { if (node->fDisconnect) continue; NodeEvictionCandidate candidate = {node->id, node->nTimeConnected, node->nMinPingUsecTime, - node->nLastBlockTime, node->nLastTXTime, node->fNetworkNode, + node->nLastBlockTime, node->nLastTXTime, + (node->nServices & nRelevantServices) == nRelevantServices, node->fRelayTxes, node->pfilter != NULL, node->addr, node->nKeyedNetGroup}; vEvictionCandidates.push_back(candidate); } -- cgit v1.2.3 From 106da691a5b935289dfecb25ee4fe2f085cee77f Mon Sep 17 00:00:00 2001 From: BtcDrak Date: Fri, 26 Aug 2016 22:35:46 +0100 Subject: Sync bitcoin-tx with tx version policy Github-Pull: #8932 Rebased-From: b0aea8057921f0ed2288cf07048f652c7d6d9cf3 --- src/bitcoin-tx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 8e8ac47455..b24f295530 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -164,7 +164,7 @@ static void RegisterLoad(const string& strInput) static void MutateTxVersion(CMutableTransaction& tx, const string& cmdVal) { int64_t newVersion = atoi64(cmdVal); - if (newVersion < 1 || newVersion > CTransaction::CURRENT_VERSION) + if (newVersion < 1 || newVersion > CTransaction::MAX_STANDARD_VERSION) throw runtime_error("Invalid TX version requested"); tx.nVersion = (int) newVersion; -- cgit v1.2.3 From 6f86b5364345b238a812c9dffca13fe9f11a0073 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 30 Nov 2015 20:57:20 +0100 Subject: [Qt] make warnings label selectable Github-Pull: #8972 Rebased-From: ef0c9ee2960fda58b2fe5b0c3b4c672231b30322 --- src/qt/forms/overviewpage.ui | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index 6d792d1475..4a6ee92508 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -20,7 +20,7 @@ false - background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; + QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; } true @@ -28,6 +28,9 @@ 3 + + Qt::TextSelectableByMouse + -- cgit v1.2.3 From 973ca1e4912e7ad85e0d06e9490c5939232de6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Jan=C3=ADk?= Date: Fri, 21 Oct 2016 23:42:37 +0200 Subject: Fix doxygen comment: the transaction is returned in txOut Github-Pull: #8993 Rebased-From: 1d8e12ba48154b2c59213e92efb50958d430a007 --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 962960a150..cf96efbe81 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1591,7 +1591,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa return res; } -/** Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock */ +/** Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */ bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow) { CBlockIndex *pindexSlow = NULL; -- cgit v1.2.3 From 5bcb05d4e1304ac3582f1779a25693c0065c69e9 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 30 Oct 2016 16:58:13 +0100 Subject: [rpc] ParseHash: Fail when length is not 64 Github-Pull: #9042 Rebased-From: fa326193ad739d1f93da456b3fa73af0bbf9fdd1 --- src/rpc/server.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 23149baa6d..102c776314 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -146,6 +146,8 @@ uint256 ParseHashV(const UniValue& v, string strName) strHex = v.get_str(); if (!IsHex(strHex)) // Note: IsHex("") is false throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); + if (64 != strHex.length()) + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d)", strName, 64, strHex.length())); uint256 result; result.SetHex(strHex); return result; -- cgit v1.2.3 From f85ee01303b3d5127a31285b2682fcae2f8df64d Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 2 Nov 2016 21:59:09 +0300 Subject: Fix exit codes: - `--help`, `--version` etc should exit with `0` i.e. no error ("not enough args" case should still trigger an error) - error reading config file should exit with `1` Slightly refactor AppInitRPC/AppInitRawTx to return standard exit codes (EXIT_FAILURE/EXIT_SUCCESS) or CONTINUE_EXECUTION (-1) Github-Pull: #9067 Rebased-From: bd0de1386e1c7f9b875d52290de0d561c8d56bc9 --- src/bitcoin-cli.cpp | 28 +++++++++++++++++++--------- src/bitcoin-tx.cpp | 20 +++++++++++++++----- src/bitcoind.cpp | 2 +- src/qt/bitcoin.cpp | 4 ++-- 4 files changed, 37 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index a04101d3ed..bf6f11a50d 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -28,6 +28,7 @@ using namespace std; static const char DEFAULT_RPCCONNECT[] = "127.0.0.1"; static const int DEFAULT_HTTP_CLIENT_TIMEOUT=900; +static const int CONTINUE_EXECUTION=-1; std::string HelpMessageCli() { @@ -67,7 +68,11 @@ public: }; -static bool AppInitRPC(int argc, char* argv[]) +// +// This function returns either one of EXIT_ codes when it's expected to stop the process or +// CONTINUE_EXECUTION when it's expected to continue further. +// +static int AppInitRPC(int argc, char* argv[]) { // // Parameters @@ -85,31 +90,35 @@ static bool AppInitRPC(int argc, char* argv[]) } fprintf(stdout, "%s", strUsage.c_str()); - return false; + if (argc < 2) { + fprintf(stderr, "Error: too few parameters\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } if (!boost::filesystem::is_directory(GetDataDir(false))) { fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); - return false; + return EXIT_FAILURE; } try { ReadConfigFile(mapArgs, mapMultiArgs); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); - return false; + return EXIT_FAILURE; } // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause) try { SelectBaseParams(ChainNameFromCommandLine()); } catch (const std::exception& e) { fprintf(stderr, "Error: %s\n", e.what()); - return false; + return EXIT_FAILURE; } if (GetBoolArg("-rpcssl", false)) { fprintf(stderr, "Error: SSL mode for RPC (-rpcssl) is no longer supported.\n"); - return false; + return EXIT_FAILURE; } - return true; + return CONTINUE_EXECUTION; } @@ -318,8 +327,9 @@ int main(int argc, char* argv[]) } try { - if(!AppInitRPC(argc, argv)) - return EXIT_FAILURE; + int ret = AppInitRPC(argc, argv); + if (ret != CONTINUE_EXECUTION) + return ret; } catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRPC()"); diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index b24f295530..384eae9632 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -30,8 +30,13 @@ using namespace std; static bool fCreateBlank; static map registers; +static const int CONTINUE_EXECUTION=-1; -static bool AppInitRawTx(int argc, char* argv[]) +// +// This function returns either one of EXIT_ codes when it's expected to stop the process or +// CONTINUE_EXECUTION when it's expected to continue further. +// +static int AppInitRawTx(int argc, char* argv[]) { // // Parameters @@ -89,9 +94,13 @@ static bool AppInitRawTx(int argc, char* argv[]) strUsage += HelpMessageOpt("set=NAME:JSON-STRING", _("Set register NAME to given JSON-STRING")); fprintf(stdout, "%s", strUsage.c_str()); - return false; + if (argc < 2) { + fprintf(stderr, "Error: too few parameters\n"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } - return true; + return CONTINUE_EXECUTION; } static void RegisterSetJson(const string& key, const string& rawJson) @@ -680,8 +689,9 @@ int main(int argc, char* argv[]) SetupEnvironment(); try { - if(!AppInitRawTx(argc, argv)) - return EXIT_FAILURE; + int ret = AppInitRawTx(argc, argv); + if (ret != CONTINUE_EXECUTION) + return ret; } catch (const std::exception& e) { PrintExceptionContinue(&e, "AppInitRawTx()"); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 28bc374acc..b534caffac 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -93,7 +93,7 @@ bool AppInit(int argc, char* argv[]) } fprintf(stdout, "%s", strUsage.c_str()); - return false; + return true; } try diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 430e6dd0e8..595fa48253 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -573,7 +573,7 @@ int main(int argc, char *argv[]) { HelpMessageDialog help(NULL, mapArgs.count("-version")); help.showOrPrint(); - return 1; + return 0; } /// 5. Now that settings and translations are available, ask user for data directory @@ -594,7 +594,7 @@ int main(int argc, char *argv[]) } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); - return false; + return 1; } /// 7. Determine network (and switch to network specific options) -- cgit v1.2.3 From f27596a7ec3c625c3b0f25d66fc1bc804c250e7f Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 7 Nov 2016 21:31:38 +0300 Subject: Every main()/exit() should return/use one of EXIT_ codes instead of magic numbers Github-Pull: #9067 Rebased-From: 4441018d0860fce64ee74fa78da79bbb21114ca9 --- src/bitcoind.cpp | 4 ++-- src/qt/bitcoin.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index b534caffac..823b9ce581 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -127,7 +127,7 @@ bool AppInit(int argc, char* argv[]) if (fCommandLine) { fprintf(stderr, "Error: There is no RPC client functionality in bitcoind anymore. Use the bitcoin-cli utility instead.\n"); - exit(1); + exit(EXIT_FAILURE); } #ifndef WIN32 fDaemon = GetBoolArg("-daemon", false); @@ -187,5 +187,5 @@ int main(int argc, char* argv[]) // Connect bitcoind signal handlers noui_connect(); - return (AppInit(argc, argv) ? 0 : 1); + return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE); } diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 595fa48253..d3d13423f7 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -496,7 +496,7 @@ void BitcoinApplication::shutdownResult(int retval) void BitcoinApplication::handleRunawayException(const QString &message) { QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Bitcoin can no longer continue safely and will quit.") + QString("\n\n") + message); - ::exit(1); + ::exit(EXIT_FAILURE); } WId BitcoinApplication::getMainWinId() const @@ -573,13 +573,13 @@ int main(int argc, char *argv[]) { HelpMessageDialog help(NULL, mapArgs.count("-version")); help.showOrPrint(); - return 0; + return EXIT_SUCCESS; } /// 5. Now that settings and translations are available, ask user for data directory // User language is set up: pick a data directory if (!Intro::pickDataDirectory()) - return 0; + return EXIT_SUCCESS; /// 6. Determine availability of data directory and parse bitcoin.conf /// - Do not call GetDataDir(true) before this step finishes @@ -587,14 +587,14 @@ int main(int argc, char *argv[]) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); - return 1; + return EXIT_FAILURE; } try { ReadConfigFile(mapArgs, mapMultiArgs); } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); - return 1; + return EXIT_FAILURE; } /// 7. Determine network (and switch to network specific options) @@ -608,7 +608,7 @@ int main(int argc, char *argv[]) SelectParams(ChainNameFromCommandLine()); } catch(std::exception &e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: %1").arg(e.what())); - return 1; + return EXIT_FAILURE; } #ifdef ENABLE_WALLET // Parse URIs on command line -- this can affect Params() @@ -630,7 +630,7 @@ int main(int argc, char *argv[]) // - Do this after creating app and setting up translations, so errors are // translated properly. if (PaymentServer::ipcSendCommandLine()) - exit(0); + exit(EXIT_SUCCESS); // Start up the payment server early, too, so impatient users that click on // bitcoin: links repeatedly have their payment requests routed to this process: -- cgit v1.2.3 From 08d1c90113efb51d4fb2fcea36171181a66aea36 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Thu, 10 Nov 2016 00:53:55 +0300 Subject: Missed one "return false" in recent refactoring in #9067 Github-Pull: #9120 Rebased-From: 45d372f88900bda74835a20a44246746c2ac94e6 --- src/bitcoin-tx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 384eae9632..c5ae33da88 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -48,7 +48,7 @@ static int AppInitRawTx(int argc, char* argv[]) SelectParams(ChainNameFromCommandLine()); } catch (const std::exception& e) { fprintf(stderr, "Error: %s\n", e.what()); - return false; + return EXIT_FAILURE; } fCreateBlank = GetBoolArg("-create", false); -- cgit v1.2.3 From 5f3a12c97c25f811083679cd3f284059cf7ea54f Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 7 Nov 2016 12:11:59 +0100 Subject: qt: Use correct conversion function for boost::path datadir Fixes #9089. Github-Pull: #9094 Rebased-From: e760b307f6210bee293796d606bcca87f86be200 --- src/qt/clientmodel.cpp | 3 ++- src/qt/paymentserver.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 14661b857a..9530b63a27 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -6,6 +6,7 @@ #include "bantablemodel.h" #include "guiconstants.h" +#include "guiutil.h" #include "peertablemodel.h" #include "chainparams.h" @@ -186,7 +187,7 @@ QString ClientModel::formatClientStartupTime() const QString ClientModel::dataDir() const { - return QString::fromStdString(GetDataDir().string()); + return GUIUtil::boostPathToQString(GetDataDir()); } void ClientModel::updateBanlist() diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index c80aebb009..96627710ee 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -80,7 +80,7 @@ static QString ipcServerName() // Append a simple hash of the datadir // Note that GetDataDir(true) returns a different path // for -testnet versus main net - QString ddir(QString::fromStdString(GetDataDir(true).string())); + QString ddir(GUIUtil::boostPathToQString(GetDataDir(true))); name.append(QString::number(qHash(ddir))); return name; -- cgit v1.2.3 From 6fe3981ac8267f9f045b0d518399d943d3147268 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Wed, 9 Nov 2016 12:45:13 -0500 Subject: net: don't send feefilter messages before the version handshake is complete Github-Pull: #9117 Rebased-From: 46625538d674a5aaf1bcfa7c8be8a49e5a23fa9e --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index cf96efbe81..083ea194ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6856,7 +6856,7 @@ bool SendMessages(CNode* pto) // Message: feefilter // // We don't want white listed peers to filter txs to us if we have -whitelistforcerelay - if (pto->nVersion >= FEEFILTER_VERSION && GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && + if (!pto->fDisconnect && pto->nVersion >= FEEFILTER_VERSION && GetBoolArg("-feefilter", DEFAULT_FEEFILTER) && !(pto->fWhitelisted && GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY))) { CAmount currentFilter = mempool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); int64_t timeNow = GetTimeMicros(); -- cgit v1.2.3 From f82c81b177dfb540c086ccccc39c030b8d9ca81f Mon Sep 17 00:00:00 2001 From: Masahiko Hyuga Date: Thu, 10 Nov 2016 18:18:52 +0900 Subject: fix getnettotals RPC description about timemillis. Github-Pull: #9122 Rebased-From: a79f864945d7abe05e777a942864c181311e5070 --- src/rpc/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 89035aaa84..51f9d1c333 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -344,7 +344,7 @@ UniValue getnettotals(const UniValue& params, bool fHelp) "{\n" " \"totalbytesrecv\": n, (numeric) Total bytes received\n" " \"totalbytessent\": n, (numeric) Total bytes sent\n" - " \"timemillis\": t, (numeric) Total cpu time\n" + " \"timemillis\": t, (numeric) Current UNIX time in milliseconds\n" " \"uploadtarget\":\n" " {\n" " \"timeframe\": n, (numeric) Length of the measuring timeframe in seconds\n" -- cgit v1.2.3 From 6d70a73968695ee34e15e31a79d889db6f53b734 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 18 Nov 2016 10:26:38 +0100 Subject: [Qt] fix coincontrol sort issue Github-Pull: #9185 Rebased-From: 76af4eb876814a916dd4f26cf71faa20bdc54f2d --- src/qt/coincontroldialog.cpp | 21 +++++++++++++++------ src/qt/coincontroldialog.h | 12 ++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 837f8ba6c1..2a482baa6d 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -35,6 +35,15 @@ QList CoinControlDialog::payAmounts; CCoinControl* CoinControlDialog::coinControl = new CCoinControl(); bool CoinControlDialog::fSubtractFeeFromAmount = false; +bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const { + int column = treeWidget()->sortColumn(); + if (column == CoinControlDialog::COLUMN_AMOUNT_INT64 || column == CoinControlDialog::COLUMN_AMOUNT_INT64) + return data(CoinControlDialog::COLUMN_AMOUNT_INT64, Qt::DisplayRole).toULongLong() < other.data(CoinControlDialog::COLUMN_AMOUNT_INT64, Qt::DisplayRole).toULongLong(); + if (column == CoinControlDialog::COLUMN_DATE || column == CoinControlDialog::COLUMN_DATE_INT64) + return data(CoinControlDialog::COLUMN_DATE_INT64, Qt::DisplayRole).toULongLong() < other.data(CoinControlDialog::COLUMN_DATE_INT64, Qt::DisplayRole).toULongLong(); + return QTreeWidgetItem::operator<(other); +} + CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::CoinControlDialog), @@ -708,7 +717,7 @@ void CoinControlDialog::updateView() model->listCoins(mapCoins); BOOST_FOREACH(const PAIRTYPE(QString, std::vector)& coins, mapCoins) { - QTreeWidgetItem *itemWalletAddress = new QTreeWidgetItem(); + CCoinControlWidgetItem *itemWalletAddress = new CCoinControlWidgetItem(); itemWalletAddress->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); QString sWalletAddress = coins.first; QString sWalletLabel = model->getAddressTableModel()->labelForAddress(sWalletAddress); @@ -739,9 +748,9 @@ void CoinControlDialog::updateView() nSum += out.tx->vout[out.i].nValue; nChildren++; - QTreeWidgetItem *itemOutput; - if (treeMode) itemOutput = new QTreeWidgetItem(itemWalletAddress); - else itemOutput = new QTreeWidgetItem(ui->treeWidget); + CCoinControlWidgetItem *itemOutput; + if (treeMode) itemOutput = new CCoinControlWidgetItem(itemWalletAddress); + else itemOutput = new CCoinControlWidgetItem(ui->treeWidget); itemOutput->setFlags(flgCheckbox); itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); @@ -779,11 +788,11 @@ void CoinControlDialog::updateView() // amount itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->vout[out.i].nValue)); - itemOutput->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(out.tx->vout[out.i].nValue), 15, " ")); // padding so that sorting works correctly + itemOutput->setData(COLUMN_AMOUNT_INT64, Qt::DisplayRole, QVariant((qlonglong)out.tx->vout[out.i].nValue)); // padding so that sorting works correctly // date itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime())); - itemOutput->setText(COLUMN_DATE_INT64, strPad(QString::number(out.tx->GetTxTime()), 20, " ")); + itemOutput->setData(COLUMN_DATE_INT64, Qt::DisplayRole, QVariant((qlonglong)out.tx->GetTxTime())); // confirmations itemOutput->setText(COLUMN_CONFIRMATIONS, strPad(QString::number(out.nDepth), 8, " ")); diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 1a467eb2ff..6229d21dab 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -28,6 +28,17 @@ namespace Ui { #define ASYMP_UTF8 "\xE2\x89\x88" +class CCoinControlWidgetItem : public QTreeWidgetItem +{ +public: + CCoinControlWidgetItem(QTreeWidget *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + CCoinControlWidgetItem(int type = Type) : QTreeWidgetItem(type) {} + CCoinControlWidgetItem(QTreeWidgetItem *parent, int type = Type) : QTreeWidgetItem(parent, type) {} + + bool operator<(const QTreeWidgetItem &other) const; +}; + + class CoinControlDialog : public QDialog { Q_OBJECT @@ -79,6 +90,7 @@ private: COLUMN_PRIORITY_INT64, COLUMN_DATE_INT64 }; + friend class CCoinControlWidgetItem; // some columns have a hidden column containing the value used for sorting int getMappedColumn(int column, bool fVisibleColumn = true) -- cgit v1.2.3 From ff423cc6b0323854b93810fa7a9a479a746f6d5d Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Nov 2016 14:33:34 +0100 Subject: [Qt] Clean up and fix coincontrol tree widget handling - Do sorting for date, amount and confirmations column as longlong, not unsigned longlong. - Use `UserRole` to store our own data. This makes it treated as ancillary data prevents it from being displayed. - Get rid of `getMappedColumn` `strPad` - these are no longer necessary. - Get rid of hidden `_INT64` columns. - Start enumeration from 0 (otherwise values are undefined). Github-Pull: #9185 Rebased-From: 4231032bfcb9728f0f629b3d67884ba9de63e4ff --- src/qt/coincontroldialog.cpp | 39 ++++++++++++--------------------------- src/qt/coincontroldialog.h | 31 +------------------------------ 2 files changed, 13 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 2a482baa6d..81cd098bf9 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -37,10 +37,8 @@ bool CoinControlDialog::fSubtractFeeFromAmount = false; bool CCoinControlWidgetItem::operator<(const QTreeWidgetItem &other) const { int column = treeWidget()->sortColumn(); - if (column == CoinControlDialog::COLUMN_AMOUNT_INT64 || column == CoinControlDialog::COLUMN_AMOUNT_INT64) - return data(CoinControlDialog::COLUMN_AMOUNT_INT64, Qt::DisplayRole).toULongLong() < other.data(CoinControlDialog::COLUMN_AMOUNT_INT64, Qt::DisplayRole).toULongLong(); - if (column == CoinControlDialog::COLUMN_DATE || column == CoinControlDialog::COLUMN_DATE_INT64) - return data(CoinControlDialog::COLUMN_DATE_INT64, Qt::DisplayRole).toULongLong() < other.data(CoinControlDialog::COLUMN_DATE_INT64, Qt::DisplayRole).toULongLong(); + if (column == CoinControlDialog::COLUMN_AMOUNT || column == CoinControlDialog::COLUMN_DATE || column == CoinControlDialog::COLUMN_CONFIRMATIONS) + return data(column, Qt::UserRole).toLongLong() < other.data(column, Qt::UserRole).toLongLong(); return QTreeWidgetItem::operator<(other); } @@ -141,12 +139,9 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget ui->treeWidget->setColumnWidth(COLUMN_PRIORITY, 100); ui->treeWidget->setColumnHidden(COLUMN_TXHASH, true); // store transaction hash in this column, but don't show it ui->treeWidget->setColumnHidden(COLUMN_VOUT_INDEX, true); // store vout index in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_AMOUNT_INT64, true); // store amount int64 in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_PRIORITY_INT64, true); // store priority int64 in this column, but don't show it - ui->treeWidget->setColumnHidden(COLUMN_DATE_INT64, true); // store date int64 in this column, but don't show it // default view is sorted by amount desc - sortView(COLUMN_AMOUNT_INT64, Qt::DescendingOrder); + sortView(COLUMN_AMOUNT, Qt::DescendingOrder); // restore list mode and sortorder as a convenience feature QSettings settings; @@ -178,15 +173,6 @@ void CoinControlDialog::setModel(WalletModel *model) } } -// helper function str_pad -QString CoinControlDialog::strPad(QString s, int nPadLength, QString sPadding) -{ - while (s.length() < nPadLength) - s = sPadding + s; - - return s; -} - // ok button void CoinControlDialog::buttonBoxClicked(QAbstractButton* button) { @@ -358,7 +344,7 @@ void CoinControlDialog::sortView(int column, Qt::SortOrder order) sortColumn = column; sortOrder = order; ui->treeWidget->sortItems(column, order); - ui->treeWidget->header()->setSortIndicator(getMappedColumn(sortColumn), sortOrder); + ui->treeWidget->header()->setSortIndicator(sortColumn, sortOrder); } // treeview: clicked on header @@ -366,12 +352,10 @@ void CoinControlDialog::headerSectionClicked(int logicalIndex) { if (logicalIndex == COLUMN_CHECKBOX) // click on most left column -> do nothing { - ui->treeWidget->header()->setSortIndicator(getMappedColumn(sortColumn), sortOrder); + ui->treeWidget->header()->setSortIndicator(sortColumn, sortOrder); } else { - logicalIndex = getMappedColumn(logicalIndex, false); - if (sortColumn == logicalIndex) sortOrder = ((sortOrder == Qt::AscendingOrder) ? Qt::DescendingOrder : Qt::AscendingOrder); else @@ -788,19 +772,20 @@ void CoinControlDialog::updateView() // amount itemOutput->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, out.tx->vout[out.i].nValue)); - itemOutput->setData(COLUMN_AMOUNT_INT64, Qt::DisplayRole, QVariant((qlonglong)out.tx->vout[out.i].nValue)); // padding so that sorting works correctly + itemOutput->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)out.tx->vout[out.i].nValue)); // padding so that sorting works correctly // date itemOutput->setText(COLUMN_DATE, GUIUtil::dateTimeStr(out.tx->GetTxTime())); - itemOutput->setData(COLUMN_DATE_INT64, Qt::DisplayRole, QVariant((qlonglong)out.tx->GetTxTime())); + itemOutput->setData(COLUMN_DATE, Qt::UserRole, QVariant((qlonglong)out.tx->GetTxTime())); // confirmations - itemOutput->setText(COLUMN_CONFIRMATIONS, strPad(QString::number(out.nDepth), 8, " ")); + itemOutput->setText(COLUMN_CONFIRMATIONS, QString::number(out.nDepth)); + itemOutput->setData(COLUMN_CONFIRMATIONS, Qt::UserRole, QVariant((qlonglong)out.nDepth)); // priority double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10 itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority)); - itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPriority), 20, " ")); + itemOutput->setData(COLUMN_PRIORITY, Qt::UserRole, QVariant((qlonglong)dPriority)); dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); nInputSum += nInputSize; @@ -831,9 +816,9 @@ void CoinControlDialog::updateView() dPrioritySum = dPrioritySum / (nInputSum + 78); itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")"); itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum)); - itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " ")); + itemWalletAddress->setData(COLUMN_AMOUNT, Qt::UserRole, QVariant((qlonglong)nSum)); itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum, mempoolEstimatePriority)); - itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPrioritySum), 20, " ")); + itemWalletAddress->setData(COLUMN_PRIORITY, Qt::UserRole, QVariant((qlonglong)dPrioritySum)); } } diff --git a/src/qt/coincontroldialog.h b/src/qt/coincontroldialog.h index 6229d21dab..785079b1ad 100644 --- a/src/qt/coincontroldialog.h +++ b/src/qt/coincontroldialog.h @@ -71,13 +71,12 @@ private: const PlatformStyle *platformStyle; - QString strPad(QString, int, QString); void sortView(int, Qt::SortOrder); void updateView(); enum { - COLUMN_CHECKBOX, + COLUMN_CHECKBOX = 0, COLUMN_AMOUNT, COLUMN_LABEL, COLUMN_ADDRESS, @@ -86,37 +85,9 @@ private: COLUMN_PRIORITY, COLUMN_TXHASH, COLUMN_VOUT_INDEX, - COLUMN_AMOUNT_INT64, - COLUMN_PRIORITY_INT64, - COLUMN_DATE_INT64 }; friend class CCoinControlWidgetItem; - // some columns have a hidden column containing the value used for sorting - int getMappedColumn(int column, bool fVisibleColumn = true) - { - if (fVisibleColumn) - { - if (column == COLUMN_AMOUNT_INT64) - return COLUMN_AMOUNT; - else if (column == COLUMN_PRIORITY_INT64) - return COLUMN_PRIORITY; - else if (column == COLUMN_DATE_INT64) - return COLUMN_DATE; - } - else - { - if (column == COLUMN_AMOUNT) - return COLUMN_AMOUNT_INT64; - else if (column == COLUMN_PRIORITY) - return COLUMN_PRIORITY_INT64; - else if (column == COLUMN_DATE) - return COLUMN_DATE_INT64; - } - - return column; - } - private Q_SLOTS: void showMenu(const QPoint &); void copyAmount(); -- cgit v1.2.3 From dc46b10a087921343bb5a05d08393ece061d6303 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Nov 2016 15:47:20 +0100 Subject: qt: Plug many memory leaks None of these are very serious, and are leaks in objects that are created at most one time. In most cases this means properly using the QObject parent hierarchy, except for BanTablePriv/PeerTablePriv which are not QObject, so use a std::unique_ptr instead. Github-Pull: #9190 Rebased-From: 47db07537746940ee7dd0739a8c73e328837813f --- src/qt/addressbookpage.cpp | 2 +- src/qt/bantablemodel.cpp | 7 ++++++- src/qt/bantablemodel.h | 3 ++- src/qt/bitcoingui.cpp | 2 +- src/qt/coincontroldialog.cpp | 2 +- src/qt/guiutil.cpp | 3 ++- src/qt/guiutil.h | 2 +- src/qt/overviewpage.cpp | 11 +++++------ src/qt/overviewpage.h | 3 ++- src/qt/peertablemodel.cpp | 9 +++++++-- src/qt/peertablemodel.h | 3 ++- src/qt/receivecoinsdialog.cpp | 5 +++-- src/qt/receiverequestdialog.cpp | 2 +- src/qt/recentrequeststablemodel.cpp | 2 +- src/qt/rpcconsole.cpp | 4 ++-- src/qt/transactionview.cpp | 6 +++--- 16 files changed, 40 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 135f15ffa8..727956c88d 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -83,7 +83,7 @@ AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode mode, deleteAction = new QAction(ui->deleteAddress->text(), this); // Build context menu - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(editAction); diff --git a/src/qt/bantablemodel.cpp b/src/qt/bantablemodel.cpp index d95106b5ac..7707ce7b6b 100644 --- a/src/qt/bantablemodel.cpp +++ b/src/qt/bantablemodel.cpp @@ -86,7 +86,7 @@ BanTableModel::BanTableModel(ClientModel *parent) : clientModel(parent) { columns << tr("IP/Netmask") << tr("Banned Until"); - priv = new BanTablePriv(); + priv.reset(new BanTablePriv()); // default to unsorted priv->sortColumn = -1; @@ -94,6 +94,11 @@ BanTableModel::BanTableModel(ClientModel *parent) : refresh(); } +BanTableModel::~BanTableModel() +{ + // Intentionally left empty +} + int BanTableModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); diff --git a/src/qt/bantablemodel.h b/src/qt/bantablemodel.h index fe9600ac0b..3c03d05c05 100644 --- a/src/qt/bantablemodel.h +++ b/src/qt/bantablemodel.h @@ -40,6 +40,7 @@ class BanTableModel : public QAbstractTableModel public: explicit BanTableModel(ClientModel *parent = 0); + ~BanTableModel(); void startAutoRefresh(); void stopAutoRefresh(); @@ -66,7 +67,7 @@ public Q_SLOTS: private: ClientModel *clientModel; QStringList columns; - BanTablePriv *priv; + std::unique_ptr priv; }; #endif // BITCOIN_QT_BANTABLEMODEL_H diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 2afefb733e..169ca50087 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -1147,7 +1147,7 @@ void UnitDisplayStatusBarControl::mousePressEvent(QMouseEvent *event) /** Creates context menu, its actions, and wires up all the relevant signals for mouse events. */ void UnitDisplayStatusBarControl::createContextMenu() { - menu = new QMenu(); + menu = new QMenu(this); Q_FOREACH(BitcoinUnits::Unit u, BitcoinUnits::availableUnits()) { QAction *menuAction = new QAction(QString(BitcoinUnits::name(u)), this); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 81cd098bf9..866d3872c6 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -59,7 +59,7 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *platformStyle, QWidget unlockAction = new QAction(tr("Unlock unspent"), this); // we need to enable/disable this // context menu - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyAmountAction); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 947a4c6821..dec3e56ec5 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -591,7 +591,8 @@ void TableViewLastColumnResizingFixer::on_geometriesChanged() * Initializes all internal variables and prepares the * the resize modes of the last 2 columns of the table and */ -TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth) : +TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent) : + QObject(parent), tableView(table), lastColumnMinimumWidth(lastColMinimumWidth), allColumnsMinimumWidth(allColsMinimumWidth) diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 9267e0a6c9..83cd6b5d46 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -150,7 +150,7 @@ namespace GUIUtil Q_OBJECT public: - TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth); + TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth, QObject *parent); void stretchColumnWidth(int column); private: diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 6a0404cbf7..a010f01021 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -25,8 +25,8 @@ class TxViewDelegate : public QAbstractItemDelegate { Q_OBJECT public: - TxViewDelegate(const PlatformStyle *platformStyle): - QAbstractItemDelegate(), unit(BitcoinUnits::BTC), + TxViewDelegate(const PlatformStyle *platformStyle, QObject *parent=nullptr): + QAbstractItemDelegate(parent), unit(BitcoinUnits::BTC), platformStyle(platformStyle) { @@ -119,8 +119,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent) currentWatchOnlyBalance(-1), currentWatchUnconfBalance(-1), currentWatchImmatureBalance(-1), - txdelegate(new TxViewDelegate(platformStyle)), - filter(0) + txdelegate(new TxViewDelegate(platformStyle, this)) { ui->setupUi(this); @@ -213,7 +212,7 @@ void OverviewPage::setWalletModel(WalletModel *model) if(model && model->getOptionsModel()) { // Set up transaction list - filter = new TransactionFilterProxy(); + filter.reset(new TransactionFilterProxy()); filter->setSourceModel(model->getTransactionTableModel()); filter->setLimit(NUM_ITEMS); filter->setDynamicSortFilter(true); @@ -221,7 +220,7 @@ void OverviewPage::setWalletModel(WalletModel *model) filter->setShowInactive(false); filter->sort(TransactionTableModel::Date, Qt::DescendingOrder); - ui->listTransactions->setModel(filter); + ui->listTransactions->setModel(filter.get()); ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); // Keep up to date with wallet diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index 911443c76a..23746a6b48 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -8,6 +8,7 @@ #include "amount.h" #include +#include class ClientModel; class TransactionFilterProxy; @@ -55,7 +56,7 @@ private: CAmount currentWatchImmatureBalance; TxViewDelegate *txdelegate; - TransactionFilterProxy *filter; + std::unique_ptr filter; private Q_SLOTS: void updateDisplayUnit(); diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 84ad0052fd..3829696e0e 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -115,12 +115,12 @@ PeerTableModel::PeerTableModel(ClientModel *parent) : timer(0) { columns << tr("Node/Service") << tr("User Agent") << tr("Ping Time"); - priv = new PeerTablePriv(); + priv.reset(new PeerTablePriv()); // default to unsorted priv->sortColumn = -1; // set up timer for auto refresh - timer = new QTimer(); + timer = new QTimer(this); connect(timer, SIGNAL(timeout()), SLOT(refresh())); timer->setInterval(MODEL_UPDATE_DELAY); @@ -128,6 +128,11 @@ PeerTableModel::PeerTableModel(ClientModel *parent) : refresh(); } +PeerTableModel::~PeerTableModel() +{ + // Intentionally left empty +} + void PeerTableModel::startAutoRefresh() { timer->start(); diff --git a/src/qt/peertablemodel.h b/src/qt/peertablemodel.h index a2aaaa5d24..8227b5ec76 100644 --- a/src/qt/peertablemodel.h +++ b/src/qt/peertablemodel.h @@ -46,6 +46,7 @@ class PeerTableModel : public QAbstractTableModel public: explicit PeerTableModel(ClientModel *parent = 0); + ~PeerTableModel(); const CNodeCombinedStats *getNodeStats(int idx); int getRowByNodeId(NodeId nodeid); void startAutoRefresh(); @@ -74,7 +75,7 @@ public Q_SLOTS: private: ClientModel *clientModel; QStringList columns; - PeerTablePriv *priv; + std::unique_ptr priv; QTimer *timer; }; diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 0b355837ab..752a05a409 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -25,6 +25,7 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveCoinsDialog), + columnResizingFixer(0), model(0), platformStyle(platformStyle) { @@ -48,7 +49,7 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidg QAction *copyAmountAction = new QAction(tr("Copy amount"), this); // context menu - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyMessageAction); contextMenu->addAction(copyAmountAction); @@ -88,7 +89,7 @@ void ReceiveCoinsDialog::setModel(WalletModel *model) SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection))); // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready. - columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH); + columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this); } } diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index b13ea3df70..04cc2003c5 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -32,7 +32,7 @@ QRImageWidget::QRImageWidget(QWidget *parent): QLabel(parent), contextMenu(0) { - contextMenu = new QMenu(); + contextMenu = new QMenu(this); QAction *saveImageAction = new QAction(tr("&Save Image..."), this); connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage())); contextMenu->addAction(saveImageAction); diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp index 2335d6b282..35d37bb22b 100644 --- a/src/qt/recentrequeststablemodel.cpp +++ b/src/qt/recentrequeststablemodel.cpp @@ -14,7 +14,7 @@ #include RecentRequestsTableModel::RecentRequestsTableModel(CWallet *wallet, WalletModel *parent) : - walletModel(parent) + QAbstractTableModel(parent), walletModel(parent) { Q_UNUSED(wallet); nReceiveRequestsMaxId = 0; diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 650ff8b00d..751ce552da 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -389,7 +389,7 @@ void RPCConsole::setClientModel(ClientModel *model) QAction* banAction365d = new QAction(tr("Ban Node for") + " " + tr("1 &year"), this); // create peer table context menu - peersTableContextMenu = new QMenu(); + peersTableContextMenu = new QMenu(this); peersTableContextMenu->addAction(disconnectAction); peersTableContextMenu->addAction(banAction1h); peersTableContextMenu->addAction(banAction24h); @@ -435,7 +435,7 @@ void RPCConsole::setClientModel(ClientModel *model) QAction* unbanAction = new QAction(tr("&Unban Node"), this); // create ban table context menu - banTableContextMenu = new QMenu(); + banTableContextMenu = new QMenu(this); banTableContextMenu->addAction(unbanAction); // ban table context menu signals diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp index 48cf940502..79af4a1f9c 100644 --- a/src/qt/transactionview.cpp +++ b/src/qt/transactionview.cpp @@ -37,7 +37,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) : QWidget(parent), model(0), transactionProxyModel(0), - transactionView(0), abandonAction(0) + transactionView(0), abandonAction(0), columnResizingFixer(0) { // Build filter row setContentsMargins(0,0,0,0); @@ -147,7 +147,7 @@ TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *pa QAction *editLabelAction = new QAction(tr("Edit label"), this); QAction *showDetailsAction = new QAction(tr("Show transaction details"), this); - contextMenu = new QMenu(); + contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(copyAmountAction); @@ -212,7 +212,7 @@ void TransactionView::setModel(WalletModel *model) transactionView->setColumnWidth(TransactionTableModel::Type, TYPE_COLUMN_WIDTH); transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH); - columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH); + columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH, this); if (model->getOptionsModel()) { -- cgit v1.2.3 From c12f4e93b9be01ba2d6e96f0a851562549049686 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Nov 2016 16:35:14 +0100 Subject: qt: Prevent thread/memory leak on exiting RPCConsole Make ownership of the QThread object clear, so that the RPCConsole can wait for the executor thread to quit before shutdown is called. This increases overall thread safety, and prevents some objects from leaking on exit. Github-Pull: #9190 Rebased-From: 693384eedb1ac7f449e226edd53e2cb52a86e279 --- src/qt/bitcoin.cpp | 8 +++++--- src/qt/bitcoingui.cpp | 6 ++++++ src/qt/rpcconsole.cpp | 24 ++++++++++++++---------- src/qt/rpcconsole.h | 2 ++ 4 files changed, 27 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index d3d13423f7..ca017b2f7b 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -409,6 +409,11 @@ void BitcoinApplication::requestInitialize() void BitcoinApplication::requestShutdown() { + // Show a simple window indicating shutdown status + // Do this first as some of the steps may take some time below, + // for example the RPC console may still be executing a command. + ShutdownWindow::showShutdownWindow(window); + qDebug() << __func__ << ": Requesting shutdown"; startThread(); window->hide(); @@ -423,9 +428,6 @@ void BitcoinApplication::requestShutdown() delete clientModel; clientModel = 0; - // Show a simple window indicating shutdown status - ShutdownWindow::showShutdownWindow(window); - // Request shutdown from core thread Q_EMIT requestedShutdown(); } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 169ca50087..1a5d27f6eb 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -496,6 +496,12 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel) // Disable context menu on tray icon trayIconMenu->clear(); } + // Propagate cleared model to child objects + rpcConsole->setClientModel(nullptr); +#ifdef ENABLE_WALLET + walletFrame->setClientModel(nullptr); +#endif // ENABLE_WALLET + unitDisplayControl->setOptionsModel(nullptr); } } diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 751ce552da..167a3474c1 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -288,7 +288,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : // based timer interface RPCSetTimerInterfaceIfUnset(rpcTimerInterface); - startExecutor(); setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS); ui->detailWidget->hide(); @@ -302,7 +301,6 @@ RPCConsole::RPCConsole(const PlatformStyle *platformStyle, QWidget *parent) : RPCConsole::~RPCConsole() { GUIUtil::saveWindowGeometry("nRPCConsoleWindow", this); - Q_EMIT stopExecutor(); RPCUnsetTimerInterface(rpcTimerInterface); delete rpcTimerInterface; delete ui; @@ -466,6 +464,14 @@ void RPCConsole::setClientModel(ClientModel *model) autoCompleter = new QCompleter(wordList, this); ui->lineEdit->setCompleter(autoCompleter); autoCompleter->popup()->installEventFilter(this); + // Start thread to execute RPC commands. + startExecutor(); + } + if (!model) { + // Client model is being set to 0, this means shutdown() is about to be called. + // Make sure we clean up the executor thread + Q_EMIT stopExecutor(); + thread.wait(); } } @@ -646,9 +652,8 @@ void RPCConsole::browseHistory(int offset) void RPCConsole::startExecutor() { - QThread *thread = new QThread; RPCExecutor *executor = new RPCExecutor(); - executor->moveToThread(thread); + executor->moveToThread(&thread); // Replies from executor object must go to this object connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString))); @@ -656,16 +661,15 @@ void RPCConsole::startExecutor() connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString))); // On stopExecutor signal - // - queue executor for deletion (in execution thread) // - quit the Qt event loop in the execution thread - connect(this, SIGNAL(stopExecutor()), executor, SLOT(deleteLater())); - connect(this, SIGNAL(stopExecutor()), thread, SLOT(quit())); - // Queue the thread for deletion (in this thread) when it is finished - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); + connect(this, SIGNAL(stopExecutor()), &thread, SLOT(quit())); + // - queue executor for deletion (in execution thread) + connect(&thread, SIGNAL(finished()), executor, SLOT(deleteLater()), Qt::DirectConnection); + connect(&thread, SIGNAL(finished()), this, SLOT(test()), Qt::DirectConnection); // Default implementation of QThread::run() simply spins up an event loop in the thread, // which is what we want. - thread->start(); + thread.start(); } void RPCConsole::on_tabWidget_currentChanged(int index) diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 28affa954d..c1efa95f8c 100644 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -12,6 +12,7 @@ #include #include +#include class ClientModel; class PlatformStyle; @@ -140,6 +141,7 @@ private: QMenu *banTableContextMenu; int consoleFontSize; QCompleter *autoCompleter; + QThread thread; }; #endif // BITCOIN_QT_RPCCONSOLE_H -- cgit v1.2.3 From e4bea4fb84dceab44f8a8de4f8b974ba8bb98529 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 19 Nov 2016 11:08:19 +0100 Subject: qt: Avoid splash-screen related memory leak Make splash screen queue its own deletion when it receives the finished command, instead of relying on WA_DeleteOnClose which doesn't work under these circumstances. Github-Pull: #9190 Rebased-From: e4f126a7ba66e7317718c30276dff6db92dc1986 --- src/qt/bitcoin.cpp | 5 ++--- src/qt/splashscreen.cpp | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index ca017b2f7b..d708f4b111 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -365,9 +365,8 @@ void BitcoinApplication::createWindow(const NetworkStyle *networkStyle) void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle) { SplashScreen *splash = new SplashScreen(0, networkStyle); - // We don't hold a direct pointer to the splash screen after creation, so use - // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually. - splash->setAttribute(Qt::WA_DeleteOnClose); + // We don't hold a direct pointer to the splash screen after creation, but the splash + // screen will take care of deleting itself when slotFinish happens. splash->show(); connect(this, SIGNAL(splashFinished(QWidget*)), splash, SLOT(slotFinish(QWidget*))); connect(this, SIGNAL(requestedShutdown()), splash, SLOT(close())); diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index e36d86fddd..68e9ffeb94 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -147,6 +147,7 @@ void SplashScreen::slotFinish(QWidget *mainWin) if (isMinimized()) showNormal(); hide(); + deleteLater(); // No more need for this } static void InitMessage(SplashScreen *splash, const std::string &message) -- cgit v1.2.3 From e5ad693f91632219407b15137b8863223919849b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 19 Nov 2016 14:28:55 +0100 Subject: qt: Avoid shutdownwindow-related memory leak Store a reference to the shutdown window on BitcoinApplication, so that it will be deleted when exiting the main loop. Github-Pull: #9190 Rebased-From: 5204598f8d07d7432d91e9b8781806d2f3d16415 --- src/qt/bitcoin.cpp | 3 ++- src/qt/utilitydialog.cpp | 8 +++----- src/qt/utilitydialog.h | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index d708f4b111..dbf372b12f 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -245,6 +245,7 @@ private: #endif int returnValue; const PlatformStyle *platformStyle; + std::unique_ptr shutdownWindow; void startThread(); }; @@ -411,7 +412,7 @@ void BitcoinApplication::requestShutdown() // Show a simple window indicating shutdown status // Do this first as some of the steps may take some time below, // for example the RPC console may still be executing a command. - ShutdownWindow::showShutdownWindow(window); + shutdownWindow.reset(ShutdownWindow::showShutdownWindow(window)); qDebug() << __func__ << ": Requesting shutdown"; startThread(); diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 947bcdb15a..4ec022881c 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -171,22 +171,20 @@ ShutdownWindow::ShutdownWindow(QWidget *parent, Qt::WindowFlags f): setLayout(layout); } -void ShutdownWindow::showShutdownWindow(BitcoinGUI *window) +QWidget *ShutdownWindow::showShutdownWindow(BitcoinGUI *window) { if (!window) - return; + return nullptr; // Show a simple window indicating shutdown status QWidget *shutdownWindow = new ShutdownWindow(); - // We don't hold a direct pointer to the shutdown window after creation, so use - // Qt::WA_DeleteOnClose to make sure that the window will be deleted eventually. - shutdownWindow->setAttribute(Qt::WA_DeleteOnClose); shutdownWindow->setWindowTitle(window->windowTitle()); // Center shutdown window at where main window was const QPoint global = window->mapToGlobal(window->rect().center()); shutdownWindow->move(global.x() - shutdownWindow->width() / 2, global.y() - shutdownWindow->height() / 2); shutdownWindow->show(); + return shutdownWindow; } void ShutdownWindow::closeEvent(QCloseEvent *event) diff --git a/src/qt/utilitydialog.h b/src/qt/utilitydialog.h index 843bd7f67b..b930429578 100644 --- a/src/qt/utilitydialog.h +++ b/src/qt/utilitydialog.h @@ -43,7 +43,7 @@ class ShutdownWindow : public QWidget public: ShutdownWindow(QWidget *parent=0, Qt::WindowFlags f=0); - static void showShutdownWindow(BitcoinGUI *window); + static QWidget *showShutdownWindow(BitcoinGUI *window); protected: void closeEvent(QCloseEvent *event); -- cgit v1.2.3 From 6f7841c4d490de01c2e458d45ba5cd1ac8ee97d5 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 19 Nov 2016 16:12:23 +0100 Subject: qt: Avoid OpenSSL certstore-related memory leak - Correctly manage the X509 and X509_STORE objects lifetime. Github-Pull: #9190 Rebased-From: ed998ea7a0ecf294211b06e9ef82f1548a621a1d --- src/qt/paymentserver.cpp | 43 ++++++++++++++++++++++++------------------- src/qt/paymentserver.h | 5 +---- 2 files changed, 25 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index 96627710ee..1ef224b521 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -58,14 +58,19 @@ const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest" // BIP70 max payment request size in bytes (DoS protection) const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; -X509_STORE* PaymentServer::certStore = NULL; -void PaymentServer::freeCertStore() +struct X509StoreDeleter { + void operator()(X509_STORE* b) { + X509_STORE_free(b); + } +}; + +struct X509Deleter { + void operator()(X509* b) { X509_free(b); } +}; + +namespace // Anon namespace { - if (PaymentServer::certStore != NULL) - { - X509_STORE_free(PaymentServer::certStore); - PaymentServer::certStore = NULL; - } + std::unique_ptr certStore; } // @@ -107,20 +112,15 @@ static void ReportInvalidCertificate(const QSslCertificate& cert) // void PaymentServer::LoadRootCAs(X509_STORE* _store) { - if (PaymentServer::certStore == NULL) - atexit(PaymentServer::freeCertStore); - else - freeCertStore(); - // Unit tests mostly use this, to pass in fake root CAs: if (_store) { - PaymentServer::certStore = _store; + certStore.reset(_store); return; } // Normal execution, use either -rootcertificates or system certs: - PaymentServer::certStore = X509_STORE_new(); + certStore.reset(X509_STORE_new()); // Note: use "-system-" default here so that users can pass -rootcertificates="" // and get 'I don't like X.509 certificates, don't trust anybody' behavior: @@ -167,11 +167,11 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) QByteArray certData = cert.toDer(); const unsigned char *data = (const unsigned char *)certData.data(); - X509* x509 = d2i_X509(0, &data, certData.size()); - if (x509 && X509_STORE_add_cert(PaymentServer::certStore, x509)) + std::unique_ptr x509(d2i_X509(0, &data, certData.size())); + if (x509 && X509_STORE_add_cert(certStore.get(), x509.get())) { - // Note: X509_STORE_free will free the X509* objects when - // the PaymentServer is destroyed + // Note: X509_STORE increases the reference count to the X509 object, + // we still have to release our reference to it. ++nRootCerts; } else @@ -550,7 +550,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen recipient.paymentRequest = request; recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo()); - request.getMerchant(PaymentServer::certStore, recipient.authenticatedMerchant); + request.getMerchant(certStore.get(), recipient.authenticatedMerchant); QList > sendingTos = request.getPayTo(); QStringList addresses; @@ -807,3 +807,8 @@ bool PaymentServer::verifyAmount(const CAmount& requestAmount) } return fVerified; } + +X509_STORE* PaymentServer::getCertStore() +{ + return certStore.get(); +} diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 2d27ed078b..7202e7dada 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -83,7 +83,7 @@ public: static void LoadRootCAs(X509_STORE* store = NULL); // Return certificate store - static X509_STORE* getCertStore() { return certStore; } + static X509_STORE* getCertStore(); // OptionsModel is used for getting proxy settings and display unit void setOptionsModel(OptionsModel *optionsModel); @@ -140,9 +140,6 @@ private: bool saveURIs; // true during startup QLocalServer* uriServer; - static X509_STORE* certStore; // Trusted root certificates - static void freeCertStore(); - QNetworkAccessManager* netManager; // Used to fetch payment requests OptionsModel *optionsModel; -- cgit v1.2.3 From 0c09d9f00e39c4b1aee0fcb091fba068845b8edd Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Tue, 25 Oct 2016 15:30:55 -0400 Subject: Send tip change notification from invalidateblock This change is needed to prevent sync_blocks timeouts in the mempool_reorg test after the sync_blocks update in the upcoming commit "[qa] Change sync_blocks to pick smarter maxheight". This change was initially suggested by Suhas Daftuar in https://github.com/bitcoin/bitcoin/pull/8680#r78209060 Github-Pull: #9196 Rebased-From: 67c6326abd1788e6f411feb4f44b69774e76aae2 --- src/main.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 083ea194ab..10e2fa983b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3176,6 +3176,7 @@ bool InvalidateBlock(CValidationState& state, const CChainParams& chainparams, C InvalidChainFound(pindex); mempool.removeForReorg(pcoinsTip, chainActive.Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS); + uiInterface.NotifyBlockTip(IsInitialBlockDownload(), pindex->pprev); return true; } -- cgit v1.2.3 From eebc699d3070c71365a0f3542e2f5f6eca3fd281 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Tue, 22 Nov 2016 09:59:50 +0100 Subject: bench: Fix subtle counting issue when rescaling iteration count Make sure that the count is a zero modulo the new mask before scaling, otherwise the next time until a measure triggers will take only 1/2 as long as accounted for. This caused the 'min time' to be potentially off by as much as 100%. Github-Pull: #9200 Rebased-From: e0a9cb25b0af87723d50cb8d8cffa10f1ebf7dcc --- src/bench/bench.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index 227546a7a7..8942da8c74 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -64,8 +64,11 @@ bool State::KeepRunning() return true; } if (elapsed*16 < maxElapsed) { - countMask = ((countMask<<1)|1) & ((1LL<<60)-1); - countMaskInv = 1./(countMask+1); + uint64_t newCountMask = ((countMask<<1)|1) & ((1LL<<60)-1); + if ((count & newCountMask)==0) { + countMask = newCountMask; + countMaskInv = 1./(countMask+1); + } } } lastTime = now; -- cgit v1.2.3 From 396c405e7b4911eea3eceecd001840ffa8c38e95 Mon Sep 17 00:00:00 2001 From: Ivo van der Sangen Date: Sun, 27 Nov 2016 12:08:39 +0100 Subject: Include select.h when WIN32 is not defined Github-Pull: #9224 Rebased-From: 498a1d75e75649b02caeca7b1bc9bbc19e51a566 --- src/compat.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/compat.h b/src/compat.h index 79a297e5e4..2578d6d344 100644 --- a/src/compat.h +++ b/src/compat.h @@ -34,6 +34,7 @@ #else #include #include +#include #include #include #include -- cgit v1.2.3 From 28d0f224fda3ec375c07aaa18f786ce18f674f29 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 29 Nov 2016 17:49:08 -0800 Subject: Fix calculation of number of bound sockets to use Github-Pull: #9253 Rebased-From: 9e1f46821d5bb69e2cbf25738eefa7c6cb99c838 --- src/init.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/init.cpp b/src/init.cpp index eab8de8d02..4a837018b1 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -854,7 +854,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } // Make sure enough file descriptors are available - int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1); + int nBind = std::max( + (mapMultiArgs.count("-bind") ? mapMultiArgs.at("-bind").size() : 0) + + (mapMultiArgs.count("-whitebind") ? mapMultiArgs.at("-whitebind").size() : 0), size_t(1)); int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); nMaxConnections = std::max(nUserMaxConnections, 0); -- cgit v1.2.3 From b1e978cfd6de4e61659e019c52d9c4953b9791c1 Mon Sep 17 00:00:00 2001 From: "S. Matthew English" Date: Thu, 27 Oct 2016 12:13:03 +0200 Subject: instance of 'mem pool' to 'mempool' there was only one instance of 'mem pool' and not 'mempool', so I changed it to conform to the others Github-Pull: #9029 Rebased-From: 1c3ecc70c8cd6c33cf3ff4e2099c8e7d8a8ca9d2 --- src/rpc/blockchain.cpp | 2 +- src/rpc/mining.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6f97671f52..a38b3fc607 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -719,7 +719,7 @@ UniValue gettxout(const UniValue& params, bool fHelp) "\nArguments:\n" "1. \"txid\" (string, required) The transaction id\n" "2. n (numeric, required) vout number\n" - "3. includemempool (boolean, optional) Whether to include the mem pool\n" + "3. includemempool (boolean, optional) Whether to include the mempool\n" "\nResult:\n" "{\n" " \"bestblock\" : \"hash\", (string) the block hash\n" diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index ba48079c05..e5eb4b8c1e 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -229,7 +229,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) " \"difficulty\": xxx.xxxxx (numeric) The current difficulty\n" " \"errors\": \"...\" (string) Current errors\n" " \"networkhashps\": nnn, (numeric) The network hashes per second\n" - " \"pooledtx\": n (numeric) The size of the mem pool\n" + " \"pooledtx\": n (numeric) The size of the mempool\n" " \"testnet\": true|false (boolean) If using testnet or not\n" " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" "}\n" -- cgit v1.2.3 From 87fbcede5ceb49fc24c3102c0f3cf81a68617ac6 Mon Sep 17 00:00:00 2001 From: matthias Date: Mon, 31 Oct 2016 01:11:46 +0100 Subject: Change all instance of 'GMT epoch' to 'Unix epoch' Github-Pull: #9041 Rebased-From: 7f61b49de82989dc692e7750860eb1ec4044db7a --- src/rpc/misc.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 06489566ba..11befb529f 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -57,7 +57,7 @@ UniValue getinfo(const UniValue& params, bool fHelp) " \"proxy\": \"host:port\", (string, optional) the proxy used by the server\n" " \"difficulty\": xxxxxx, (numeric) the current difficulty\n" " \"testnet\": true|false, (boolean) if the server is using testnet or not\n" - " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" + " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n" diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 2ad379e46b..fdb7a53d3b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2274,7 +2274,7 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n" " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n" " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" - " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" + " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" -- cgit v1.2.3 From 387ec9d9635580fbbedc222126c5b1a68002d543 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Sat, 15 Oct 2016 23:45:07 +0800 Subject: Add script tests for FindAndDelete in pre-segwit and segwit scripts Github-Pull: #8927 Rebased-From: acf853df910339412bafb1743f42af1774f5b910 --- src/script/interpreter.cpp | 4 ++-- src/test/data/tx_invalid.json | 26 ++++++++++++++++++++++++++ src/test/data/tx_valid.json | 23 +++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 836cf9ee35..0e17ddc130 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -890,7 +890,7 @@ bool EvalScript(vector >& stack, const CScript& script, un // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); - // Drop the signature, since there's no way for a signature to sign itself + // Drop the signature in pre-segwit scripts but not segwit scripts if (sigversion == SIGVERSION_BASE) { scriptCode.FindAndDelete(CScript(vchSig)); } @@ -951,7 +951,7 @@ bool EvalScript(vector >& stack, const CScript& script, un // Subset of script starting at the most recent codeseparator CScript scriptCode(pbegincodehash, pend); - // Drop the signatures, since there's no way for a signature to sign itself + // Drop the signature in pre-segwit scripts but not segwit scripts for (int k = 0; k < nSigsCount; k++) { valtype& vchSig = stacktop(-isig-k); diff --git a/src/test/data/tx_invalid.json b/src/test/data/tx_invalid.json index f8baee0577..f7d9e1847f 100644 --- a/src/test/data/tx_invalid.json +++ b/src/test/data/tx_invalid.json @@ -314,5 +314,31 @@ [[["0000000000000000000000000000000000000000000000000000000000000100", 0, "0x60 0x21 0xff25429251b5a84f452230a3c75fd886b7fc5a7865ce4a7bb7a9d7c5be6da3dbff", 1000]], "010000000100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e803000000000000015100000000", "P2SH,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM"], +["FindAndDelete tests"], +["This is a test of FindAndDelete. The first tx is a spend of normal scriptPubKey and the second tx is a spend of bare P2WSH."], +["The redeemScript/witnessScript is CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01>."], +["The signature is <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> ,"], +["where the pubkey is obtained through key recovery with sig and the wrong sighash."], +["This is to show that FindAndDelete is applied only to non-segwit scripts"], +["To show that the tests are 'correctly wrong', they should pass by modifying OP_CHECKSIG under interpreter.cpp"], +["by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE)"], +["Non-segwit: wrong sighash (without FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]], +"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012103b12a1ec8428fc74166926318c15e17408fea82dbb157575e16a8c365f546248f4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: wrong sighash (with FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]], +"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9d7ed6e161f0e255c10bbfcca0128a9e2035c2c8da58899c54d22d3a31afdef4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"], +["This is multisig version of the FindAndDelete tests"], +["Script is 2 CHECKMULTISIGVERIFY DROP"], +["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"], +["Signature is 0 2 "], +["Should pass by replacing (sigversion == SIGVERSION_BASE) with (sigversion != SIGVERSION_BASE) under OP_CHECKMULTISIG"], +["Non-segwit: wrong sighash (without FindAndDelete) = 4bc6a53e8e16ef508c19e38bba08831daba85228b0211f323d4cb0999cf2a5e8"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]], +"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596015221023fd5dd42b44769c5653cbc5947ff30ab8871f240ad0c0e7432aefe84b5b4ff3421039d52178dbde360b83f19cf348deb04fa8360e1bf5634577be8e50fafc2b0e4ef4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: wrong sighash (with FindAndDelete) = 17c50ec2181ecdfdc85ca081174b248199ba81fff730794d4f69b8ec031f2dce"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]], +"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601010221023cb6055f4b57a1580c5a753e19610cafaedf7e0ff377731c77837fd666eae1712102c1b1db303ac232ffa8e5e7cc2cf5f96c6e40d3e6914061204c0541cb2043a0969552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] diff --git a/src/test/data/tx_valid.json b/src/test/data/tx_valid.json index 1ea70135b4..2f299aa5fe 100644 --- a/src/test/data/tx_valid.json +++ b/src/test/data/tx_valid.json @@ -487,5 +487,28 @@ [[["6eb98797a21c6c10aa74edf29d618be109f48a8e94c694f3701e08ca69186436", 1, "HASH160 0x14 0x9993a429037b5d912407a71c252019287b8d27a5 EQUAL", 987654321]], "0100000000010136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000023220020a16b5755f7f6f96dbd65f5f0d6ab9418b89af4b1f14a1bb8a09062c35f0dcb54ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac080047304402206ac44d672dac41f9b00e28f4df20c52eeb087207e8d758d76d92c6fab3b73e2b0220367750dbbe19290069cba53d096f44530e4f98acaa594810388cf7409a1870ce01473044022068c7946a43232757cbdf9176f009a928e1cd9a1a8c212f15c1e11ac9f2925d9002205b75f937ff2f9f3c1246e547e54f62e027f64eefa2695578cc6432cdabce271502473044022059ebf56d98010a932cf8ecfec54c48e6139ed6adb0728c09cbe1e4fa0915302e022007cd986c8fa870ff5d2b3a89139c9fe7e499259875357e20fcbb15571c76795403483045022100fbefd94bd0a488d50b79102b5dad4ab6ced30c4069f1eaa69a4b5a763414067e02203156c6a5c9cf88f91265f5a942e96213afae16d83321c8b31bb342142a14d16381483045022100a5263ea0553ba89221984bd7f0b13613db16e7a70c549a86de0cc0444141a407022005c360ef0ae5a5d4f9f2f87a56c1546cc8268cab08c73501d6b3be2e1e1a8a08824730440220525406a1482936d5a21888260dc165497a90a15669636d8edca6b9fe490d309c022032af0c646a34a44d1f4576bf6a4a74b67940f8faa84c7df9abe12a01a11e2b4783cf56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28bfab54554ae8c658ac5c3e0ce6e79ad336331f78c428dd43eea8449b21034b8113d703413d57761b8b9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b14862c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b56ae00000000", "P2SH,WITNESS"], +["FindAndDelete tests"], +["This is a test of FindAndDelete. The first tx is a spend of normal P2SH and the second tx is a spend of bare P2WSH."], +["The redeemScript/witnessScript is CHECKSIGVERIFY <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01>."], +["The signature is <0x30450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01> ,"], +["where the pubkey is obtained through key recovery with sig and correct sighash."], +["This is to show that FindAndDelete is applied only to non-segwit scripts"], +["Non-segwit: correct sighash (with FindAndDelete) = 1ba1fe3bc90c5d1265460e684ce6774e324f0fabdf67619eda729e64e8b6bc08"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7000, "HASH160 0x14 0x0c746489e2d83cdbb5b90b432773342ba809c134 EQUAL", 200000]], +"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0121037a3fb04bcdb09eba90f69961ba1692a3528e45e67c85b200df820212d7594d334aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: correct sighash (without FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"], +[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]], +"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"], +["This is multisig version of the FindAndDelete tests"], +["Script is 2 CHECKMULTISIGVERIFY DROP"], +["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"], +["Signature is 0 2 "], +["Non-segwit: correct sighash (with FindAndDelete) = 1d50f00ba4db2917b903b0ec5002e017343bb38876398c9510570f5dce099295"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7000, "HASH160 0x14 0x5748407f5ca5cdca53ba30b79040260770c9ee1b EQUAL", 200000]], +"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601522102cd74a2809ffeeed0092bc124fd79836706e41f048db3f6ae9df8708cefb83a1c2102e615999372426e46fd107b76eaf007156a507584aa2cc21de9eee3bdbd26d36c4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"], +["BIP143: correct sighash (without FindAndDelete) = c1628a1e7c67f14ca0c27c06e4fdeec2e6d1a73c7a91d7c046ff83e835aebb72"], +[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]], +"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"], + ["Make diffs cleaner by leaving a comment here without comma at the end"] ] -- cgit v1.2.3 From a710a4304033eea581e463a5fb0502bdb8991aa1 Mon Sep 17 00:00:00 2001 From: wodry Date: Wed, 30 Nov 2016 17:19:08 +0100 Subject: Improvement of documentation of command line parameter 'whitelist' Github-Pull: #9251 Rebased-From: 8a70a9da3da0df5c376042b18b87f0a63e88d2e3 --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/init.cpp b/src/init.cpp index 4a837018b1..bbdab14ee0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -376,7 +376,7 @@ std::string HelpMessage(HelpMessageMode mode) #endif #endif strUsage += HelpMessageOpt("-whitebind=", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6")); - strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") + + strUsage += HelpMessageOpt("-whitelist=", _("Whitelist peers connecting from the given IP address (e.g. 1.2.3.4) or CIDR notated network (e.g. 1.2.3.0/24). Can be specified multiple times.") + " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); strUsage += HelpMessageOpt("-whitelistrelay", strprintf(_("Accept relayed transactions received from whitelisted peers even when not relaying transactions (default: %d)"), DEFAULT_WHITELISTRELAY)); strUsage += HelpMessageOpt("-whitelistforcerelay", strprintf(_("Force relay of transactions from whitelisted peers even if they violate local relay policy (default: %d)"), DEFAULT_WHITELISTFORCERELAY)); -- cgit v1.2.3 From 21ccb9f2530af996fc0a58df418837a08b75781f Mon Sep 17 00:00:00 2001 From: Gregory Sanders Date: Sun, 20 Nov 2016 09:54:51 -0500 Subject: Add option to return non-segwit serialization via rpc Github-Pull: #9194 Rebased-From: 835c75acaac004c3315395dcd7d1f193dfb9e5da --- src/core_io.h | 2 +- src/core_write.cpp | 4 ++-- src/init.cpp | 4 ++++ src/rpc/blockchain.cpp | 2 +- src/rpc/rawtransaction.cpp | 2 +- src/rpc/server.cpp | 8 ++++++++ src/rpc/server.h | 5 +++++ src/wallet/rpcwallet.cpp | 2 +- 8 files changed, 23 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/core_io.h b/src/core_io.h index b559d44bf5..44a732b697 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -25,7 +25,7 @@ extern std::vector ParseHexUV(const UniValue& v, const std::strin // core_write.cpp extern std::string FormatScript(const CScript& script); -extern std::string EncodeHexTx(const CTransaction& tx); +extern std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0); extern void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); extern void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry); diff --git a/src/core_write.cpp b/src/core_write.cpp index ea01ddc10d..9f859ba9e1 100644 --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -116,9 +116,9 @@ string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode) return str; } -string EncodeHexTx(const CTransaction& tx) +string EncodeHexTx(const CTransaction& tx, const int serialFlags) { - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | serialFlags); ssTx << tx; return HexStr(ssTx.begin(), ssTx.end()); } diff --git a/src/init.cpp b/src/init.cpp index bbdab14ee0..8e40c4388d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -364,6 +364,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-port=", strprintf(_("Listen for connections on (default: %u or testnet: %u)"), Params(CBaseChainParams::MAIN).GetDefaultPort(), Params(CBaseChainParams::TESTNET).GetDefaultPort())); strUsage += HelpMessageOpt("-proxy=", _("Connect through SOCKS5 proxy")); strUsage += HelpMessageOpt("-proxyrandomize", strprintf(_("Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u)"), DEFAULT_PROXYRANDOMIZE)); + strUsage += HelpMessageOpt("-rpcserialversion", strprintf(_("Sets the serialization of raw transaction or block hex returned in non-verbose mode, non-segwit(0) or segwit(>0) (default: %d)"), DEFAULT_RPC_SERIALIZE_VERSION)); strUsage += HelpMessageOpt("-seednode=", _("Connect to a node to retrieve peer addresses, and disconnect")); strUsage += HelpMessageOpt("-timeout=", strprintf(_("Specify connection timeout in milliseconds (minimum: 1, default: %d)"), DEFAULT_CONNECT_TIMEOUT)); strUsage += HelpMessageOpt("-torcontrol=:", strprintf(_("Tor control port to use if onion listening enabled (default: %s)"), DEFAULT_TOR_CONTROL)); @@ -982,6 +983,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) if (GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM); + if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0) + return InitError("rpcserialversion must be non-negative."); + nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); fEnableReplacement = GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a38b3fc607..b4d53a9f3d 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -607,7 +607,7 @@ UniValue getblock(const UniValue& params, bool fHelp) if (!fVerbose) { - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssBlock << block; std::string strHex = HexStr(ssBlock.begin(), ssBlock.end()); return strHex; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index b2bbb8b3ed..2719829e65 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -209,7 +209,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); - string strHex = EncodeHexTx(tx); + string strHex = EncodeHexTx(tx, RPCSerializationFlags()); if (!fVerbose) return strHex; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 102c776314..deeabcb8d7 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -495,4 +495,12 @@ void RPCRunLater(const std::string& name, boost::function func, int6 deadlineTimers.insert(std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds*1000)))); } +int RPCSerializationFlags() +{ + int flag = 0; + if (GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) == 0) + flag |= SERIALIZE_TRANSACTION_NO_WITNESS; + return flag; +} + CRPCTable tableRPC; diff --git a/src/rpc/server.h b/src/rpc/server.h index b5ccc153d0..1ed8f2466d 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -19,6 +19,8 @@ #include +static const unsigned int DEFAULT_RPC_SERIALIZE_VERSION = 1; + class CRPCCommand; namespace RPCServer @@ -195,4 +197,7 @@ void InterruptRPC(); void StopRPC(); std::string JSONRPCExecBatch(const UniValue& vReq); +// Retrieves any serialization flags requested in command line argument +int RPCSerializationFlags(); + #endif // BITCOIN_RPCSERVER_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fdb7a53d3b..17bda050c3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1780,7 +1780,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) ListTransactions(wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); - string strHex = EncodeHexTx(static_cast(wtx)); + string strHex = EncodeHexTx(static_cast(wtx), RPCSerializationFlags()); entry.push_back(Pair("hex", strHex)); return entry; -- cgit v1.2.3 From f26dab7e90cfb1733736c1dd63c507254de84a34 Mon Sep 17 00:00:00 2001 From: instagibbs Date: Tue, 22 Nov 2016 15:47:07 -0500 Subject: Adapt ZMQ/rest serialization to take rpcserialversion arg Github-Pull: #9194 Rebased-From: ad5c4c93cae53a2a6f74880ca11b4d788677a378 --- src/rest.cpp | 4 ++-- src/zmq/zmqpublishnotifier.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/rest.cpp b/src/rest.cpp index 2dff8d7dad..57cd9baeb7 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -228,7 +228,7 @@ static bool rest_block(HTTPRequest* req, return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); } - CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssBlock(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssBlock << block; switch (rf) { @@ -367,7 +367,7 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true)) return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); - CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ssTx << tx; switch (rf) { diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index b6c907980f..cdef17e08c 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -6,6 +6,7 @@ #include "zmqpublishnotifier.h" #include "main.h" #include "util.h" +#include "rpc/server.h" static std::multimap mapPublishNotifiers; @@ -165,7 +166,7 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) LogPrint("zmq", "zmq: Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); const Consensus::Params& consensusParams = Params().GetConsensus(); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); { LOCK(cs_main); CBlock block; @@ -185,7 +186,7 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr { uint256 hash = transaction.GetHash(); LogPrint("zmq", "zmq: Publish rawtx %s\n", hash.GetHex()); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); ss << transaction; return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size()); } -- cgit v1.2.3