Skip to content

Commit c77c877

Browse files
committed
net: Load fixed seeds from reachable networks for which we don't have addresses
Previously, we'd only load fixed seeds if we'd not know any addresses at all. This change makes it possible to change -onlynet abruptly, e.g. from -onlynet=onion to -onlynet=i2p and still find peers.
1 parent d35595a commit c77c877

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

src/net.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,19 @@ int CConnman::GetExtraBlockRelayCount() const
15751575
return std::max(block_relay_peers - m_max_outbound_block_relay, 0);
15761576
}
15771577

1578+
std::unordered_set<Network> CConnman::GetReachableEmptyNetworks() const
1579+
{
1580+
std::unordered_set<Network> networks{};
1581+
for (int n = 0; n < NET_MAX; n++) {
1582+
enum Network net = (enum Network)n;
1583+
if (net == NET_UNROUTABLE || net == NET_INTERNAL) continue;
1584+
if (IsReachable(net) && addrman.Size(net, std::nullopt) == 0) {
1585+
networks.insert(net);
1586+
}
1587+
}
1588+
return networks;
1589+
}
1590+
15781591
void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
15791592
{
15801593
SetSyscallSandboxPolicy(SyscallSandboxPolicy::NET_OPEN_CONNECTION);
@@ -1624,7 +1637,8 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
16241637
if (interruptNet)
16251638
return;
16261639

1627-
if (add_fixed_seeds && addrman.size() == 0) {
1640+
const std::unordered_set<Network> fixed_seed_networks{GetReachableEmptyNetworks()};
1641+
if (add_fixed_seeds && !fixed_seed_networks.empty()) {
16281642
// When the node starts with an empty peers.dat, there are a few other sources of peers before
16291643
// we fallback on to fixed seeds: -dnsseed, -seednode, -addnode
16301644
// If none of those are available, we fallback on to fixed seeds immediately, else we allow
@@ -1633,7 +1647,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
16331647
// It is cheapest to check if enough time has passed first.
16341648
if (GetTime<std::chrono::seconds>() > start + std::chrono::minutes{1}) {
16351649
add_fixed_seeds_now = true;
1636-
LogPrintf("Adding fixed seeds as 60 seconds have passed and addrman is empty\n");
1650+
LogPrintf("Adding fixed seeds as 60 seconds have passed and addrman is empty for at least one reachable network\n");
16371651
}
16381652

16391653
// Checking !dnsseed is cheaper before locking 2 mutexes.
@@ -1650,14 +1664,12 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
16501664
// We will not make outgoing connections to peers that are unreachable
16511665
// (e.g. because of -onlynet configuration).
16521666
// Therefore, we do not add them to addrman in the first place.
1653-
// Note that if you change -onlynet setting from one network to another,
1654-
// peers.dat will contain only peers of unreachable networks and
1655-
// manual intervention will be needed (either delete peers.dat after
1656-
// configuration change or manually add some reachable peer using addnode),
1657-
// see <https://github.com/bitcoin/bitcoin/issues/26035> for details.
1667+
// In case previously unreachable networks become reachable
1668+
// (e.g. in case of -onlynet changes by the user), fixed seeds will
1669+
// be loaded only for networks for which we have no addressses.
16581670
seed_addrs.erase(std::remove_if(seed_addrs.begin(), seed_addrs.end(),
1659-
[](const CAddress& addr) { return !IsReachable(addr); }),
1660-
seed_addrs.end());
1671+
[&fixed_seed_networks](const CAddress& addr) { return fixed_seed_networks.count(addr.GetNetwork()) == 0; }),
1672+
seed_addrs.end());
16611673
CNetAddr local;
16621674
local.SetInternal("fixedseeds");
16631675
addrman.Add(seed_addrs, local);

src/net.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <memory>
4040
#include <optional>
4141
#include <thread>
42+
#include <unordered_set>
4243
#include <vector>
4344

4445
class AddrMan;
@@ -969,6 +970,12 @@ class CConnman
969970
void RecordBytesRecv(uint64_t bytes);
970971
void RecordBytesSent(uint64_t bytes) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex);
971972

973+
/**
974+
Return reachable networks for which we have no addresses in addrman and therefore
975+
may require loading fixed seeds.
976+
*/
977+
std::unordered_set<Network> GetReachableEmptyNetworks() const;
978+
972979
/**
973980
* Return vector of current BLOCK_RELAY peers.
974981
*/

0 commit comments

Comments
 (0)