From 3587f6a0247d12b7d50b184b16248ccec3757ff0 Mon Sep 17 00:00:00 2001 From: Patick Strateman Date: Tue, 17 Nov 2015 16:59:18 -0800 Subject: [PATCH 1/4] Fix relay mechanism for whitelisted peers under blocks only mode. Previously in blocks only mode all inv messages where type!=MSG_BLOCK would be rejected without regard for whitelisting or whitelistalwaysrelay. As such whitelisted peers would never send the transaction (which would be processed). --- src/main.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 8fb121c00dbff..c7e67a1d74ca7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4210,6 +4210,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return error("message inv size() = %u", vInv.size()); } + bool fBlocksOnly = GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); + + // Allow whitelisted peers to send data other than blocks in blocks only mode if whitelistalwaysrelay is true + if (pfrom->fWhitelisted && GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY)) + fBlocksOnly = false; + LOCK(cs_main); std::vector vToFetch; @@ -4224,9 +4230,6 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, bool fAlreadyHave = AlreadyHave(inv); LogPrint("net", "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->id); - if (!fAlreadyHave && !fImporting && !fReindex && inv.type != MSG_BLOCK && !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) - pfrom->AskFor(inv); - if (inv.type == MSG_BLOCK) { UpdateBlockAvailability(pfrom->GetId(), inv.hash); if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) { @@ -4250,6 +4253,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", "getheaders (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->id); } } + else + { + if (fBlocksOnly) + LogPrint("net", "peer sent inv %s in violation of protocol peer=%d\n", inv.ToString(), pfrom->id); + else if (!fAlreadyHave && !fImporting && !fReindex) + pfrom->AskFor(inv); + } // Track requests for our stuff GetMainSignals().Inventory(inv.hash); From d8aaa51bec7d9e96eab78b88f494efb937a93bfb Mon Sep 17 00:00:00 2001 From: Patick Strateman Date: Tue, 17 Nov 2015 17:01:43 -0800 Subject: [PATCH 2/4] Bail early in processing transactions in blocks only mode. Previously unsolicited transactions would be processed as normal. --- src/main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index c7e67a1d74ca7..243a6475978e6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4384,6 +4384,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == "tx") { + // Stop processing the transaction early if + // We are in blocks only mode and peer is either not whitelisted or whitelistalwaysrelay is off + if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY))) + { + LogPrint("net", "peer sent transaction in violation of protocol peer=%d\n", pfrom->id); + return true; + } + vector vWorkQueue; vector vEraseQueue; CTransaction tx; From 08843ed99843078acb10eecda2045d5f0f1c2b4f Mon Sep 17 00:00:00 2001 From: Peter Todd Date: Fri, 20 Nov 2015 18:51:44 -0500 Subject: [PATCH 3/4] Add relaytxes status to getpeerinfo --- src/net.cpp | 1 + src/net.h | 1 + src/rpcnet.cpp | 2 ++ 3 files changed, 4 insertions(+) diff --git a/src/net.cpp b/src/net.cpp index 000eefc858ba8..cff4c5450505b 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -617,6 +617,7 @@ void CNode::copyStats(CNodeStats &stats) { stats.nodeid = this->GetId(); X(nServices); + X(fRelayTxes); X(nLastSend); X(nLastRecv); X(nTimeConnected); diff --git a/src/net.h b/src/net.h index ebdbe77565456..559cdf0878838 100644 --- a/src/net.h +++ b/src/net.h @@ -180,6 +180,7 @@ class CNodeStats public: NodeId nodeid; uint64_t nServices; + bool fRelayTxes; int64_t nLastSend; int64_t nLastRecv; int64_t nTimeConnected; diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 89150106494ac..2578848891501 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -90,6 +90,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) " \"addr\":\"host:port\", (string) The ip address and port of the peer\n" " \"addrlocal\":\"ip:port\", (string) local address\n" " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n" + " \"relaytxes\":true|false, (boolean) Whether peer has asked us to relay transactions to it\n" " \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n" " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n" " \"bytessent\": n, (numeric) The total bytes sent\n" @@ -134,6 +135,7 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) if (!(stats.addrLocal.empty())) obj.push_back(Pair("addrlocal", stats.addrLocal)); obj.push_back(Pair("services", strprintf("%016x", stats.nServices))); + obj.push_back(Pair("relaytxes", stats.fRelayTxes)); obj.push_back(Pair("lastsend", stats.nLastSend)); obj.push_back(Pair("lastrecv", stats.nLastRecv)); obj.push_back(Pair("bytessent", stats.nSendBytes)); From 80ae230a52ab781806876ea8be174b1793b9b683 Mon Sep 17 00:00:00 2001 From: Patick Strateman Date: Fri, 20 Nov 2015 15:54:27 -0800 Subject: [PATCH 4/4] Improve log messages for blocks only violations. --- src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 243a6475978e6..7242abb0cbf9f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4256,7 +4256,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else { if (fBlocksOnly) - LogPrint("net", "peer sent inv %s in violation of protocol peer=%d\n", inv.ToString(), pfrom->id); + LogPrint("net", "transaction (%s) inv sent in violation of protocol peer=%d\n", inv.hash.ToString(), pfrom->id); else if (!fAlreadyHave && !fImporting && !fReindex) pfrom->AskFor(inv); } @@ -4388,7 +4388,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // We are in blocks only mode and peer is either not whitelisted or whitelistalwaysrelay is off if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && (!pfrom->fWhitelisted || !GetBoolArg("-whitelistalwaysrelay", DEFAULT_WHITELISTALWAYSRELAY))) { - LogPrint("net", "peer sent transaction in violation of protocol peer=%d\n", pfrom->id); + LogPrint("net", "transaction sent in violation of protocol peer=%d\n", pfrom->id); return true; }