Merge #6329: backport: merge bitcoin#20524, #26553, #27986, #28645, #28632, #28782, #28822, #29006, #29212, merge bitcoin-core/gui#754, partial bitcoin#23443, #26448 (BIP324 backports: part 3)

aa5311d0fc merge bitcoin#29212: Fix -netinfo backward compat with getpeerinfo pre-v26 (Kittywhiskers Van Gogh)
1a293c7cc5 merge bitcoin#29006: fix v2 transport intermittent test failure (Kittywhiskers Van Gogh)
d0804d4bf0 merge bitcoin#28822: Add missing wait for version to be sent in add_outbound_p2p_connection (Kittywhiskers Van Gogh)
c0b3062215 merge bitcoin#28782: Add missing sync on send_version in peer_connect (Kittywhiskers Van Gogh)
35253cdd15 merge bitcoin#28632: make python p2p not send getaddr on incoming connections (Kittywhiskers Van Gogh)
6a4ca62fd1 merge bitcoin#28645: fix `assert_debug_log` call-site bugs, add type checks (Kittywhiskers Van Gogh)
deaee147b7 merge bitcoin-core/gui#754: Add BIP324-specific labels to peer details (Kittywhiskers Van Gogh)
fffe6e716b merge bitcoin#27986: remove race in the user-agent reception check (Kittywhiskers Van Gogh)
1bf135bbc9 merge bitcoin#26553: Fix intermittent failure in rpc_net.py (Kittywhiskers Van Gogh)
5bf245b4a0 partial bitcoin#26448: fix intermittent failure in p2p_sendtxrcncl.py (Kittywhiskers Van Gogh)
b7c0030d3d partial bitcoin#23443: Erlay support signaling (Kittywhiskers Van Gogh)
c709df74cc merge bitcoin#20524: Move MIN_VERSION_SUPPORTED to p2p.py (Kittywhiskers Van Gogh)

Pull request description:

  ## Additional Information

  * Dependent on https://github.com/dashpay/dash/pull/6324

  * Dependency for https://github.com/dashpay/dash/pull/6330

  ## How Has This Been Tested?

  * Changes to Qt client were validated by running the client

    <details>

    <summary>Screenshot</summary>

    ![Transport reporting in Qt](https://github.com/user-attachments/assets/0d551e19-f3a2-4ce7-83d6-5cb3d03b1765)

    </details>

  * Changes to `dash-cli` were validated by running it with different node versions

    **Against a node built on this PR**

    <details>

    <summary>Screenshot</summary>

    ![getinfo with node running the latest build](https://github.com/user-attachments/assets/8cda68cc-727a-4cf3-a4d8-dd6a33331d78)

    </details>

    **Against a node built running the last release**

    <details>

    <summary>Screenshot</summary>

    ![getinfo with node running the latest release](https://github.com/user-attachments/assets/0c6ff476-7cc9-4297-bae5-35d423aba480)

    </details>

  ## Breaking Changes

  None expected.

  ## Checklist:

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas (note: N/A)
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation (note: N/A)
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    ACK aa5311d0fc
  PastaPastaPasta:
    utACK aa5311d0fc

Tree-SHA512: 8cca324ac988a73c0590a4e9b318e81ce951ac55fb173cf507fa647cab01ab4981e6a06d4792376b4bfb44ff09d4811de05fadb9ba793dd00b4c7965b4b22654
This commit is contained in:
pasta 2024-10-22 09:19:20 -05:00
commit dd629cf0eb
No known key found for this signature in database
GPG Key ID: E2F3D7916E722D38
9 changed files with 203 additions and 88 deletions

View File

@ -518,7 +518,7 @@ public:
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 @@ public:
// 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 @@ public:
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 @@ public:
" \"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"

View File

@ -977,17 +977,17 @@
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="peerNetworkLabel">
<widget class="QLabel" name="peerTransportTypeLabel">
<property name="toolTip">
<string>The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS.</string>
<string>The transport layer version: %1</string>
</property>
<property name="text">
<string>Network</string>
<string>Transport</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="peerNetwork">
<widget class="QLabel" name="peerTransportType">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1003,14 +1003,17 @@
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_30">
<widget class="QLabel" name="peerSessionIdLabel">
<property name="toolTip">
<string>The BIP324 session ID string in hex, if any.</string>
</property>
<property name="text">
<string>Permissions</string>
<string>Session ID</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="peerPermissions">
<widget class="QLabel" name="peerSessionId">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1026,17 +1029,17 @@
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="peerConnectionTypeLabel">
<widget class="QLabel" name="peerNetworkLabel">
<property name="toolTip">
<string>The direction and type of peer connection: %1</string>
<string>The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS.</string>
</property>
<property name="text">
<string>Direction/Type</string>
<string>Network</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="peerConnectionType">
<widget class="QLabel" name="peerNetwork">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1052,14 +1055,14 @@
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_21">
<widget class="QLabel" name="label_30">
<property name="text">
<string>Version</string>
<string>Permissions</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="peerVersion">
<widget class="QLabel" name="peerPermissions">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
@ -1075,13 +1078,62 @@
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="peerConnectionTypeLabel">
<property name="toolTip">
<string>The direction and type of peer connection: %1</string>
</property>
<property name="text">
<string>Direction/Type</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="peerConnectionType">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string>N/A</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>Version</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLabel" name="peerVersion">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="text">
<string>N/A</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_28">
<property name="text">
<string>User Agent</string>
</property>
</widget>
</item>
<item row="6" column="2">
<item row="8" column="2">
<widget class="QLabel" name="peerSubversion">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1100,14 +1152,14 @@
</property>
</widget>
</item>
<item row="7" column="0">
<item row="9" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Services</string>
</property>
</widget>
</item>
<item row="7" column="2">
<item row="9" column="2">
<widget class="QLabel" name="peerServices">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1123,7 +1175,7 @@
</property>
</widget>
</item>
<item row="8" column="0">
<item row="10" column="0">
<widget class="QLabel" name="peerRelayTxesLabel">
<property name="toolTip">
<string>Whether the peer requested us to relay transactions.</string>
@ -1133,7 +1185,7 @@
</property>
</widget>
</item>
<item row="8" column="2">
<item row="10" column="2">
<widget class="QLabel" name="peerRelayTxes">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1149,7 +1201,7 @@
</property>
</widget>
</item>
<item row="9" column="0">
<item row="11" column="0">
<widget class="QLabel" name="peerHighBandwidthLabel">
<property name="toolTip">
<string>High bandwidth BIP152 compact block relay: %1</string>
@ -1159,7 +1211,7 @@
</property>
</widget>
</item>
<item row="9" column="2">
<item row="11" column="2">
<widget class="QLabel" name="peerHighBandwidth">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1175,14 +1227,14 @@
</property>
</widget>
</item>
<item row="10" column="0">
<item row="12" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Starting Block</string>
</property>
</widget>
</item>
<item row="10" column="2">
<item row="12" column="2">
<widget class="QLabel" name="peerHeight">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1198,14 +1250,14 @@
</property>
</widget>
</item>
<item row="11" column="0">
<item row="13" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Synced Headers</string>
</property>
</widget>
</item>
<item row="11" column="2">
<item row="13" column="2">
<widget class="QLabel" name="peerSyncHeight">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1221,14 +1273,14 @@
</property>
</widget>
</item>
<item row="12" column="0">
<item row="14" column="0">
<widget class="QLabel" name="label_25">
<property name="text">
<string>Synced Blocks</string>
</property>
</widget>
</item>
<item row="12" column="2">
<item row="14" column="2">
<widget class="QLabel" name="peerCommonHeight">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1244,14 +1296,14 @@
</property>
</widget>
</item>
<item row="13" column="0">
<item row="15" column="0">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Connection Time</string>
</property>
</widget>
</item>
<item row="13" column="2">
<item row="15" column="2">
<widget class="QLabel" name="peerConnTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1267,7 +1319,7 @@
</property>
</widget>
</item>
<item row="14" column="0">
<item row="16" column="0">
<widget class="QLabel" name="peerLastBlockLabel">
<property name="toolTip">
<string>Elapsed time since a novel block passing initial validity checks was received from this peer.</string>
@ -1277,7 +1329,7 @@
</property>
</widget>
</item>
<item row="14" column="2">
<item row="16" column="2">
<widget class="QLabel" name="peerLastBlock">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1293,7 +1345,7 @@
</property>
</widget>
</item>
<item row="15" column="0">
<item row="17" column="0">
<widget class="QLabel" name="peerLastTxLabel">
<property name="toolTip">
<string extracomment="Tooltip text for the Last Transaction field in the peer details area.">Elapsed time since a novel transaction accepted into our mempool was received from this peer.</string>
@ -1303,7 +1355,7 @@
</property>
</widget>
</item>
<item row="15" column="2">
<item row="17" column="2">
<widget class="QLabel" name="peerLastTx">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1319,14 +1371,14 @@
</property>
</widget>
</item>
<item row="16" column="0">
<item row="18" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Last Send</string>
</property>
</widget>
</item>
<item row="16" column="2">
<item row="18" column="2">
<widget class="QLabel" name="peerLastSend">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1342,14 +1394,14 @@
</property>
</widget>
</item>
<item row="17" column="0">
<item row="19" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Last Receive</string>
</property>
</widget>
</item>
<item row="17" column="2">
<item row="19" column="2">
<widget class="QLabel" name="peerLastRecv">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1365,14 +1417,14 @@
</property>
</widget>
</item>
<item row="18" column="0">
<item row="20" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Sent</string>
</property>
</widget>
</item>
<item row="18" column="2">
<item row="20" column="2">
<widget class="QLabel" name="peerBytesSent">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1388,14 +1440,14 @@
</property>
</widget>
</item>
<item row="19" column="0">
<item row="21" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Received</string>
</property>
</widget>
</item>
<item row="19" column="2">
<item row="21" column="2">
<widget class="QLabel" name="peerBytesRecv">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1411,14 +1463,14 @@
</property>
</widget>
</item>
<item row="20" column="0">
<item row="22" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>Ping Time</string>
</property>
</widget>
</item>
<item row="20" column="2">
<item row="22" column="2">
<widget class="QLabel" name="peerPingTime">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1434,7 +1486,7 @@
</property>
</widget>
</item>
<item row="21" column="0">
<item row="23" column="0">
<widget class="QLabel" name="peerPingWaitLabel">
<property name="toolTip">
<string>The duration of a currently outstanding ping.</string>
@ -1444,7 +1496,7 @@
</property>
</widget>
</item>
<item row="21" column="2">
<item row="23" column="2">
<widget class="QLabel" name="peerPingWait">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1460,14 +1512,14 @@
</property>
</widget>
</item>
<item row="22" column="0">
<item row="24" column="0">
<widget class="QLabel" name="peerMinPingLabel">
<property name="text">
<string>Min Ping</string>
</property>
</widget>
</item>
<item row="22" column="2">
<item row="24" column="2">
<widget class="QLabel" name="peerMinPing">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1483,14 +1535,14 @@
</property>
</widget>
</item>
<item row="23" column="0">
<item row="25" column="0">
<widget class="QLabel" name="label_timeoffset">
<property name="text">
<string>Time Offset</string>
</property>
</widget>
</item>
<item row="23" column="2">
<item row="25" column="2">
<widget class="QLabel" name="timeoffset">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1506,7 +1558,7 @@
</property>
</widget>
</item>
<item row="24" column="0">
<item row="26" column="0">
<widget class="QLabel" name="peerMappedASLabel">
<property name="toolTip">
<string>The mapped Autonomous System used for diversifying peer selection.</string>
@ -1516,7 +1568,7 @@
</property>
</widget>
</item>
<item row="24" column="2">
<item row="26" column="2">
<widget class="QLabel" name="peerMappedAS">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1532,7 +1584,7 @@
</property>
</widget>
</item>
<item row="25" column="0">
<item row="27" column="0">
<widget class="QLabel" name="peerAddrRelayEnabledLabel">
<property name="toolTip">
<string extracomment="Tooltip text for the Address Relay field in the peer details area.">Whether we relay addresses to this peer.</string>
@ -1542,7 +1594,7 @@
</property>
</widget>
</item>
<item row="25" column="2">
<item row="27" column="2">
<widget class="QLabel" name="peerAddrRelayEnabled">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1558,7 +1610,7 @@
</property>
</widget>
</item>
<item row="26" column="0">
<item row="28" column="0">
<widget class="QLabel" name="peerAddrProcessedLabel">
<property name="toolTip">
<string extracomment="Tooltip text for the Addresses Processed field in the peer details area.">Total number of addresses processed, excluding those dropped due to rate-limiting.</string>
@ -1568,7 +1620,7 @@
</property>
</widget>
</item>
<item row="26" column="2">
<item row="28" column="2">
<widget class="QLabel" name="peerAddrProcessed">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1584,7 +1636,7 @@
</property>
</widget>
</item>
<item row="27" column="0">
<item row="29" column="0">
<widget class="QLabel" name="peerAddrRateLimitedLabel">
<property name="toolTip">
<string extracomment="Tooltip text for the Addresses Rate-Limited field in the peer details area.">Total number of addresses dropped due to rate-limiting.</string>
@ -1594,7 +1646,7 @@
</property>
</widget>
</item>
<item row="27" column="2">
<item row="29" column="2">
<widget class="QLabel" name="peerAddrRateLimited">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
@ -1610,7 +1662,7 @@
</property>
</widget>
</item>
<item row="28" column="0">
<item row="30" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>

View File

@ -15,6 +15,7 @@
#include <chainparams.h>
#include <interfaces/node.h>
#include <netbase.h>
#include <node/connection_types.h>
#include <qt/bantablemodel.h>
#include <qt/clientmodel.h>
#include <qt/peertablesortproxy.h>
@ -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{"<ul><li>" + Join(CONNECTION_TYPE_DOC, QString("</li><li>")) + "</li></ul>"};
ui->peerConnectionTypeLabel->setToolTip(ui->peerConnectionTypeLabel->toolTip().arg(list));
const QString connection_types_list{"<ul><li>" + Join(CONNECTION_TYPE_DOC, QString("</li><li>")) + "</li></ul>"};
ui->peerConnectionTypeLabel->setToolTip(ui->peerConnectionTypeLabel->toolTip().arg(connection_types_list));
const std::vector<QString> 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{"<ul><li>" + Join(TRANSPORT_TYPE_DOC, QString("</li><li>")) + "</li></ul>"};
ui->peerTransportTypeLabel->setToolTip(ui->peerTransportTypeLabel->toolTip().arg(transport_types_list));
const QString hb_list{"<ul><li>\""
+ ts.to + "\" " + tr("we selected the peer for high bandwidth relay") + "</li><li>\""
+ ts.from + "\" " + tr("the peer selected us for high bandwidth relay") + "</li><li>\""
@ -1286,6 +1296,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);

View File

@ -302,7 +302,7 @@ class DashGovernanceTest (DashTestFramework):
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

View File

@ -257,15 +257,16 @@ class AddrTest(BitcoinTestFramework):
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

View File

@ -133,9 +133,8 @@ class V2TransportTest(BitcoinTestFramework):
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 @@ class V2TransportTest(BitcoinTestFramework):
# 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].assert_debug_log("V2 transport error: V1 peer with wrong MessageStart"):
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"):
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__':

View File

@ -114,7 +114,7 @@ class NetTest(DashTestFramework):
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 @@ class NetTest(DashTestFramework):
"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")

View File

@ -392,8 +392,8 @@ class P2PInterface(P2PConnection):
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)
@ -490,7 +490,8 @@ class P2PInterface(P2PConnection):
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

View File

@ -27,6 +27,7 @@ from .descriptors import descsum_create
from .p2p import P2P_SUBVERSION
from .util import (
MAX_NODES,
assert_equal,
append_config,
delete_cookie_file,
get_auth_cookie,
@ -426,6 +427,9 @@ class TestNode():
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()
@ -486,6 +490,24 @@ class TestNode():
'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):
"""
@ -609,7 +631,7 @@ class TestNode():
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
@ -619,9 +641,12 @@ class TestNode():
if 'dstaddr' not in kwargs:
kwargs['dstaddr'] = '127.0.0.1'
p2p_conn.peer_connect(**kwargs, net=self.chain, timeout_factor=self.timeout_factor)()
p2p_conn.p2p_connected_to_node = True
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()
@ -637,20 +662,33 @@ class TestNode():
# 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 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
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.
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):
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":
@ -661,8 +699,10 @@ class TestNode():
p2p_conn.wait_for_connect()
self.p2ps.append(p2p_conn)
p2p_conn.wait_for_verack()
p2p_conn.sync_with_ping()
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()
return p2p_conn
@ -671,7 +711,8 @@ class TestNode():
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()