Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backport: merge bitcoin#21594, #21843, #22306, #22211, #22387, #21528, #22616, #22604, #22960, #23218 (networking backports: part 3) #5978

Merged
merged 13 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions doc/release-notes-5978.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
RPC changes
-----------------------

- The `getnodeaddresses` RPC now returns a "network" field indicating the
network type (ipv4, ipv6, onion, or i2p) for each address.

- `getnodeaddresses` now also accepts a "network" argument (ipv4, ipv6, onion,
or i2p) to return only addresses of the specified network.

P2P and network changes
-----------------------

- A dashd node will no longer rumour addresses to inbound peers by default.
They will become eligible for address gossip after sending an ADDR, ADDRV2,
or GETADDR message.
3 changes: 1 addition & 2 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1491,9 +1491,8 @@ void CConnman::CalculateNumConnectionsChangedStats()
statsClient.gauge("peers.torConnections", torNodes, 1.0f);
}

bool CConnman::ShouldRunInactivityChecks(const CNode& node, std::optional<int64_t> now_in) const
bool CConnman::ShouldRunInactivityChecks(const CNode& node, int64_t now) const
{
const int64_t now = now_in ? now_in.value() : GetTimeSeconds();
return node.nTimeConnected + m_peer_connect_timeout < now;
}

Expand Down
5 changes: 3 additions & 2 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,8 @@ class CNode
};

// in bitcoin: m_tx_relay == nullptr if we're not relaying transactions with this peer
// in dash: m_tx_relay should never be nullptr, use `!IsBlockOnlyConn() == false` instead
// in dash: m_tx_relay should never be nullptr, we don't relay transactions if
// `IsBlockOnlyConn() == true` is instead
std::unique_ptr<TxRelay> m_tx_relay{std::make_unique<TxRelay>()};

/** UNIX epoch time of the last block received from this peer that we had
Expand Down Expand Up @@ -1236,7 +1237,7 @@ friend class CNode;
void SetAsmap(std::vector<bool> asmap) { addrman.m_asmap = std::move(asmap); }

/** Return true if we should disconnect the peer for failing an inactivity check. */
bool ShouldRunInactivityChecks(const CNode& node, std::optional<int64_t> now=std::nullopt) const;
bool ShouldRunInactivityChecks(const CNode& node, int64_t secs_now) const;

private:
struct ListenSocket {
Expand Down
3 changes: 2 additions & 1 deletion src/net_permissions.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ enum class NetPermissionFlags : uint32_t {
NoBan = (1U << 4) | Download,
// Can query the mempool
Mempool = (1U << 5),
// Can request addrs without hitting a privacy-preserving cache
// Can request addrs without hitting a privacy-preserving cache, and send us
// unlimited amounts of addrs.
Addr = (1U << 7),

// True if the user did not specifically set fine grained permissions
Expand Down
162 changes: 131 additions & 31 deletions src/net_processing.cpp

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/net_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ struct CNodeStateStats {
int m_starting_height = -1;
std::chrono::microseconds m_ping_wait;
std::vector<int> vHeightInFlight;
uint64_t m_addr_processed = 0;
uint64_t m_addr_rate_limited = 0;
bool m_addr_relay_enabled{false};
};

class PeerManager : public CValidationInterface, public NetEventsInterface
Expand Down
2 changes: 1 addition & 1 deletion src/netaddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class CNetAddr
*/
bool IsRelayable() const
{
return IsIPv4() || IsIPv6() || IsTor();
return IsIPv4() || IsIPv6() || IsTor() || IsI2P();
}

/**
Expand Down
39 changes: 26 additions & 13 deletions src/rpc/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ static RPCHelpMan getpeerinfo()
{
{RPCResult::Type::NUM, "n", "The heights of blocks we're currently asking from this peer"},
}},
{RPCResult::Type::BOOL, "addr_relay_enabled", "Whether we participate in address relay with this peer"},
{RPCResult::Type::NUM, "addr_processed", "The total number of addresses processed, excluding those dropped due to rate limiting"},
{RPCResult::Type::NUM, "addr_rate_limited", "The total number of addresses dropped due to rate limiting"},
{RPCResult::Type::BOOL, "whitelisted", "Whether the peer is whitelisted"},
{RPCResult::Type::ARR, "permissions", "Any special permissions that have been granted to this peer",
{
Expand Down Expand Up @@ -243,6 +246,9 @@ static RPCHelpMan getpeerinfo()
heights.push_back(height);
}
obj.pushKV("inflight", heights);
obj.pushKV("addr_relay_enabled", statestats.m_addr_relay_enabled);
obj.pushKV("addr_processed", statestats.m_addr_processed);
obj.pushKV("addr_rate_limited", statestats.m_addr_rate_limited);
}
obj.pushKV("whitelisted", stats.m_legacyWhitelisted);
UniValue permissions(UniValue::VARR);
Expand Down Expand Up @@ -901,25 +907,30 @@ static RPCHelpMan setnetworkactive()
static RPCHelpMan getnodeaddresses()
{
return RPCHelpMan{"getnodeaddresses",
"\nReturn known addresses which can potentially be used to find new nodes in the network\n",
"\nReturn known addresses, which can potentially be used to find new nodes in the network.\n",
{
{"count", RPCArg::Type::NUM, /* default */ "1", "The maximum number of addresses to return. Specify 0 to return all known addresses."},
{"network", RPCArg::Type::STR, /* default */ "all networks", "Return only addresses of the specified network. Can be one of: " + Join(GetNetworkNames(), ", ") + "."},
},
RPCResult{
RPCResult::Type::ARR, "", "",
{
{RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " of when the node was last seen"},
{RPCResult::Type::NUM, "services", "The services offered"},
{RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " when the node was last seen"},
{RPCResult::Type::NUM, "services", "The services offered by the node"},
{RPCResult::Type::STR, "address", "The address of the node"},
{RPCResult::Type::NUM, "port", "The port of the node"},
{RPCResult::Type::NUM, "port", "The port number of the node"},
{RPCResult::Type::STR, "network", "The network (" + Join(GetNetworkNames(), ", ") + ") the node connected through"},
}},
}
},
RPCExamples{
HelpExampleCli("getnodeaddresses", "8")
+ HelpExampleRpc("getnodeaddresses", "8")
+ HelpExampleCli("getnodeaddresses", "4 \"i2p\"")
+ HelpExampleCli("-named getnodeaddresses", "network=onion count=12")
+ HelpExampleRpc("getnodeaddresses", "8")
+ HelpExampleRpc("getnodeaddresses", "4, \"i2p\"")
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
Expand All @@ -928,15 +939,16 @@ static RPCHelpMan getnodeaddresses()
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
}

int count = 1;
if (!request.params[0].isNull()) {
count = request.params[0].get_int();
if (count < 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");
}
const int count{request.params[0].isNull() ? 1 : request.params[0].get_int()};
if (count < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");

const std::optional<Network> network{request.params[1].isNull() ? std::nullopt : std::optional<Network>{ParseNetwork(request.params[1].get_str())}};
if (network == NET_UNROUTABLE) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Network not recognized: %s", request.params[1].get_str()));
}

// returns a shuffled list of CAddress
std::vector<CAddress> vAddr = node.connman->GetAddresses(count, /* max_pct */ 0, /* network */ std::nullopt);
const std::vector<CAddress> vAddr{node.connman->GetAddresses(count, /* max_pct */ 0, network)};
UniValue ret(UniValue::VARR);

for (const CAddress& addr : vAddr) {
Expand All @@ -945,6 +957,7 @@ static RPCHelpMan getnodeaddresses()
obj.pushKV("services", (uint64_t)addr.nServices);
obj.pushKV("address", addr.ToStringIP());
obj.pushKV("port", addr.GetPort());
obj.pushKV("network", GetNetworkName(addr.GetNetClass()));
ret.push_back(obj);
}
return ret;
Expand Down Expand Up @@ -1022,7 +1035,7 @@ static const CRPCCommand commands[] =
{ "network", "clearbanned", &clearbanned, {} },
{ "network", "cleardiscouraged", &cleardiscouraged, {} },
{ "network", "setnetworkactive", &setnetworkactive, {"state"} },
{ "network", "getnodeaddresses", &getnodeaddresses, {"count"} },
{ "network", "getnodeaddresses", &getnodeaddresses, {"count", "network"} },

{ "hidden", "addconnection", &addconnection, {"address", "connection_type"} },
{ "hidden", "addpeeraddress", &addpeeraddress, {"address", "port"} },
Expand Down
2 changes: 2 additions & 0 deletions src/test/denialofservice_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
{
const CChainParams& chainparams = Params();
auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
// Disable inactivity checks for this test to avoid interference
static_cast<ConnmanTestMsg*>(connman.get())->SetPeerConnectTimeout(99999);
auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr, *m_node.scheduler,
*m_node.chainman, *m_node.mempool, *m_node.govman, *m_node.sporkman,
::deterministicMNManager, m_node.cj_ctx, m_node.llmq_ctx, false);
Expand Down
6 changes: 6 additions & 0 deletions src/test/util/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@

struct ConnmanTestMsg : public CConnman {
using CConnman::CConnman;

void SetPeerConnectTimeout(int64_t timeout)
{
m_peer_connect_timeout = timeout;
}

void AddTestNode(CNode& node)
{
LOCK(cs_vNodes);
Expand Down
5 changes: 1 addition & 4 deletions test/functional/feature_bip68_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ class BIP68Test(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.extra_args = [
[
"-acceptnonstdtxn=1",
"-peertimeout=9999", # bump because mocktime might cause a disconnect otherwise
],
["-acceptnonstdtxn=1"],
["-acceptnonstdtxn=0"],
]

Expand Down
1 change: 0 additions & 1 deletion test/functional/feature_maxuploadtarget.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def set_test_params(self):
self.extra_args = [[
"-maxuploadtarget=200",
"-blockmaxsize=999000",
"-peertimeout=9999", # bump because mocktime might cause a disconnect otherwise
"-maxtipage="+str(2*60*60*24*7),
"-acceptnonstdtxn=1"
]]
Expand Down
Loading
Loading