From c709df74cc4b9f99c86bb7ac60069a923d2bac52 Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Mon, 14 Oct 2024 21:18:17 +0000
Subject: [PATCH 01/12] merge bitcoin#20524: Move MIN_VERSION_SUPPORTED to
p2p.py
continuation of cbff29a6 (dash#6067)
---
test/functional/test_framework/test_node.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 6aa1bbd844870..df020736b7b9b 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -27,6 +27,7 @@
from .p2p import P2P_SUBVERSION
from .util import (
MAX_NODES,
+ assert_equal,
append_config,
delete_cookie_file,
get_auth_cookie,
@@ -637,6 +638,11 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
# in comparison to the upside of making tests less fragile and unexpected intermittent errors less likely.
p2p_conn.sync_with_ping()
+ # Consistency check that the Dash Core has received our user agent string. This checks the
+ # node's newest peer. It could be racy if another Dash Core node has connected since we opened
+ # our connection, but we don't expect that to happen.
+ assert_equal(self.getpeerinfo()[-1]['subver'], p2p_conn.strSubVer)
+
return p2p_conn
def add_outbound_p2p_connection(self, p2p_conn, *, p2p_idx, connection_type="outbound-full-relay", **kwargs):
From b7c0030d3d8d070c4346aa6aaa3daa73578d8675 Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Mon, 19 Sep 2022 17:11:32 +0300
Subject: [PATCH 02/12] partial bitcoin#23443: Erlay support signaling
contains:
- e56d1d2a (changes to `test_node.py`)
---
test/functional/test_framework/test_node.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index df020736b7b9b..3d1140e1d9839 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -645,7 +645,7 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
return p2p_conn
- def add_outbound_p2p_connection(self, p2p_conn, *, p2p_idx, connection_type="outbound-full-relay", **kwargs):
+ def add_outbound_p2p_connection(self, p2p_conn, *, wait_for_verack=True, p2p_idx, connection_type="outbound-full-relay", **kwargs):
"""Add an outbound p2p connection from node. Must be an
"outbound-full-relay", "block-relay-only", "addr-fetch" or "feeler" connection.
@@ -667,8 +667,9 @@ def addconnection_callback(address, port):
p2p_conn.wait_for_connect()
self.p2ps.append(p2p_conn)
- p2p_conn.wait_for_verack()
- p2p_conn.sync_with_ping()
+ if wait_for_verack:
+ p2p_conn.wait_for_verack()
+ p2p_conn.sync_with_ping()
return p2p_conn
From 5bf245b4a0d2400f89ade6e15c7c562201e30c36 Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Mon, 14 Oct 2024 18:30:40 +0000
Subject: [PATCH 03/12] partial bitcoin#26448: fix intermittent failure in
p2p_sendtxrcncl.py
contains:
- 74d97531 (changes to `test_node.py`)
---
test/functional/test_framework/test_node.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 3d1140e1d9839..12f05b6ec4ddf 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -651,6 +651,10 @@ def add_outbound_p2p_connection(self, p2p_conn, *, wait_for_verack=True, p2p_idx
This method adds the p2p connection to the self.p2ps list and returns
the connection to the caller.
+
+ p2p_idx must be different for simultaneously connected peers. When reusing it for the next peer
+ after disconnecting the previous one, it is necessary to wait for the disconnect to finish to avoid
+ a race condition.
"""
def addconnection_callback(address, port):
From 1bf135bbc91d24d5f3cf947148caa37980d6c9e5 Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Tue, 15 Oct 2024 07:11:47 +0000
Subject: [PATCH 04/12] merge bitcoin#26553: Fix intermittent failure in
rpc_net.py
---
test/functional/rpc_net.py | 5 +++--
test/functional/test_framework/test_node.py | 3 ++-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py
index e8d26077639e6..d7d7d5d0c4811 100755
--- a/test/functional/rpc_net.py
+++ b/test/functional/rpc_net.py
@@ -114,7 +114,7 @@ def test_getpeerinfo(self):
no_version_peer_id = 3
no_version_peer_conntime = self.mocktime
with self.nodes[0].assert_debug_log([f"Added connection peer={no_version_peer_id}"]):
- self.nodes[0].add_p2p_connection(P2PInterface(), send_version=False, wait_for_verack=False)
+ no_version_peer = self.nodes[0].add_p2p_connection(P2PInterface(), send_version=False, wait_for_verack=False)
peer_info = self.nodes[0].getpeerinfo()[no_version_peer_id]
peer_info.pop("addr")
peer_info.pop("addrbind")
@@ -155,7 +155,8 @@ def test_getpeerinfo(self):
"version": 0,
},
)
- self.nodes[0].disconnect_p2ps()
+ no_version_peer.peer_disconnect()
+ self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 3)
def test_getnettotals(self):
self.log.info("Test getnettotals")
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 12f05b6ec4ddf..fb59e6c2069b7 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -682,7 +682,8 @@ def num_test_p2p_connections(self):
return len([peer for peer in self.getpeerinfo() if P2P_SUBVERSION % "" in peer['subver']])
def disconnect_p2ps(self):
- """Close all p2p connections to the node."""
+ """Close all p2p connections to the node.
+ Use only after each p2p has sent a version message to ensure the wait works."""
for p in self.p2ps:
p.peer_disconnect()
From fffe6e716b509e87d5dd30b27cfd2df8ecd5a0e7 Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Wed, 28 Jun 2023 10:15:41 +0200
Subject: [PATCH 05/12] merge bitcoin#27986: remove race in the user-agent
reception check
---
test/functional/test_framework/test_node.py | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index fb59e6c2069b7..3da025570f269 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -638,10 +638,13 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
# in comparison to the upside of making tests less fragile and unexpected intermittent errors less likely.
p2p_conn.sync_with_ping()
- # Consistency check that the Dash Core has received our user agent string. This checks the
- # node's newest peer. It could be racy if another Dash Core node has connected since we opened
- # our connection, but we don't expect that to happen.
- assert_equal(self.getpeerinfo()[-1]['subver'], p2p_conn.strSubVer)
+ # Consistency check that the node received our user agent string.
+ # Find our connection in getpeerinfo by our address:port, as it is unique.
+ sockname = p2p_conn._transport.get_extra_info("socket").getsockname()
+ our_addr_and_port = f"{sockname[0]}:{sockname[1]}"
+ info = [peer for peer in self.getpeerinfo() if peer["addr"] == our_addr_and_port]
+ assert_equal(len(info), 1)
+ assert_equal(info[0]["subver"], p2p_conn.strSubVer)
return p2p_conn
From deaee147b7ef4a28a304ee16b92e3ca0712226bc Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Tue, 15 Oct 2024 11:19:07 +0000
Subject: [PATCH 06/12] merge bitcoin-core/gui#754: Add BIP324-specific labels
to peer details
---
src/qt/forms/debugwindow.ui | 156 ++++++++++++++++++++++++------------
src/qt/rpcconsole.cpp | 23 +++++-
2 files changed, 125 insertions(+), 54 deletions(-)
diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui
index d6ea9fd3eb0af..c45f6bcaeb474 100644
--- a/src/qt/forms/debugwindow.ui
+++ b/src/qt/forms/debugwindow.ui
@@ -977,6 +977,58 @@
-
+
+
+ The transport layer version: %1
+
+
+ Transport
+
+
+
+ -
+
+
+ IBeamCursor
+
+
+ N/A
+
+
+ Qt::PlainText
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+
+
+
+ -
+
+
+ The BIP324 session ID string in hex, if any.
+
+
+ Session ID
+
+
+
+ -
+
+
+ IBeamCursor
+
+
+ N/A
+
+
+ Qt::PlainText
+
+
+ Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse
+
+
+
+ -
The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS.
@@ -986,7 +1038,7 @@
- -
+
-
IBeamCursor
@@ -1002,14 +1054,14 @@
- -
+
-
Permissions
- -
+
-
IBeamCursor
@@ -1025,7 +1077,7 @@
- -
+
-
The direction and type of peer connection: %1
@@ -1035,7 +1087,7 @@
- -
+
-
IBeamCursor
@@ -1051,14 +1103,14 @@
- -
+
-
Version
- -
+
-
IBeamCursor
@@ -1074,14 +1126,14 @@
- -
+
-
User Agent
- -
+
-
IBeamCursor
@@ -1100,14 +1152,14 @@
- -
+
-
Services
- -
+
-
IBeamCursor
@@ -1123,7 +1175,7 @@
- -
+
-
Whether the peer requested us to relay transactions.
@@ -1133,7 +1185,7 @@
- -
+
-
IBeamCursor
@@ -1149,7 +1201,7 @@
- -
+
-
High bandwidth BIP152 compact block relay: %1
@@ -1159,7 +1211,7 @@
- -
+
-
IBeamCursor
@@ -1175,14 +1227,14 @@
- -
+
-
Starting Block
- -
+
-
IBeamCursor
@@ -1198,14 +1250,14 @@
- -
+
-
Synced Headers
- -
+
-
IBeamCursor
@@ -1221,14 +1273,14 @@
- -
+
-
Synced Blocks
- -
+
-
IBeamCursor
@@ -1244,14 +1296,14 @@
- -
+
-
Connection Time
- -
+
-
IBeamCursor
@@ -1267,7 +1319,7 @@
- -
+
-
Elapsed time since a novel block passing initial validity checks was received from this peer.
@@ -1277,7 +1329,7 @@
- -
+
-
IBeamCursor
@@ -1293,7 +1345,7 @@
- -
+
-
Elapsed time since a novel transaction accepted into our mempool was received from this peer.
@@ -1303,7 +1355,7 @@
- -
+
-
IBeamCursor
@@ -1319,14 +1371,14 @@
- -
+
-
Last Send
- -
+
-
IBeamCursor
@@ -1342,14 +1394,14 @@
- -
+
-
Last Receive
- -
+
-
IBeamCursor
@@ -1365,14 +1417,14 @@
- -
+
-
Sent
- -
+
-
IBeamCursor
@@ -1388,14 +1440,14 @@
- -
+
-
Received
- -
+
-
IBeamCursor
@@ -1411,14 +1463,14 @@
- -
+
-
Ping Time
- -
+
-
IBeamCursor
@@ -1434,7 +1486,7 @@
- -
+
-
The duration of a currently outstanding ping.
@@ -1444,7 +1496,7 @@
- -
+
-
IBeamCursor
@@ -1460,14 +1512,14 @@
- -
+
-
Min Ping
- -
+
-
IBeamCursor
@@ -1483,14 +1535,14 @@
- -
+
-
Time Offset
- -
+
-
IBeamCursor
@@ -1506,7 +1558,7 @@
- -
+
-
The mapped Autonomous System used for diversifying peer selection.
@@ -1516,7 +1568,7 @@
- -
+
-
IBeamCursor
@@ -1532,7 +1584,7 @@
- -
+
-
Whether we relay addresses to this peer.
@@ -1542,7 +1594,7 @@
- -
+
-
IBeamCursor
@@ -1558,7 +1610,7 @@
- -
+
-
Total number of addresses processed, excluding those dropped due to rate-limiting.
@@ -1568,7 +1620,7 @@
- -
+
-
IBeamCursor
@@ -1584,7 +1636,7 @@
- -
+
-
Total number of addresses dropped due to rate-limiting.
@@ -1594,7 +1646,7 @@
- -
+
-
IBeamCursor
@@ -1610,7 +1662,7 @@
- -
+
-
Qt::Vertical
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index b76b05bced0f5..e5c6c20466e8b 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -533,8 +534,17 @@ RPCConsole::RPCConsole(interfaces::Node& node, QWidget* parent, Qt::WindowFlags
/*: Explanatory text for a short-lived outbound peer connection that is used
to request addresses from a peer. */
tr("Outbound Address Fetch: short-lived, for soliciting addresses")};
- const QString list{"
- " + Join(CONNECTION_TYPE_DOC, QString("
- ")) + "
"};
- ui->peerConnectionTypeLabel->setToolTip(ui->peerConnectionTypeLabel->toolTip().arg(list));
+ const QString connection_types_list{"- " + Join(CONNECTION_TYPE_DOC, QString("
- ")) + "
"};
+ ui->peerConnectionTypeLabel->setToolTip(ui->peerConnectionTypeLabel->toolTip().arg(connection_types_list));
+ const std::vector TRANSPORT_TYPE_DOC{
+ //: Explanatory text for "detecting" transport type.
+ tr("detecting: peer could be v1 or v2"),
+ //: Explanatory text for v1 transport type.
+ tr("v1: unencrypted, plaintext transport protocol"),
+ //: Explanatory text for v2 transport type.
+ tr("v2: BIP324 encrypted transport protocol")};
+ const QString transport_types_list{"- " + Join(TRANSPORT_TYPE_DOC, QString("
- ")) + "
"};
+ ui->peerTransportTypeLabel->setToolTip(ui->peerTransportTypeLabel->toolTip().arg(transport_types_list));
const QString hb_list{"- \""
+ ts.to + "\" – " + tr("we selected the peer for high bandwidth relay") + "
- \""
+ ts.from + "\" – " + tr("the peer selected us for high bandwidth relay") + "
- \""
@@ -1272,6 +1282,15 @@ void RPCConsole::updateDetailWidget()
ui->peerVersion->setText(QString::number(stats->nodeStats.nVersion));
ui->peerSubversion->setText(QString::fromStdString(stats->nodeStats.cleanSubVer));
ui->peerConnectionType->setText(GUIUtil::ConnectionTypeToQString(stats->nodeStats.m_conn_type, /* prepend_direction */ true));
+ ui->peerTransportType->setText(QString::fromStdString(TransportTypeAsString(stats->nodeStats.m_transport_type)));
+ if (stats->nodeStats.m_transport_type == TransportProtocolType::V2) {
+ ui->peerSessionIdLabel->setVisible(true);
+ ui->peerSessionId->setVisible(true);
+ ui->peerSessionId->setText(QString::fromStdString(stats->nodeStats.m_session_id));
+ } else {
+ ui->peerSessionIdLabel->setVisible(false);
+ ui->peerSessionId->setVisible(false);
+ }
ui->peerNetwork->setText(GUIUtil::NetworkToQString(stats->nodeStats.m_network));
if (stats->nodeStats.m_permission_flags == NetPermissionFlags::None) {
ui->peerPermissions->setText(ts.na);
From 6a4ca62fd135190ecf8126ac15269f3ad6ce07cd Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Tue, 15 Oct 2024 09:43:55 +0000
Subject: [PATCH 07/12] merge bitcoin#28645: fix `assert_debug_log` call-site
bugs, add type checks
---
test/functional/feature_governance.py | 2 +-
test/functional/p2p_v2_transport.py | 4 ++--
test/functional/test_framework/test_node.py | 3 +++
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/test/functional/feature_governance.py b/test/functional/feature_governance.py
index 4e499ffa31ace..43c49784d2252 100755
--- a/test/functional/feature_governance.py
+++ b/test/functional/feature_governance.py
@@ -302,7 +302,7 @@ def sync_gov(node):
self.log.info("Move a few block past the recent superblock height and make sure we have no new votes")
for _ in range(5):
- with self.nodes[1].assert_debug_log("", [f"Voting NO-FUNDING for trigger:{winning_trigger_hash} success"]):
+ with self.nodes[1].assert_debug_log(expected_msgs=[""], unexpected_msgs=[f"Voting NO-FUNDING for trigger:{winning_trigger_hash} success"]):
self.bump_mocktime(1)
self.generate(self.nodes[0], 1, sync_fun=self.sync_blocks())
# Votes on both triggers should NOT change
diff --git a/test/functional/p2p_v2_transport.py b/test/functional/p2p_v2_transport.py
index a7f208c858e2c..a99d368c7096a 100755
--- a/test/functional/p2p_v2_transport.py
+++ b/test/functional/p2p_v2_transport.py
@@ -145,7 +145,7 @@ def run_test(self):
wrong_network_magic_prefix = MAGIC_BYTES["mainnet"] + V1_PREFIX[4:]
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect(("127.0.0.1", p2p_port(0)))
- with self.nodes[0].assert_debug_log("V2 transport error: V1 peer with wrong MessageStart"):
+ with self.nodes[0].assert_debug_log(["V2 transport error: V1 peer with wrong MessageStart"]):
s.sendall(wrong_network_magic_prefix + b"somepayload")
# Check detection of missing garbage terminator (hits after fixed amount of data if terminator never matches garbage)
@@ -156,7 +156,7 @@ def run_test(self):
self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == num_peers + 1)
s.sendall(b'\x00' * (MAX_KEY_GARB_AND_GARBTERM_LEN - 1))
self.wait_until(lambda: self.nodes[0].getpeerinfo()[-1]["bytesrecv"] == MAX_KEY_GARB_AND_GARBTERM_LEN - 1)
- with self.nodes[0].assert_debug_log("V2 transport error: missing garbage terminator"):
+ with self.nodes[0].assert_debug_log(["V2 transport error: missing garbage terminator"]):
s.sendall(b'\x00') # send out last byte
# should disconnect immediately
self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == num_peers)
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 3da025570f269..91671e1f1f102 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -427,6 +427,9 @@ def debug_log_bytes(self) -> int:
def assert_debug_log(self, expected_msgs, unexpected_msgs=None, timeout=2):
if unexpected_msgs is None:
unexpected_msgs = []
+ assert_equal(type(expected_msgs), list)
+ assert_equal(type(unexpected_msgs), list)
+
time_end = time.time() + timeout * self.timeout_factor
prev_size = self.debug_log_bytes()
From 35253cdd15c3b9b0e7d3e327c5b4c0474d4f2290 Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Tue, 10 Oct 2023 12:11:00 -0400
Subject: [PATCH 08/12] merge bitcoin#28632: make python p2p not send getaddr
on incoming connections
---
test/functional/p2p_addr_relay.py | 5 +++--
test/functional/test_framework/p2p.py | 3 ++-
test/functional/test_framework/test_node.py | 2 ++
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py
index cbc15dcbf538b..e89734fcfeb24 100755
--- a/test/functional/p2p_addr_relay.py
+++ b/test/functional/p2p_addr_relay.py
@@ -257,15 +257,16 @@ def getaddr_tests(self):
full_outbound_peer.sync_with_ping()
assert full_outbound_peer.getaddr_received()
- self.log.info('Check that we do not send a getaddr message upon connecting to a block-relay-only peer')
+ self.log.info('Check that we do not send a getaddr message to a block-relay-only or inbound peer')
block_relay_peer = self.nodes[0].add_outbound_p2p_connection(AddrReceiver(), p2p_idx=1, connection_type="block-relay-only")
block_relay_peer.sync_with_ping()
assert_equal(block_relay_peer.getaddr_received(), False)
- self.log.info('Check that we answer getaddr messages only from inbound peers')
inbound_peer = self.nodes[0].add_p2p_connection(AddrReceiver(send_getaddr=False))
inbound_peer.sync_with_ping()
+ assert_equal(inbound_peer.getaddr_received(), False)
+ self.log.info('Check that we answer getaddr messages only from inbound peers')
# Add some addresses to addrman
for i in range(1000):
first_octet = i >> 8
diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py
index 43c27a4702c89..3bdccbd89cc0d 100755
--- a/test/functional/test_framework/p2p.py
+++ b/test/functional/test_framework/p2p.py
@@ -490,7 +490,8 @@ def on_version(self, message):
self.send_message(msg_sendaddrv2())
self.send_message(msg_verack())
self.nServices = message.nServices
- self.send_message(msg_getaddr())
+ if self.p2p_connected_to_node:
+ self.send_message(msg_getaddr())
# Connection helper methods
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 91671e1f1f102..fd8df3eec5abd 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -623,6 +623,7 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
if 'dstaddr' not in kwargs:
kwargs['dstaddr'] = '127.0.0.1'
+ p2p_conn.p2p_connected_to_node = True
p2p_conn.peer_connect(**kwargs, net=self.chain, timeout_factor=self.timeout_factor)()
self.p2ps.append(p2p_conn)
p2p_conn.wait_until(lambda: p2p_conn.is_connected, check_connected=False)
@@ -667,6 +668,7 @@ def addconnection_callback(address, port):
self.log.debug("Connecting to %s:%d %s" % (address, port, connection_type))
self.addconnection('%s:%d' % (address, port), connection_type)
+ p2p_conn.p2p_connected_to_node = False
p2p_conn.peer_accept_connection(connect_cb=addconnection_callback, connect_id=p2p_idx + 1, net=self.chain, timeout_factor=self.timeout_factor, **kwargs)()
if connection_type == "feeler":
From c0b3062215f66cdf5f26daf8af268583be9bf735 Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Mon, 14 Oct 2024 20:53:38 +0000
Subject: [PATCH 09/12] merge bitcoin#28782: Add missing sync on send_version
in peer_connect
---
test/functional/test_framework/p2p.py | 4 ++--
test/functional/test_framework/test_node.py | 6 ++++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/test/functional/test_framework/p2p.py b/test/functional/test_framework/p2p.py
index 3bdccbd89cc0d..2be688ee69487 100755
--- a/test/functional/test_framework/p2p.py
+++ b/test/functional/test_framework/p2p.py
@@ -392,8 +392,8 @@ def peer_connect_send_version(self, services):
vt.strSubVer = self.strSubVer
self.on_connection_send_msg = vt # Will be sent soon after connection_made
- def peer_connect(self, *args, services=P2P_SERVICES, send_version=True, **kwargs):
- create_conn = super().peer_connect(*args, **kwargs)
+ def peer_connect(self, *, services=P2P_SERVICES, send_version, **kwargs):
+ create_conn = super().peer_connect(**kwargs)
if send_version:
self.peer_connect_send_version(services)
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index fd8df3eec5abd..8c1a5b171722e 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -613,7 +613,7 @@ def assert_start_raises_init_error(self, extra_args=None, expected_msg=None, mat
assert_msg += "with expected error " + expected_msg
self._raise_assertion_error(assert_msg)
- def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
+ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, send_version=True, **kwargs):
"""Add an inbound p2p connection to the node.
This method adds the p2p connection to the self.p2ps list and also
@@ -624,9 +624,11 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
kwargs['dstaddr'] = '127.0.0.1'
p2p_conn.p2p_connected_to_node = True
- p2p_conn.peer_connect(**kwargs, net=self.chain, timeout_factor=self.timeout_factor)()
+ p2p_conn.peer_connect(**kwargs, send_version=send_version, net=self.chain, timeout_factor=self.timeout_factor)()
self.p2ps.append(p2p_conn)
p2p_conn.wait_until(lambda: p2p_conn.is_connected, check_connected=False)
+ if send_version:
+ p2p_conn.wait_until(lambda: not p2p_conn.on_connection_send_msg)
if wait_for_verack:
# Wait for the node to send us the version and verack
p2p_conn.wait_for_verack()
From d0804d4bf08a4764905dd0f52e0448defbddaf91 Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Mon, 14 Oct 2024 21:26:07 +0000
Subject: [PATCH 10/12] merge bitcoin#28822: Add missing wait for version to be
sent in add_outbound_p2p_connection
---
test/functional/test_framework/test_node.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 8c1a5b171722e..ded022473e444 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -681,6 +681,7 @@ def addconnection_callback(address, port):
p2p_conn.wait_for_connect()
self.p2ps.append(p2p_conn)
+ p2p_conn.wait_until(lambda: not p2p_conn.on_connection_send_msg)
if wait_for_verack:
p2p_conn.wait_for_verack()
p2p_conn.sync_with_ping()
From 1a293c7cc57fb6555806b12e5c5ffda43a214fe2 Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Tue, 15 Oct 2024 10:36:47 +0000
Subject: [PATCH 11/12] merge bitcoin#29006: fix v2 transport intermittent test
failure
---
test/functional/p2p_v2_transport.py | 16 ++++++++--------
test/functional/test_framework/test_node.py | 18 ++++++++++++++++++
2 files changed, 26 insertions(+), 8 deletions(-)
diff --git a/test/functional/p2p_v2_transport.py b/test/functional/p2p_v2_transport.py
index a99d368c7096a..4c566df1a9000 100755
--- a/test/functional/p2p_v2_transport.py
+++ b/test/functional/p2p_v2_transport.py
@@ -133,9 +133,8 @@ def run_test(self):
V1_PREFIX = MAGIC_BYTES[self.chain] + b"version\x00\x00\x00\x00\x00"
assert_equal(len(V1_PREFIX), 16)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
- num_peers = len(self.nodes[0].getpeerinfo())
- s.connect(("127.0.0.1", p2p_port(0)))
- self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == num_peers + 1)
+ with self.nodes[0].wait_for_new_peer():
+ s.connect(("127.0.0.1", p2p_port(0)))
s.sendall(V1_PREFIX[:-1])
assert_equal(self.nodes[0].getpeerinfo()[-1]["transport_protocol_type"], "detecting")
s.sendall(bytes([V1_PREFIX[-1]])) # send out last prefix byte
@@ -144,22 +143,23 @@ def run_test(self):
# Check wrong network prefix detection (hits if the next 12 bytes correspond to a v1 version message)
wrong_network_magic_prefix = MAGIC_BYTES["mainnet"] + V1_PREFIX[4:]
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
- s.connect(("127.0.0.1", p2p_port(0)))
+ with self.nodes[0].wait_for_new_peer():
+ s.connect(("127.0.0.1", p2p_port(0)))
with self.nodes[0].assert_debug_log(["V2 transport error: V1 peer with wrong MessageStart"]):
s.sendall(wrong_network_magic_prefix + b"somepayload")
# Check detection of missing garbage terminator (hits after fixed amount of data if terminator never matches garbage)
MAX_KEY_GARB_AND_GARBTERM_LEN = 64 + 4095 + 16
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
- num_peers = len(self.nodes[0].getpeerinfo())
- s.connect(("127.0.0.1", p2p_port(0)))
- self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == num_peers + 1)
+ with self.nodes[0].wait_for_new_peer():
+ s.connect(("127.0.0.1", p2p_port(0)))
s.sendall(b'\x00' * (MAX_KEY_GARB_AND_GARBTERM_LEN - 1))
self.wait_until(lambda: self.nodes[0].getpeerinfo()[-1]["bytesrecv"] == MAX_KEY_GARB_AND_GARBTERM_LEN - 1)
with self.nodes[0].assert_debug_log(["V2 transport error: missing garbage terminator"]):
+ peer_id = self.nodes[0].getpeerinfo()[-1]["id"]
s.sendall(b'\x00') # send out last byte
# should disconnect immediately
- self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == num_peers)
+ self.wait_until(lambda: not peer_id in [p["id"] for p in self.nodes[0].getpeerinfo()])
if __name__ == '__main__':
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index ded022473e444..7080149b5d7a9 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -490,6 +490,24 @@ def wait_for_debug_log(self, expected_msgs, timeout=60):
'Expected messages "{}" does not partially match log:\n\n{}\n\n'.format(
str(expected_msgs), print_log))
+ @contextlib.contextmanager
+ def wait_for_new_peer(self, timeout=5):
+ """
+ Wait until the node is connected to at least one new peer. We detect this
+ by watching for an increased highest peer id, using the `getpeerinfo` RPC call.
+ Note that the simpler approach of only accounting for the number of peers
+ suffers from race conditions, as disconnects from unrelated previous peers
+ could happen anytime in-between.
+ """
+ def get_highest_peer_id():
+ peer_info = self.getpeerinfo()
+ return peer_info[-1]["id"] if peer_info else -1
+
+ initial_peer_id = get_highest_peer_id()
+ yield
+ wait_until_helper(lambda: get_highest_peer_id() > initial_peer_id,
+ timeout=timeout, timeout_factor=self.timeout_factor)
+
@contextlib.contextmanager
def profile_with_perf(self, profile_name: str):
"""
From aa5311d0fc0868e9d3dcb386a13d24f79cdfa29f Mon Sep 17 00:00:00 2001
From: Kittywhiskers Van Gogh <63189531+kwvg@users.noreply.github.com>
Date: Wed, 16 Oct 2024 10:32:29 +0000
Subject: [PATCH 12/12] merge bitcoin#29212: Fix -netinfo backward compat with
getpeerinfo pre-v26
---
src/bitcoin-cli.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 11f1a144f5a1d..cd691e151ca4a 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -518,7 +518,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
const std::string addr{peer["addr"].get_str()};
const std::string age{conn_time == 0 ? "" : ToString((m_time_now - conn_time) / 60)};
const std::string sub_version{peer["subver"].get_str()};
- const std::string transport{peer["transport_protocol_type"].get_str()};
+ const std::string transport{peer["transport_protocol_type"].isNull() ? "v1" : peer["transport_protocol_type"].get_str()};
const bool is_addr_relay_enabled{peer["addr_relay_enabled"].isNull() ? false : peer["addr_relay_enabled"].get_bool()};
const bool is_bip152_hb_from{peer["bip152_hb_from"].get_bool()};
const bool is_bip152_hb_to{peer["bip152_hb_to"].get_bool()};
@@ -538,7 +538,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
// Report detailed peer connections list sorted by direction and minimum ping time.
if (DetailsRequested() && !m_peers.empty()) {
std::sort(m_peers.begin(), m_peers.end());
- result += strprintf("<-> type net tp mping ping send recv txn blk hb %*s%*s%*s ",
+ result += strprintf("<-> type net v mping ping send recv txn blk hb %*s%*s%*s ",
m_max_addr_processed_length, "addrp",
m_max_addr_rate_limited_length, "addrl",
m_max_age_length, "age");
@@ -551,7 +551,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
peer.is_outbound ? "out" : "in",
ConnectionTypeForNetinfo(peer.conn_type),
peer.network,
- peer.transport_protocol_type == "detecting" ? "*" : peer.transport_protocol_type,
+ peer.transport_protocol_type.rfind('v', 0) == 0 ? peer.transport_protocol_type[1] : ' ',
PingTimeToString(peer.min_ping),
PingTimeToString(peer.ping),
peer.last_send ? ToString(m_time_now - peer.last_send) : "",
@@ -660,7 +660,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
" \"feeler\" - short-lived connection for testing addresses\n"
" \"addr\" - address fetch; short-lived connection for requesting addresses\n"
" net Network the peer connected through (\"ipv4\", \"ipv6\", \"onion\", \"i2p\", \"cjdns\", or \"npr\" (not publicly routable))\n"
- " tp Transport protocol used for the connection (\"v1\", \"v2\" or \"*\" if detecting)\n"
+ " v Version of transport protocol used for the connection\n"
" mping Minimum observed ping time, in milliseconds (ms)\n"
" ping Last observed ping time, in milliseconds (ms)\n"
" send Time since last message sent to the peer, in seconds\n"