From 0597a77be55ae44924df766436423f888e69884f Mon Sep 17 00:00:00 2001 From: Rhett Creighton Date: Fri, 5 Jun 2026 23:41:56 +0000 Subject: [PATCH] beta7: beta7: fix user -addnode starved/ignored by bootstrap-peer injection (+ respect -connect) ThreadOpenAddedConnections (src/net.cpp): - LogPrintf when an -addnode name fails to resolve (was silently skipped), so a misconfigured/unreachable -addnode is visible in the debug log. - Track IP-literal -addnode addresses (resolved with no DNS via LookupNumeric) and, when any such literal peer is still not connected after the connect pass, retry after 15s instead of the full 120s name-resolution backoff so IP-literal addnodes reconnect promptly. Name entries keep the 120s interval to avoid hammering DNS. The -connect guard and append-after-user-entries + std::find de-duplication of the injected bootstrap peers (src/init.cpp) already landed on master in commit 0517f09316 (peer-discovery: fix fresh nodes stuck at "syncing 0"): the injection is wrapped in if (!mapArgs.count("-connect")) and uses push_back so user -addnode entries remain first in vAddedNodes. Verified; no change needed there. Consensus impact: none -- outbound peer-connection scheduling and logging only; no change to block/tx validation, PoW, script, serialization, or chainparams. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/net.cpp | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index 4aab7bda1c0..36b4aa08486 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1466,6 +1466,12 @@ void ThreadOpenAddedConnections() } list > lservAddressesToAdd(0); + // Numeric (IP-literal) -addnode addresses that still need a connection. + // Such entries cost no DNS, so a resolution failure can never explain them + // being unconnected -- only a transient connect failure can -- and they + // should be retried promptly rather than after the full 2-minute + // name-resolution backoff. + std::vector vIpLiteralAddrs; BOOST_FOREACH(const std::string& strAddNode, lAddresses) { vector vservNode(0); if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0)) @@ -1476,6 +1482,19 @@ void ThreadOpenAddedConnections() BOOST_FOREACH(const CService& serv, vservNode) setservAddNodeAddresses.insert(serv); } + // Did this entry resolve with no DNS (a bare IP literal)? If so, + // track its addresses so we can shorten the retry backoff below. + CService servLiteral; + if (LookupNumeric(strAddNode.c_str(), servLiteral, Params().GetDefaultPort())) + BOOST_FOREACH(const CService& serv, vservNode) + vIpLiteralAddrs.push_back(serv); + } + else + { + // Previously skipped silently, leaving the user with no clue why an + // -addnode never connected. A name that fails to resolve here will + // be retried on the next loop iteration. + LogPrintf("ThreadOpenAddedConnections: could not resolve -addnode=%s; will retry\n", strAddNode); } } // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry @@ -1498,7 +1517,23 @@ void ThreadOpenAddedConnections() OpenNetworkConnection(CAddress(vserv[i % vserv.size()]), &grant); MilliSleep(500); } - MilliSleep(120000); // Retry every 2 minutes + // Is any IP-literal -addnode still not connected? If so, retry it quickly + // (no DNS to wait on); otherwise -- only name entries pending, or all + // connected -- keep the longer interval so we don't hammer DNS. + bool fHaveIpLiteralPending = false; + { + LOCK(cs_vNodes); + BOOST_FOREACH(const CService& addrLit, vIpLiteralAddrs) { + bool fConnected = false; + BOOST_FOREACH(CNode* pnode, vNodes) + if (pnode->addr == addrLit) { fConnected = true; break; } + if (!fConnected) { fHaveIpLiteralPending = true; break; } + } + } + // IP-literal -addnode entries need no DNS, so retry them quickly instead of + // waiting the full 2-minute name-resolution backoff; name entries keep the + // longer interval so we don't hammer DNS. + MilliSleep(fHaveIpLiteralPending ? 15000 : 120000); } }