Repository: bitcoin/bitcoin (language: cpp)

Issue:
ci: failure in p2p_handshake.py
https://github.com/bitcoin/bitcoin/actions/runs/9741796701/job/26881733806#step:7:6601

```bash
  node0 2024-07-01T10:31:12.195996Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: sendheaders (0 bytes) peer=19 
 test  2024-07-01T10:32:32.120000Z TestFramework (ERROR): Assertion failed 
                                   Traceback (most recent call last):
                                     File "/home/runner/work/_temp/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/test_framework.py", line 132, in main
                                       self.run_test()
                                     File "/home/runner/work/_temp/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/p2p_handshake.py", line 93, in run_test
                                       with node.assert_debug_log(["connected to self", "disconnecting"]):
                                     File "/usr/lib/python3.12/contextlib.py", line 144, in __exit__
                                       next(self.gen)
                                     File "/home/runner/work/_temp/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/test_node.py", line 491, in assert_debug_log
                                       self._raise_assertion_error('Expected messages "{}" does not partially match log:\n\n{}\n\n'.format(str(expected_msgs), print_log))
                                     File "/home/runner/work/_temp/ci/scratch/build/bitcoin-x86_64-pc-linux-gnu/test/functional/test_framework/test_node.py", line 188, in _raise_assertion_error
                                       raise AssertionError(self._node_msg(msg))
                                   AssertionError: [node 0] Expected messages "['connected to self', 'disconnecting']" does not partially match log:
                                    - 2024-07-01T10:31:12.118903Z [http] [httpserver.cpp:305] [http_request_cb] [http] Received a POST request for / from 127.0.0.1:58234
                                    - 2024-07-01T10:31:12.119030Z [httpworker.3] [rpc/request.cpp:232] [parse] [rpc] ThreadRPCServer method=addconnection user=__cookie__
                                    - 2024-07-01T10:31:12.119166Z [httpworker.3] [net.cpp:407] [ConnectNode] [net] trying v1 connection 127.0.0.1:11072 lastseen=0.0hrs
                                    - 2024-07-01T10:31:12.119487Z [httpworker.3] [net.cpp:3747] [CNode] [net] Added connection peer=19
                                    - 2024-07-01T10:31:12.119532Z [net] [net.cpp:3747] [CNode] [net] Added connection peer=20
                                    - 2024-07-01T10:31:12.119620Z [net] [net.cpp:1814] [CreateNodeFromAcceptedSocket] [net] connection from 127.0.0.1:36064 accepted
                                    - 2024-07-01T10:31:12.120224Z [httpworker.3] [net.cpp:3791] [PushMessage] [net] sending version (114 bytes) peer=19
                                    - 2024-07-01T10:31:12.120525Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: version (114 bytes) peer=20
                                    - 2024-07-01T10:31:12.120606Z [msghand] [net.cpp:3791] [PushMessage] [net] sending version (114 bytes) peer=20
                                    - 2024-07-01T10:31:12.120711Z [msghand] [net_processing.cpp:1624] [PushNodeVersion] [net] send version message: version 70016, blocks=202, txrelay=1, peer=20
                                    - 2024-07-01T10:31:12.120739Z [msghand] [net.cpp:3791] [PushMessage] [net] sending wtxidrelay (0 bytes) peer=20
                                    - 2024-07-01T10:31:12.120810Z [msghand] [net.cpp:3791] [PushMessage] [net] sending sendaddrv2 (0 bytes) peer=20
                                    - 2024-07-01T10:31:12.121500Z [msghand] [net.cpp:3791] [PushMessage] [net] sending verack (0 bytes) peer=20
                                    - 2024-07-01T10:31:12.121619Z [msghand] [net_processing.cpp:3865] [ProcessMessage] [net] receive version message: /Satoshi:27.99.0(testnode0)/: version 70016, blocks=202, us=[::]:0, txrelay=1, peer=20
                                    - 2024-07-01T10:31:12.121699Z [httpworker.3] [net_processing.cpp:1624] [PushNodeVersion] [net] send version message: version 70016, blocks=202, txrelay=1, peer=19
                                    - 2024-07-01T10:31:12.173332Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: version (114 bytes) peer=19
                                    - 2024-07-01T10:31:12.173389Z [msghand] [net.cpp:3791] [PushMessage] [net] sending wtxidrelay (0 bytes) peer=19
                                    - 2024-07-01T10:31:12.173492Z [msghand] [net.cpp:3791] [PushMessage] [net] sending sendaddrv2 (0 bytes) peer=19
                                    - 2024-07-01T10:31:12.174163Z [msghand] [net.cpp:3791] [PushMessage] [net] sending verack (0 bytes) peer=19
                                    - 2024-07-01T10:31:12.174318Z [msghand] [net.cpp:3791] [PushMessage] [net] sending getaddr (0 bytes) peer=19
                                    - 2024-07-01T10:31:12.174407Z [msghand] [net_processing.cpp:3865] [ProcessMessage] [net] receive version message: /Satoshi:27.99.0(testnode0)/: version 70016, blocks=202, us=[::]:0, txrelay=1, peer=19
                                    - 2024-07-01T10:31:12.174440Z [msghand] [node/timeoffsets.cpp:31] [Add] [net] Added time offset +0s, total samples 8
                                    - 2024-07-01T10:31:12.174635Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: wtxidrelay (0 bytes) peer=19
                                    - 2024-07-01T10:31:12.174736Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: sendaddrv2 (0 bytes) peer=19
                                    - 2024-07-01T10:31:12.174851Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: verack (0 bytes) peer=19
                                    - 2024-07-01T10:31:12.174884Z [msghand] [net_processing.cpp:3910] [ProcessMessage] New outbound-full-relay v1 peer connected: version: 70016, blocks=202, peer=19
                                    - 2024-07-01T10:31:12.174908Z [msghand] [net.cpp:3791] [PushMessage] [net] sending sendcmpct (9 bytes) peer=19
                                    - 2024-07-01T10:31:12.175052Z [msghand] [net.cpp:3791] [PushMessage] [net] sending ping (8 bytes) peer=19
                                    - 2024-07-01T10:31:12.175299Z [msghand] [net.cpp:3791] [PushMessage] [net] sending getheaders (645 bytes) peer=19
                                    - 2024-07-01T10:31:12.175392Z [msghand] [net_processing.cpp:5886] [SendMessages] [net] initial getheaders (201) to peer=19 (startheight:202)
                                    - 2024-07-01T10:31:12.175533Z [msghand] [net.cpp:3791] [PushMessage] [net] sending feefilter (8 bytes) peer=19
                                    - 2024-07-01T10:31:12.181934Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: wtxidrelay (0 bytes) peer=20
                                    - 2024-07-01T10:31:12.182171Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: sendaddrv2 (0 bytes) peer=20
                                    - 2024-07-01T10:31:12.182305Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: verack (0 bytes) peer=20
                                    - 2024-07-01T10:31:12.182339Z [msghand] [net_processing.cpp:3910] [ProcessMessage] New inbound v1 peer connected: version: 70016, blocks=202, peer=20
                                    - 2024-07-01T10:31:12.182363Z [msghand] [net.cpp:3791] [PushMessage] [net] sending sendcmpct (9 bytes) peer=20
                                    - 2024-07-01T10:31:12.182510Z [msghand] [net.cpp:3791] [PushMessage] [net] sending ping (8 bytes) peer=20
                                    - 2024-07-01T10:31:12.182633Z [msghand] [net.cpp:3791] [PushMessage] [net] sending getheaders (645 bytes) peer=20
                                    - 2024-07-01T10:31:12.182731Z [msghand] [net_processing.cpp:5886] [SendMessages] [net] initial getheaders (201) to peer=20 (startheight:202)
                                    - 2024-07-01T10:31:12.182868Z [msghand] [net.cpp:3791] [PushMessage] [net] sending feefilter (8 bytes) peer=20
                                    - 2024-07-01T10:31:12.183073Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: getaddr (0 bytes) peer=20
                                    - 2024-07-01T10:31:12.183266Z [msghand] [addrman.cpp:840] [GetAddr_] [addrman] GetAddr returned 0 random addresses
                                    - 2024-07-01T10:31:12.183804Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: sendcmpct (9 bytes) peer=19
                                    - 2024-07-01T10:31:12.183937Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: ping (8 bytes) peer=19
                                    - 2024-07-01T10:31:12.183965Z [msghand] [net.cpp:3791] [PushMessage] [net] sending pong (8 bytes) peer=19
                                    - 2024-07-01T10:31:12.186653Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: sendcmpct (9 bytes) peer=20
                                    - 2024-07-01T10:31:12.186783Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: ping (8 bytes) peer=20
                                    - 2024-07-01T10:31:12.186810Z [msghand] [net.cpp:3791] [PushMessage] [net] sending pong (8 bytes) peer=20
                                    - 2024-07-01T10:31:12.186931Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: getheaders (645 bytes) peer=19
                                    - 2024-07-01T10:31:12.186975Z [msghand] [net_processing.cpp:4463] [ProcessMessage] [net] getheaders 202 to end from peer=19
                                    - 2024-07-01T10:31:12.187008Z [msghand] [net.cpp:3791] [PushMessage] [net] sending headers (82 bytes) peer=19
                                    - 2024-07-01T10:31:12.187180Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: feefilter (8 bytes) peer=19
                                    - 2024-07-01T10:31:12.187218Z [msghand] [net_processing.cpp:5242] [ProcessMessage] [net] received: feefilter of 0.00001000 BTC/kvB from peer=19
                                    - 2024-07-01T10:31:12.187289Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: getheaders (645 bytes) peer=20
                                    - 2024-07-01T10:31:12.187321Z [msghand] [net_processing.cpp:4463] [ProcessMessage] [net] getheaders 202 to end from peer=20
                                    - 2024-07-01T10:31:12.187355Z [msghand] [net.cpp:3791] [PushMessage] [net] sending headers (82 bytes) peer=20
                                    - 2024-07-01T10:31:12.190584Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: feefilter (8 bytes) peer=20
                                    - 2024-07-01T10:31:12.190632Z [msghand] [net_processing.cpp:5242] [ProcessMessage] [net] received: feefilter of 0.00001000 BTC/kvB from peer=20
                                    - 2024-07-01T10:31:12.190758Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: pong (8 bytes) peer=19
                                    - 2024-07-01T10:31:12.190831Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: pong (8 bytes) peer=20
                                    - 2024-07-01T10:31:12.190965Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: headers (82 bytes) peer=19
                                    - 2024-07-01T10:31:12.191601Z [msghand] [net_processing.cpp:2995] [UpdatePeerStateForReceivedHeaders] [net] Protecting outbound peer=19 from eviction
                                    - 2024-07-01T10:31:12.191651Z [msghand] [net.cpp:3791] [PushMessage] [net] sending sendheaders (0 bytes) peer=19
                                    - 2024-07-01T10:31:12.191862Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: headers (82 bytes) peer=20
                                    - 2024-07-01T10:31:12.192242Z [msghand] [net.cpp:3791] [PushMessage] [net] sending sendheaders (0 bytes) peer=20
                                    - 2024-07-01T10:31:12.195693Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: sendheaders (0 bytes) peer=20
                                    - 2024-07-01T10:31:12.195996Z [msghand] [net_processing.cpp:3664] [ProcessMessage] [net] received: sendheaders (0 bytes) peer=19
 test  2024-07-01T10:32:32.124000Z TestFramework (DEBUG): Closing down network thread 
 test  2024-07-01T10:32:32.174000Z TestFramework (INFO): Stopping nodes 
 test  2024-07-01T10:32:32.174000Z TestFramework.node0 (DEBUG): Stopping node 
```

Related to #30362. cc @theStack 


Discussion / hints:
Seems like it's possible that the VERSION message for a new outbound connection  is sent out, received locally and processed _before_ the corresponding `CNode` instance is added to the `m_nodes` list, so the self-connection can't be detected yet. I can reproduce the failure locally with the following patch:
```diff
diff --git a/src/net.cpp b/src/net.cpp
index 990c58ee3d..64b5995dbe 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2921,6 +2921,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
     pnode->grantOutbound = std::move(grant_outbound);

     m_msgproc->InitializeNode(*pnode, nLocalServices);
+    std::this_thread::sleep_for(std::chrono::seconds{1});
     {
         LOCK(m_nodes_mutex);
         m_nodes.push_back(pnode);
```
One simple solution would be to put the `InitializeNode` call also under the `m_nodes_mutex` lock, like e.g. (the delay is included for demonstration purposes):
```diff
diff --git a/src/net.cpp b/src/net.cpp
index 990c58ee3d..e314675356 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -2920,9 +2920,10 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
         return;
     pnode->grantOutbound = std::move(grant_outbound);

-    m_msgproc->InitializeNode(*pnode, nLocalServices);
     {
         LOCK(m_nodes_mutex);
+        m_msgproc->InitializeNode(*pnode, nLocalServices);
+        std::this_thread::sleep_for(std::chrono::seconds{1});
         m_nodes.push_back(pnode);

         // update connection count by network
```
This works for me, but I'm not sure if this has other unintended side-effects or there is a better solution. Pinging some contributors who have worked deeper in the net/P2P areas for ideas/comments: @mzumsande @sipa @sr-gi @vasild
Noticed as well for #30356 which is _not_ based on https://github.com/bitcoin/bitcoin/pull/30362, but I guess CI runs on a merge commit? https://github.com/bitcoin/bitcoin/actions/runs/9742619062/job/26884283814?pr=30356
Calling `InitializeNode()` after acquiring `m_nodes_mutex` has the potential to cause a deadlock because of acquiring `cs_main` and `m_nodes_mutex` in different order in different parts of the code:

1. Existent code: `PeerManagerImpl::NewPoWValidBlock()` acquires `cs_main` and calls `m_connman.ForEachNode()` which acquires `m_nodes_mutex`.
2. New code: `CConnman::OpenNetworkConnection()` acquires `m_nodex_mutex` and calls `InitializeNode()` which acquires `cs_main`

:bomb: 
Rudimentary idea: insert the entry in `CConnman::m_nodes` just before `PushVersion()`.

```cpp
void PeerManagerImpl::InitializeNode(CNode& node, ServiceFlags our_services)
{
...
    // void CConnman::NodesAppend() { WITH_LOCK(m_nodes_mutex, m_nodes.push_back(node)); }
    m_connman.NodesAppend(node); 
    if (!node.IsInboundConn()) {
        PushNodeVersion(node, *peer);
    }
}
```

or, same idea but implement by splitting the `PushNodeVersion()` bit away from `InitializeNode()`:

```cpp
    // no PushNodeVersion() by InitializeNode()
    m_msgproc->InitializeNode(*pnode, nLocalServices);
    {   
          LOCK(m_nodes_mutex);
          m_nodes.push_back(pnode);
...
    }
    // BeginHandshake() { if (!node.IsInboundConn()) { PushNodeVersion(node, *peer); } }
    m_msgproc->BeginHandshake();
```
Looks to me like this is an actual bug that could happen in the real network when making an automatic outbound connection to yourself (where the `opencon` thread instead of a `httpworker` thread opens the connection, whereas the `net` thread accepts connection in both cases), so it's probably not just a ci/test failure?!

Maybe a workable fix would be to take the `PushNodeVersion` call out of `InitializeNode` and call it separately after having added the node to `m_nodes` (which would mean adding `PushNodeVersion` to `NetEventsInterface`) [Edit: looks like this is similar to vasild's second suggestion which I didn't see before submitting this answer]
since the failures are frequent and it seems that the solution won't be all that trivial, I think it might be best to revert https://github.com/bitcoin/bitcoin/pull/30362 temporarily and re-introduce it together with a fix in `net` - without any pressure to get the CI green quickly.
Thanks for the suggestions @vasild and @mzumsande, moving the `PushNodeVersion` part out of `InitializeNode` and calling it after the `CNode` instance is added to the list sounds like a good idea.

> since the failures are frequent and it seems that the solution won't be all that trivial, I think it might be best to revert #30362 temporarily and re-introduce it together with a fix in `net` - without any pressure to get the CI green quickly.

Agree, opened a revert PR #30374.
In case you settle with adding to `m_nodes` before `PushNodeVersion()` and I do not manage to review, it is good to ensure that no code will be upset by an existence of an (oubound) entry in `m_nodes` that does not have version pushed.

Fix patch:
diff --git a/src/net.h b/src/net.h
index 8075975d6201a..443f6a8de8d23 100644
--- a/src/net.h
+++ b/src/net.h
@@ -991,8 +991,8 @@ class NetEventsInterface
     /** Mutex for anything that is only accessed via the msg processing thread */
     static Mutex g_msgproc_mutex;
 
-    /** Initialize a peer (setup state, queue any initial messages) */
-    virtual void InitializeNode(CNode& node, ServiceFlags our_services) = 0;
+    /** Initialize a peer (setup state) */
+    virtual void InitializeNode(const CNode& node, ServiceFlags our_services) = 0;
 
     /** Handle removal of a peer (clear state) */
     virtual void FinalizeNode(const CNode& node) = 0;
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 8137e17c980d7..728bfc4c18fe6 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -243,6 +243,9 @@ struct Peer {
      * Most peers use headers-first syncing, which doesn't use this mechanism */
     uint256 m_continuation_block GUARDED_BY(m_block_inv_mutex) {};
 
+    /** Set to true once initial VERSION message was sent (only relevant for outbound peers). */
+    bool m_outbound_version_message_sent GUARDED_BY(NetEventsInterface::g_msgproc_mutex){false};
+
     /** This peer's reported block height when we connected */
     std::atomic<int> m_starting_height{-1};
 
@@ -498,7 +501,7 @@ class PeerManagerImpl final : public PeerManager
         EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex);
 
     /** Implement NetEventsInterface */
-    void InitializeNode(CNode& node, ServiceFlags our_services) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
+    void InitializeNode(const CNode& node, ServiceFlags our_services) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
     void FinalizeNode(const CNode& node) override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_headers_presync_mutex);
     bool HasAllDesirableServiceFlags(ServiceFlags services) const override;
     bool ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt) override
@@ -1659,7 +1662,7 @@ void PeerManagerImpl::UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_s
     if (state) state->m_last_block_announcement = time_in_seconds;
 }
 
-void PeerManagerImpl::InitializeNode(CNode& node, ServiceFlags our_services)
+void PeerManagerImpl::InitializeNode(const CNode& node, ServiceFlags our_services)
 {
     NodeId nodeid = node.GetId();
     {
@@ -1677,9 +1680,6 @@ void PeerManagerImpl::InitializeNode(CNode& node, ServiceFlags our_services)
         LOCK(m_peer_mutex);
         m_peer_map.emplace_hint(m_peer_map.end(), nodeid, peer);
     }
-    if (!node.IsInboundConn()) {
-        PushNodeVersion(node, *peer);
-    }
 }
 
 void PeerManagerImpl::ReattemptInitialBroadcast(CScheduler& scheduler)
@@ -5326,6 +5326,10 @@ bool PeerManagerImpl::ProcessMessages(CNode* pfrom, std::atomic<bool>& interrupt
     PeerRef peer = GetPeerRef(pfrom->GetId());
     if (peer == nullptr) return false;
 
+    // For outbound connections, ensure that the initial VERSION message
+    // has been sent first before processing any incoming messages
+    if (!pfrom->IsInboundConn() && !peer->m_outbound_version_message_sent) return false;
+
     {
         LOCK(peer->m_getdata_requests_mutex);
         if (!peer->m_getdata_requests.empty()) {
@@ -5817,6 +5821,12 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
     // disconnect misbehaving peers even before the version handshake is complete.
     if (MaybeDiscourageAndDisconnect(*pto, *peer)) return true;
 
+    // Initiate version handshake for outbound connections
+    if (!pto->IsInboundConn() && !peer->m_outbound_version_message_sent) {
+        PushNodeVersion(*pto, *peer);
+        peer->m_outbound_version_message_sent = true;
+    }
+
     // Don't send anything until the version handshake is complete
     if (!pto->fSuccessfullyConnected || pto->fDisconnect)
         return true;


Test patch:
diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp
index 9b38d85d582d6..e4b2ac574395a 100644
--- a/src/test/util/net.cpp
+++ b/src/test/util/net.cpp
@@ -28,7 +28,8 @@ void ConnmanTestMsg::Handshake(CNode& node,
     auto& connman{*this};
 
     peerman.InitializeNode(node, local_services);
-    FlushSendBuffer(node); // Drop the version message added by InitializeNode.
+    peerman.SendMessages(&node);
+    FlushSendBuffer(node); // Drop the version message added by SendMessages.
 
     CSerializedNetMsg msg_version{
         NetMsg::Make(NetMsgType::VERSION,
diff --git a/test/functional/p2p_handshake.py b/test/functional/p2p_handshake.py
index 21959ae522ebe..9536e748931ad 100755
--- a/test/functional/p2p_handshake.py
+++ b/test/functional/p2p_handshake.py
@@ -17,6 +17,7 @@
     NODE_WITNESS,
 )
 from test_framework.p2p import P2PInterface
+from test_framework.util import p2p_port
 
 
 # Desirable service flags for outbound non-pruned and pruned peers. Note that
@@ -88,9 +89,11 @@ def run_test(self):
         with node.assert_debug_log([f"feeler connection completed"]):
             self.add_outbound_connection(node, "feeler", NODE_NONE, wait_for_disconnect=True)
 
-        # TODO: re-add test introduced in commit 5d2fb14bafe4e80c0a482d99e5ebde07c477f000
-        # ("test: p2p: check that connecting to ourself leads to disconnect") once
-        # the race condition causing issue #30368 is fixed
+        self.log.info("Check that connecting to ourself leads to immediate disconnect")
+        with node.assert_debug_log(["connected to self", "disconnecting"]):
+            node_listen_addr = f"127.0.0.1:{p2p_port(0)}"
+            node.addconnection(node_listen_addr, "outbound-full-relay", self.options.v2transport)
+            self.wait_until(lambda: len(node.getpeerinfo()) == 0)
 
 
 if __name__ == '__main__':