From 8d58c4d81f18e9a51d11ee354434cf55d03a4add Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Thu, 26 May 2016 14:26:01 -0400 Subject: net: Pass CConnman around as needed --- src/main.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 4b42afb56..32859ebc2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3016,7 +3016,7 @@ static void NotifyHeaderTip() { * or an activated best chain. pblock is either NULL or a pointer to a block * that is already loaded (to avoid loading it again from disk). */ -bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock) { +bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, const CBlock *pblock, CConnman* connman) { CBlockIndex *pindexMostWork = NULL; CBlockIndex *pindexNewTip = NULL; do { @@ -3731,7 +3731,7 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha return true; } -bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp) +bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp, CConnman* connman) { { LOCK(cs_main); @@ -3753,7 +3753,7 @@ bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, C NotifyHeaderTip(); - if (!ActivateBestChain(state, chainparams, pblock)) + if (!ActivateBestChain(state, chainparams, pblock, connman)) return error("%s: ActivateBestChain failed", __func__); return true; @@ -4891,7 +4891,7 @@ uint32_t GetFetchFlags(CNode* pfrom, CBlockIndex* pprev, const Consensus::Params return nFetchFlags; } -bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams) +bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman& connman) { LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) @@ -5680,7 +5680,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, txn.blockhash = cmpctblock.header.GetHash(); CDataStream blockTxnMsg(SER_NETWORK, PROTOCOL_VERSION); blockTxnMsg << txn; - return ProcessMessage(pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams); + return ProcessMessage(pfrom, NetMsgType::BLOCKTXN, blockTxnMsg, nTimeReceived, chainparams, connman); } else { req.blockhash = pindex->GetBlockHash(); pfrom->PushMessage(NetMsgType::GETBLOCKTXN, req); @@ -5701,7 +5701,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, headers.push_back(cmpctblock.header); CDataStream vHeadersMsg(SER_NETWORK, PROTOCOL_VERSION); vHeadersMsg << headers; - return ProcessMessage(pfrom, NetMsgType::HEADERS, vHeadersMsg, nTimeReceived, chainparams); + return ProcessMessage(pfrom, NetMsgType::HEADERS, vHeadersMsg, nTimeReceived, chainparams, connman); } } @@ -5737,7 +5737,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->PushMessage(NetMsgType::GETDATA, invs); } else { CValidationState state; - ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL); + ProcessNewBlock(state, chainparams, pfrom, &block, false, NULL, &connman); int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes @@ -5913,7 +5913,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Such an unrequested block may still be processed, subject to the // conditions in AcceptBlock(). bool forceProcessing = pfrom->fWhitelisted && !IsInitialBlockDownload(); - ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL); + ProcessNewBlock(state, chainparams, pfrom, &block, forceProcessing, NULL, &connman); int nDoS; if (state.IsInvalid(nDoS)) { assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes @@ -6163,7 +6163,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // requires LOCK(cs_vRecvMsg) -bool ProcessMessages(CNode* pfrom) +bool ProcessMessages(CNode* pfrom, CConnman& connman) { const CChainParams& chainparams = Params(); //if (fDebug) @@ -6240,7 +6240,7 @@ bool ProcessMessages(CNode* pfrom) bool fRet = false; try { - fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime, chainparams); + fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime, chainparams, connman); boost::this_thread::interruption_point(); } catch (const std::ios_base::failure& e) @@ -6305,7 +6305,7 @@ public: } }; -bool SendMessages(CNode* pto) +bool SendMessages(CNode* pto, CConnman& connman) { const Consensus::Params& consensusParams = Params().GetConsensus(); { -- cgit v1.2.3 From 5b446dd5b11d4f403554bc2dd5a7a94c7d20422a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 24 May 2016 20:56:17 -0400 Subject: net: Pass CConnection to wallet rather than using the global --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 32859ebc2..4dc9d71ee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6431,7 +6431,7 @@ bool SendMessages(CNode* pto, CConnman& connman) // transactions become unconfirmed and spams other nodes. if (!fReindex && !fImporting && !IsInitialBlockDownload()) { - GetMainSignals().Broadcast(nTimeBestReceived); + GetMainSignals().Broadcast(nTimeBestReceived, &connman); } // -- cgit v1.2.3 From aaf018e3b79417ecfd39291a8c100df77969d77a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 24 May 2016 18:59:16 -0400 Subject: net: handle nodesignals in CConnman --- src/main.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 4dc9d71ee..bd85fa8f0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -348,7 +348,8 @@ void InitializeNode(NodeId nodeid, const CNode *pnode) { state.address = pnode->addr; } -void FinalizeNode(NodeId nodeid) { +void FinalizeNode(NodeId nodeid, bool& fUpdateConnectionTime) { + fUpdateConnectionTime = false; LOCK(cs_main); CNodeState *state = State(nodeid); @@ -356,7 +357,7 @@ void FinalizeNode(NodeId nodeid) { nSyncStarted--; if (state->nMisbehavior == 0 && state->fCurrentlyConnected) { - AddressCurrentlyConnected(state->address); + fUpdateConnectionTime = true; } BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight) { -- cgit v1.2.3 From a0f3d3cdad630103d919a4ec802c413b87fa1f1a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Sat, 16 Apr 2016 17:43:11 -0400 Subject: net: move ban and addrman functions into CConnman --- src/main.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index bd85fa8f0..f3babb71d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4944,7 +4944,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->nServices = ServiceFlags(nServiceInt); if (!pfrom->fInbound) { - addrman.SetServices(pfrom->addr, pfrom->nServices); + connman.SetServices(pfrom->addr, pfrom->nServices); } if (pfrom->nServicesExpected & ~pfrom->nServices) { @@ -5038,12 +5038,12 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // Get recent addresses - if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || addrman.size() < 1000) + if (pfrom->fOneShot || pfrom->nVersion >= CADDR_TIME_VERSION || connman.GetAddressCount() < 1000) { pfrom->PushMessage(NetMsgType::GETADDR); pfrom->fGetAddr = true; } - addrman.Good(pfrom->addr); + connman.MarkAddressGood(pfrom->addr); } pfrom->fSuccessfullyConnected = true; @@ -5108,7 +5108,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, vRecv >> vAddr; // Don't want addr from older versions unless seeding - if (pfrom->nVersion < CADDR_TIME_VERSION && addrman.size() > 1000) + if (pfrom->nVersion < CADDR_TIME_VERSION && connman.GetAddressCount() > 1000) return true; if (vAddr.size() > 1000) { @@ -5160,7 +5160,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (fReachable) vAddrOk.push_back(addr); } - addrman.Add(vAddrOk, pfrom->addr, 2 * 60 * 60); + connman.AddNewAddresses(vAddrOk, pfrom->addr, 2 * 60 * 60); if (vAddr.size() < 1000) pfrom->fGetAddr = false; if (pfrom->fOneShot) @@ -5950,7 +5950,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fSentAddr = true; pfrom->vAddrToSend.clear(); - vector vAddr = addrman.GetAddr(); + vector vAddr = connman.GetAddresses(); BOOST_FOREACH(const CAddress &addr, vAddr) pfrom->PushAddress(addr); } @@ -6393,7 +6393,7 @@ bool SendMessages(CNode* pto, CConnman& connman) LogPrintf("Warning: not banning local peer %s!\n", pto->addr.ToString()); else { - CNode::Ban(pto->addr, BanReasonNodeMisbehaving); + connman.Ban(pto->addr, BanReasonNodeMisbehaving); } } state.fShouldBan = false; -- cgit v1.2.3 From 53347f0cb99e514815e44a56439a4a10012238f8 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Sat, 16 Apr 2016 19:13:12 -0400 Subject: net: create generic functor accessors and move vNodes to CConnman --- src/main.cpp | 85 +++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 32 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index f3babb71d..af598d487 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -470,7 +470,7 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { } } -void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pfrom) { +void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pfrom, CConnman& connman) { if (nLocalServices & NODE_WITNESS) { // Don't ever request compact blocks when segwit is enabled. return; @@ -484,11 +484,12 @@ void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pf if (lNodesAnnouncingHeaderAndIDs.size() >= 3) { // As per BIP152, we only get 3 of our peers to announce // blocks using compact encodings. - CNode* pnodeStop = FindNode(lNodesAnnouncingHeaderAndIDs.front()); - if (pnodeStop) { + bool found = connman.ForNode(lNodesAnnouncingHeaderAndIDs.front(), [fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion](CNode* pnodeStop){ pnodeStop->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); + return true; + }); + if(found) lNodesAnnouncingHeaderAndIDs.pop_front(); - } } fAnnounceUsingCMPCTBLOCK = true; pfrom->PushMessage(NetMsgType::SENDCMPCT, fAnnounceUsingCMPCTBLOCK, nCMPCTBLOCKVersion); @@ -3089,15 +3090,15 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, int nBlockEstimate = 0; if (fCheckpointsEnabled) nBlockEstimate = Checkpoints::GetTotalBlocksEstimate(chainparams.Checkpoints()); - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) { + if(connman) { + connman->ForEachNode([nNewHeight, nBlockEstimate, &vHashes](CNode* pnode) { if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) { BOOST_REVERSE_FOREACH(const uint256& hash, vHashes) { pnode->PushBlockHash(hash); } } - } + return true; + }); } // Notify external listeners about the new tip. if (!vHashes.empty()) { @@ -4726,6 +4727,45 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) return true; } +static void RelayTransaction(const CTransaction& tx, CConnman& connman) +{ + CInv inv(MSG_TX, tx.GetHash()); + connman.ForEachNode([&inv](CNode* pnode) + { + pnode->PushInventory(inv); + return true; + }); +} + +static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connman) +{ + int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s) + + // Relay to a limited number of other nodes + // Use deterministic randomness to send to the same nodes for 24 hours + // at a time so the addrKnowns of the chosen nodes prevent repeats + static const uint64_t salt0 = GetRand(std::numeric_limits::max()); + static const uint64_t salt1 = GetRand(std::numeric_limits::max()); + uint64_t hashAddr = addr.GetHash(); + std::multimap mapMix; + const CSipHasher hasher = CSipHasher(salt0, salt1).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60)); + + auto sortfunc = [&mapMix, &hasher](CNode* pnode) { + if (pnode->nVersion >= CADDR_TIME_VERSION) { + uint64_t hashKey = CSipHasher(hasher).Write(pnode->id).Finalize(); + mapMix.emplace(hashKey, pnode); + } + return true; + }; + + auto pushfunc = [&addr, &mapMix, &nRelayNodes] { + for (auto mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) + mi->second->PushAddress(addr); + }; + + connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc)); +} + void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams) { std::deque::iterator it = pfrom->vRecvGetData.begin(); @@ -5135,26 +5175,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) { // Relay to a limited number of other nodes - { - LOCK(cs_vNodes); - // Use deterministic randomness to send to the same nodes for 24 hours - // at a time so the addrKnowns of the chosen nodes prevent repeats - static const uint64_t salt0 = GetRand(std::numeric_limits::max()); - static const uint64_t salt1 = GetRand(std::numeric_limits::max()); - uint64_t hashAddr = addr.GetHash(); - multimap mapMix; - const CSipHasher hasher = CSipHasher(salt0, salt1).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60)); - BOOST_FOREACH(CNode* pnode, vNodes) - { - if (pnode->nVersion < CADDR_TIME_VERSION) - continue; - uint64_t hashKey = CSipHasher(hasher).Write(pnode->id).Finalize(); - mapMix.insert(make_pair(hashKey, pnode)); - } - int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s) - for (multimap::iterator mi = mapMix.begin(); mi != mapMix.end() && nRelayNodes-- > 0; ++mi) - ((*mi).second)->PushAddress(addr); - } + RelayAddress(addr, fReachable, connman); } // Do not store addresses outside our network if (fReachable) @@ -5448,7 +5469,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (!AlreadyHave(inv) && AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs)) { mempool.check(pcoinsTip); - RelayTransaction(tx); + RelayTransaction(tx, connman); for (unsigned int i = 0; i < tx.vout.size(); i++) { vWorkQueue.emplace_back(inv.hash, i); } @@ -5485,7 +5506,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, continue; if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2)) { LogPrint("mempool", " accepted orphan tx %s\n", orphanHash.ToString()); - RelayTransaction(orphanTx); + RelayTransaction(orphanTx, connman); for (unsigned int i = 0; i < orphanTx.vout.size(); i++) { vWorkQueue.emplace_back(orphanHash, i); } @@ -5560,7 +5581,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int nDoS = 0; if (!state.IsInvalid(nDoS) || nDoS == 0) { LogPrintf("Force relaying tx %s from whitelisted peer=%d\n", tx.GetHash().ToString(), pfrom->id); - RelayTransaction(tx); + RelayTransaction(tx, connman); } else { LogPrintf("Not relaying invalid transaction %s from whitelisted peer=%d (%s)\n", tx.GetHash().ToString(), pfrom->id, FormatStateMessage(state)); } @@ -5886,7 +5907,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (nodestate->fProvidesHeaderAndIDs && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN) && !(nLocalServices & NODE_WITNESS)) { // We seem to be rather well-synced, so it appears pfrom was the first to provide us // with this block! Let's get them to announce using compact blocks in the future. - MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom); + MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom, connman); // In any case, we want to download using a compact block, not a regular one vGetData[0] = CInv(MSG_CMPCT_BLOCK, vGetData[0].hash); } -- cgit v1.2.3 From 960cf2e4058a9c195bf64e1aecb46024f9ef022a Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Sun, 17 Apr 2016 20:21:58 -0400 Subject: net: move nLocalHostNonce to CConnman This behavior seems to have been quite racy and broken. Move nLocalHostNonce into CNode, and check received nonces against all non-fully-connected nodes. If there's a match, assume we've connected to ourself. --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index af598d487..43ccb6374 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5025,7 +5025,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } // Disconnect if we connected to ourself - if (nNonce == nLocalHostNonce && nNonce > 1) + if (pfrom->fInbound && !connman.CheckIncomingNonce(nNonce)) { LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString()); pfrom->fDisconnect = true; -- cgit v1.2.3 From 63cafa6329e1a0a1daf2d324931aca42ba1cbb19 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Mon, 18 Apr 2016 21:44:42 -0400 Subject: net: move send/recv statistics to CConnman --- src/main.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 43ccb6374..019db0bdb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4766,7 +4766,7 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connma connman.ForEachNodeThen(std::move(sortfunc), std::move(pushfunc)); } -void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams) +void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams, CConnman& connman) { std::deque::iterator it = pfrom->vRecvGetData.begin(); @@ -4808,7 +4808,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam // disconnect node in case we have reached the outbound limit for serving historical blocks // never disconnect whitelisted nodes static const int nOneWeek = 7 * 24 * 60 * 60; // assume > 1 week = historical - if (send && CNode::OutboundTargetReached(true) && ( ((pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > nOneWeek)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted) + if (send && connman.OutboundTargetReached(true) && ( ((pindexBestHeader != NULL) && (pindexBestHeader->GetBlockTime() - mi->second->GetBlockTime() > nOneWeek)) || inv.type == MSG_FILTERED_BLOCK) && !pfrom->fWhitelisted) { LogPrint("net", "historical block serving limit reached, disconnect peer=%d\n", pfrom->GetId()); @@ -5312,7 +5312,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, LogPrint("net", "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->id); pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end()); - ProcessGetData(pfrom, chainparams.GetConsensus()); + ProcessGetData(pfrom, chainparams.GetConsensus(), connman); } @@ -5986,7 +5986,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; } - if (CNode::OutboundTargetReached(false) && !pfrom->fWhitelisted) + if (connman.OutboundTargetReached(false) && !pfrom->fWhitelisted) { LogPrint("net", "mempool request with bandwidth limit reached, disconnect peer=%d\n", pfrom->GetId()); pfrom->fDisconnect = true; @@ -6202,7 +6202,7 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman) bool fOk = true; if (!pfrom->vRecvGetData.empty()) - ProcessGetData(pfrom, chainparams.GetConsensus()); + ProcessGetData(pfrom, chainparams.GetConsensus(), connman); // this maintains the order of responses if (!pfrom->vRecvGetData.empty()) return fOk; -- cgit v1.2.3 From be9c796dc51c05cab0b84d2e66c928973c6e5ed6 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 19 Apr 2016 00:01:19 -0400 Subject: net: move SendBufferSize/ReceiveFloodSize to CConnman --- src/main.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 019db0bdb..db9d0d3f1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4769,6 +4769,7 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connma void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParams, CConnman& connman) { std::deque::iterator it = pfrom->vRecvGetData.begin(); + unsigned int nMaxSendBufferSize = connman.GetSendBufferSize(); vector vNotFound; @@ -4776,7 +4777,7 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam while (it != pfrom->vRecvGetData.end()) { // Don't bother if send buffer is too full to respond anyway - if (pfrom->nSendSize >= SendBufferSize()) + if (pfrom->nSendSize >= nMaxSendBufferSize) break; const CInv &inv = *it; @@ -4934,6 +4935,8 @@ uint32_t GetFetchFlags(CNode* pfrom, CBlockIndex* pprev, const Consensus::Params bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman& connman) { + unsigned int nMaxSendBufferSize = connman.GetSendBufferSize(); + LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { @@ -5283,7 +5286,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Track requests for our stuff GetMainSignals().Inventory(inv.hash); - if (pfrom->nSendSize > (SendBufferSize() * 2)) { + if (pfrom->nSendSize > (nMaxSendBufferSize * 2)) { Misbehaving(pfrom->GetId(), 50); return error("send buffer size() = %u", pfrom->nSendSize); } @@ -6188,6 +6191,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, bool ProcessMessages(CNode* pfrom, CConnman& connman) { const CChainParams& chainparams = Params(); + unsigned int nMaxSendBufferSize = connman.GetSendBufferSize(); //if (fDebug) // LogPrintf("%s(%u messages)\n", __func__, pfrom->vRecvMsg.size()); @@ -6210,7 +6214,7 @@ bool ProcessMessages(CNode* pfrom, CConnman& connman) std::deque::iterator it = pfrom->vRecvMsg.begin(); while (!pfrom->fDisconnect && it != pfrom->vRecvMsg.end()) { // Don't bother if send buffer is too full to respond anyway - if (pfrom->nSendSize >= SendBufferSize()) + if (pfrom->nSendSize >= nMaxSendBufferSize) break; // get next message -- cgit v1.2.3 From bd72937dc462b86f0e84184b270a232f7bfaa8db Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 19 Apr 2016 00:04:58 -0400 Subject: net: move nLocalServices/nRelevantServices to CConnman These are in-turn passed to CNode at connection time. This allows us to offer different services to different peers (or test the effects of doing so). --- src/main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index db9d0d3f1..a916cbc12 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -471,7 +471,7 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { } void MaybeSetPeerAsAnnouncingHeaderAndIDs(const CNodeState* nodestate, CNode* pfrom, CConnman& connman) { - if (nLocalServices & NODE_WITNESS) { + if (pfrom->GetLocalServices() & NODE_WITNESS) { // Don't ever request compact blocks when segwit is enabled. return; } @@ -4945,7 +4945,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, } - if (!(nLocalServices & NODE_BLOOM) && + if (!(pfrom->GetLocalServices() & NODE_BLOOM) && (strCommand == NetMsgType::FILTERLOAD || strCommand == NetMsgType::FILTERADD || strCommand == NetMsgType::FILTERCLEAR)) @@ -5068,7 +5068,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, // Advertise our address if (fListen && !IsInitialBlockDownload()) { - CAddress addr = GetLocalAddress(&pfrom->addr); + CAddress addr = GetLocalAddress(&pfrom->addr, pfrom->GetLocalServices()); if (addr.IsRoutable()) { LogPrint("net", "ProcessMessages: advertising address %s\n", addr.ToString()); @@ -5263,7 +5263,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, nodestate->nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER && (!IsWitnessEnabled(chainActive.Tip(), chainparams.GetConsensus()) || State(pfrom->GetId())->fHaveWitness)) { inv.type |= nFetchFlags; - if (nodestate->fProvidesHeaderAndIDs && !(nLocalServices & NODE_WITNESS)) + if (nodestate->fProvidesHeaderAndIDs && !(pfrom->GetLocalServices() & NODE_WITNESS)) vToFetch.push_back(CInv(MSG_CMPCT_BLOCK, inv.hash)); else vToFetch.push_back(inv); @@ -5907,7 +5907,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pindexLast->GetBlockHash().ToString(), pindexLast->nHeight); } if (vGetData.size() > 0) { - if (nodestate->fProvidesHeaderAndIDs && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN) && !(nLocalServices & NODE_WITNESS)) { + if (nodestate->fProvidesHeaderAndIDs && vGetData.size() == 1 && mapBlocksInFlight.size() == 1 && pindexLast->pprev->IsValid(BLOCK_VALID_CHAIN) && !(pfrom->GetLocalServices() & NODE_WITNESS)) { // We seem to be rather well-synced, so it appears pfrom was the first to provide us // with this block! Let's get them to announce using compact blocks in the future. MaybeSetPeerAsAnnouncingHeaderAndIDs(nodestate, pfrom, connman); @@ -5982,7 +5982,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, else if (strCommand == NetMsgType::MEMPOOL) { - if (!(nLocalServices & NODE_BLOOM) && !pfrom->fWhitelisted) + if (!(pfrom->GetLocalServices() & NODE_BLOOM) && !pfrom->fWhitelisted) { LogPrint("net", "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->GetId()); pfrom->fDisconnect = true; -- cgit v1.2.3 From f60b9059e4958245bda82e9656c52a31d5268ad9 Mon Sep 17 00:00:00 2001 From: Cory Fields Date: Tue, 24 May 2016 16:42:17 -0400 Subject: net: Pass best block known height into CConnman CConnman then passes the current best height into CNode at creation time. This way CConnman/CNode have no dependency on main for height, and the signals only move in one direction. This also helps to prevent identity leakage a tiny bit. Before this change, an attacker could theoretically make 2 connections on different interfaces. They would connect fully on one, and only establish the initial connection on the other. Once they receive a new block, they would relay it to your first connection, and immediately commence the version handshake on the second. Since the new block height is reflected immediately, they could attempt to learn whether the two connections were correlated. This is, of course, incredibly unlikely to work due to the small timings involved and receipt from other senders. But it doesn't hurt to lock-in nBestHeight at the time of connection, rather than letting the remote choose the time. --- src/main.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index a916cbc12..1835d9712 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -325,12 +325,6 @@ CNodeState *State(NodeId pnode) { return &it->second; } -int GetHeight() -{ - LOCK(cs_main); - return chainActive.Height(); -} - void UpdatePreferredDownload(CNode* node, CNodeState* state) { nPreferredDownload -= state->fPreferredDownload; @@ -639,7 +633,6 @@ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) { void RegisterNodeSignals(CNodeSignals& nodeSignals) { - nodeSignals.GetHeight.connect(&GetHeight); nodeSignals.ProcessMessages.connect(&ProcessMessages); nodeSignals.SendMessages.connect(&SendMessages); nodeSignals.InitializeNode.connect(&InitializeNode); @@ -648,7 +641,6 @@ void RegisterNodeSignals(CNodeSignals& nodeSignals) void UnregisterNodeSignals(CNodeSignals& nodeSignals) { - nodeSignals.GetHeight.disconnect(&GetHeight); nodeSignals.ProcessMessages.disconnect(&ProcessMessages); nodeSignals.SendMessages.disconnect(&SendMessages); nodeSignals.InitializeNode.disconnect(&InitializeNode); @@ -3058,6 +3050,8 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, // When we reach this point, we switched to a new tip (stored in pindexNewTip). // Notifications/callbacks that can run without cs_main + if(connman) + connman->SetBestHeight(nNewHeight); // throw all transactions though the signal-interface // while _not_ holding the cs_main lock -- cgit v1.2.3 From d1a2295f0d58423652b124b48fc887a9721b765c Mon Sep 17 00:00:00 2001 From: Jeremy Rubin Date: Wed, 15 Jun 2016 19:28:04 -0400 Subject: Made the ForEachNode* functions in src/net.cpp more pragmatic and self documenting --- src/main.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 1835d9712..e4c9ce562 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3091,7 +3091,6 @@ bool ActivateBestChain(CValidationState &state, const CChainParams& chainparams, pnode->PushBlockHash(hash); } } - return true; }); } // Notify external listeners about the new tip. @@ -4727,7 +4726,6 @@ static void RelayTransaction(const CTransaction& tx, CConnman& connman) connman.ForEachNode([&inv](CNode* pnode) { pnode->PushInventory(inv); - return true; }); } @@ -4749,7 +4747,6 @@ static void RelayAddress(const CAddress& addr, bool fReachable, CConnman& connma uint64_t hashKey = CSipHasher(hasher).Write(pnode->id).Finalize(); mapMix.emplace(hashKey, pnode); } - return true; }; auto pushfunc = [&addr, &mapMix, &nRelayNodes] { -- cgit v1.2.3