aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/net.cpp4
-rw-r--r--src/net.h4
-rw-r--r--src/rpc/net.cpp4
-rwxr-xr-xtest/functional/p2p_add_connections.py15
-rwxr-xr-xtest/functional/test_framework/test_node.py15
5 files changed, 33 insertions, 9 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 57b8844d6b..504619dec5 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1217,7 +1217,6 @@ bool CConnman::AddConnection(const std::string& address, ConnectionType conn_typ
switch (conn_type) {
case ConnectionType::INBOUND:
case ConnectionType::MANUAL:
- case ConnectionType::FEELER:
return false;
case ConnectionType::OUTBOUND_FULL_RELAY:
max_connections = m_max_outbound_full_relay;
@@ -1228,6 +1227,9 @@ bool CConnman::AddConnection(const std::string& address, ConnectionType conn_typ
// no limit for ADDR_FETCH because -seednode has no limit either
case ConnectionType::ADDR_FETCH:
break;
+ // no limit for FEELER connections since they're short-lived
+ case ConnectionType::FEELER:
+ break;
} // no default case, so the compiler can warn about missing cases
// Count existing connections
diff --git a/src/net.h b/src/net.h
index 28cd635976..81004a203c 100644
--- a/src/net.h
+++ b/src/net.h
@@ -892,8 +892,8 @@ public:
* Attempts to open a connection. Currently only used from tests.
*
* @param[in] address Address of node to try connecting to
- * @param[in] conn_type ConnectionType::OUTBOUND or ConnectionType::BLOCK_RELAY
- * or ConnectionType::ADDR_FETCH
+ * @param[in] conn_type ConnectionType::OUTBOUND, ConnectionType::BLOCK_RELAY,
+ * ConnectionType::ADDR_FETCH or ConnectionType::FEELER
* @return bool Returns false if there are no available
* slots for this connection:
* - conn_type not a supported ConnectionType
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 861b889118..4ef44a93db 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -343,7 +343,7 @@ static RPCHelpMan addconnection()
"\nOpen an outbound connection to a specified node. This RPC is for testing only.\n",
{
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address and port to attempt connecting to."},
- {"connection_type", RPCArg::Type::STR, RPCArg::Optional::NO, "Type of connection to open (\"outbound-full-relay\", \"block-relay-only\" or \"addr-fetch\")."},
+ {"connection_type", RPCArg::Type::STR, RPCArg::Optional::NO, "Type of connection to open (\"outbound-full-relay\", \"block-relay-only\", \"addr-fetch\" or \"feeler\")."},
},
RPCResult{
RPCResult::Type::OBJ, "", "",
@@ -371,6 +371,8 @@ static RPCHelpMan addconnection()
conn_type = ConnectionType::BLOCK_RELAY;
} else if (conn_type_in == "addr-fetch") {
conn_type = ConnectionType::ADDR_FETCH;
+ } else if (conn_type_in == "feeler") {
+ conn_type = ConnectionType::FEELER;
} else {
throw JSONRPCError(RPC_INVALID_PARAMETER, self.ToString());
}
diff --git a/test/functional/p2p_add_connections.py b/test/functional/p2p_add_connections.py
index a04ba5db2d..82674befeb 100755
--- a/test/functional/p2p_add_connections.py
+++ b/test/functional/p2p_add_connections.py
@@ -14,6 +14,13 @@ def check_node_connections(*, node, num_in, num_out):
assert_equal(info["connections_in"], num_in)
assert_equal(info["connections_out"], num_out)
+class P2PFeelerReceiver(P2PInterface):
+ def on_version(self, message):
+ # The bitcoind node closes feeler connections as soon as a version
+ # message is received from the test framework. Don't send any responses
+ # to the node's version message since the connection will already be
+ # closed.
+ pass
class P2PAddConnections(BitcoinTestFramework):
def set_test_params(self):
@@ -91,6 +98,14 @@ class P2PAddConnections(BitcoinTestFramework):
check_node_connections(node=self.nodes[1], num_in=5, num_out=10)
+ self.log.info("Add 1 feeler connection to node 0")
+ feeler_conn = self.nodes[0].add_outbound_p2p_connection(P2PFeelerReceiver(), p2p_idx=6, connection_type="feeler")
+
+ # Feeler connection is closed
+ assert not feeler_conn.is_connected
+
+ # Verify version message received
+ assert_equal(feeler_conn.message_count["version"], 1)
if __name__ == '__main__':
P2PAddConnections().main()
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index f9e2cfa2f5..d71deb76b6 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -558,7 +558,7 @@ class TestNode():
def add_outbound_p2p_connection(self, p2p_conn, *, p2p_idx, connection_type="outbound-full-relay", **kwargs):
"""Add an outbound p2p connection from node. Must be an
- "outbound-full-relay", "block-relay-only" or "addr-fetch" connection.
+ "outbound-full-relay", "block-relay-only", "addr-fetch" or "feeler" connection.
This method adds the p2p connection to the self.p2ps list and returns
the connection to the caller.
@@ -570,11 +570,16 @@ class TestNode():
p2p_conn.peer_accept_connection(connect_cb=addconnection_callback, connect_id=p2p_idx + 1, net=self.chain, timeout_factor=self.timeout_factor, **kwargs)()
- p2p_conn.wait_for_connect()
- self.p2ps.append(p2p_conn)
+ if connection_type == "feeler":
+ # feeler connections are closed as soon as the node receives a `version` message
+ p2p_conn.wait_until(lambda: p2p_conn.message_count["version"] == 1, check_connected=False)
+ p2p_conn.wait_until(lambda: not p2p_conn.is_connected, check_connected=False)
+ else:
+ p2p_conn.wait_for_connect()
+ self.p2ps.append(p2p_conn)
- p2p_conn.wait_for_verack()
- p2p_conn.sync_with_ping()
+ p2p_conn.wait_for_verack()
+ p2p_conn.sync_with_ping()
return p2p_conn