Skip to content

Commit 62d21ee

Browse files
sipadhruv
andcommitted
net: use V2Transport when NODE_P2P_V2 service flag is present
Co-authored-by: Dhruv Mehta <856960+dhruv@users.noreply.github.com>
1 parent a4706bc commit 62d21ee

File tree

5 files changed

+63
-13
lines changed

5 files changed

+63
-13
lines changed

src/net.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ static CAddress GetBindAddress(const Sock& sock)
439439
return addr_bind;
440440
}
441441

442-
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
442+
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type, bool use_v2transport)
443443
{
444444
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
445445
assert(conn_type != ConnectionType::INBOUND);
@@ -457,7 +457,8 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
457457
}
458458
}
459459

460-
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "trying connection %s lastseen=%.1fhrs\n",
460+
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "trying %s connection %s lastseen=%.1fhrs\n",
461+
use_v2transport ? "v2" : "v1",
461462
pszDest ? pszDest : addrConnect.ToStringAddrPort(),
462463
Ticks<HoursDouble>(pszDest ? 0h : Now<NodeSeconds>() - addrConnect.nTime));
463464

@@ -580,6 +581,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
580581
CNodeOptions{
581582
.i2p_sam_session = std::move(i2p_transient_session),
582583
.recv_flood_size = nReceiveFloodSize,
584+
.use_v2transport = use_v2transport,
583585
});
584586
pnode->AddRef();
585587

@@ -1794,6 +1796,10 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
17941796
}
17951797

17961798
const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
1799+
// The V2Transport transparently falls back to V1 behavior when an incoming V1 connection is
1800+
// detected, so use it whenever we signal NODE_P2P_V2.
1801+
const bool use_v2transport(nodeServices & NODE_P2P_V2);
1802+
17971803
CNode* pnode = new CNode(id,
17981804
std::move(sock),
17991805
addr,
@@ -1807,6 +1813,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
18071813
.permission_flags = permission_flags,
18081814
.prefer_evict = discouraged,
18091815
.recv_flood_size = nReceiveFloodSize,
1816+
.use_v2transport = use_v2transport,
18101817
});
18111818
pnode->AddRef();
18121819
m_msgproc->InitializeNode(*pnode, nodeServices);
@@ -1855,7 +1862,7 @@ bool CConnman::AddConnection(const std::string& address, ConnectionType conn_typ
18551862
CSemaphoreGrant grant(*semOutbound, true);
18561863
if (!grant) return false;
18571864

1858-
OpenNetworkConnection(CAddress(), false, &grant, address.c_str(), conn_type);
1865+
OpenNetworkConnection(CAddress(), false, &grant, address.c_str(), conn_type, /*use_v2transport=*/false);
18591866
return true;
18601867
}
18611868

@@ -2289,7 +2296,7 @@ void CConnman::ProcessAddrFetch()
22892296
CAddress addr;
22902297
CSemaphoreGrant grant(*semOutbound, true);
22912298
if (grant) {
2292-
OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH);
2299+
OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH, /*use_v2transport=*/false);
22932300
}
22942301
}
22952302

@@ -2391,7 +2398,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
23912398
for (const std::string& strAddr : connect)
23922399
{
23932400
CAddress addr(CService(), NODE_NONE);
2394-
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL);
2401+
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL, /*use_v2transport=*/false);
23952402
for (int i = 0; i < 10 && i < nLoop; i++)
23962403
{
23972404
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
@@ -2694,7 +2701,9 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
26942701
// Don't record addrman failure attempts when node is offline. This can be identified since all local
26952702
// network connections (if any) belong in the same netgroup, and the size of `outbound_ipv46_peer_netgroups` would only be 1.
26962703
const bool count_failures{((int)outbound_ipv46_peer_netgroups.size() + outbound_privacy_network_peers) >= std::min(nMaxConnections - 1, 2)};
2697-
OpenNetworkConnection(addrConnect, count_failures, &grant, /*strDest=*/nullptr, conn_type);
2704+
// Use BIP324 transport when both us and them have NODE_V2_P2P set.
2705+
const bool use_v2transport(addrConnect.nServices & GetLocalServices() & NODE_P2P_V2);
2706+
OpenNetworkConnection(addrConnect, count_failures, &grant, /*strDest=*/nullptr, conn_type, use_v2transport);
26982707
}
26992708
}
27002709
}
@@ -2783,7 +2792,7 @@ void CConnman::ThreadOpenAddedConnections()
27832792
}
27842793
tried = true;
27852794
CAddress addr(CService(), NODE_NONE);
2786-
OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), ConnectionType::MANUAL);
2795+
OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), ConnectionType::MANUAL, /*use_v2transport=*/false);
27872796
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
27882797
return;
27892798
}
@@ -2795,7 +2804,7 @@ void CConnman::ThreadOpenAddedConnections()
27952804
}
27962805

27972806
// if successful, this moves the passed grant to the constructed node
2798-
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type)
2807+
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type, bool use_v2transport)
27992808
{
28002809
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
28012810
assert(conn_type != ConnectionType::INBOUND);
@@ -2817,7 +2826,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
28172826
} else if (FindNode(std::string(pszDest)))
28182827
return;
28192828

2820-
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2829+
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type, use_v2transport);
28212830

28222831
if (!pnode)
28232832
return;
@@ -3579,6 +3588,15 @@ ServiceFlags CConnman::GetLocalServices() const
35793588
return nLocalServices;
35803589
}
35813590

3591+
static std::unique_ptr<Transport> MakeTransport(NodeId id, bool use_v2transport, bool inbound) noexcept
3592+
{
3593+
if (use_v2transport) {
3594+
return std::make_unique<V2Transport>(id, /*initiating=*/!inbound, SER_NETWORK, INIT_PROTO_VERSION);
3595+
} else {
3596+
return std::make_unique<V1Transport>(id, SER_NETWORK, INIT_PROTO_VERSION);
3597+
}
3598+
}
3599+
35823600
CNode::CNode(NodeId idIn,
35833601
std::shared_ptr<Sock> sock,
35843602
const CAddress& addrIn,
@@ -3589,7 +3607,7 @@ CNode::CNode(NodeId idIn,
35893607
ConnectionType conn_type_in,
35903608
bool inbound_onion,
35913609
CNodeOptions&& node_opts)
3592-
: m_transport{std::make_unique<V1Transport>(idIn, SER_NETWORK, INIT_PROTO_VERSION)},
3610+
: m_transport{MakeTransport(idIn, node_opts.use_v2transport, conn_type_in == ConnectionType::INBOUND)},
35933611
m_permission_flags{node_opts.permission_flags},
35943612
m_sock{sock},
35953613
m_connected{GetTime<std::chrono::seconds>()},

src/net.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,7 @@ struct CNodeOptions
657657
std::unique_ptr<i2p::sam::Session> i2p_sam_session = nullptr;
658658
bool prefer_evict = false;
659659
size_t recv_flood_size{DEFAULT_MAXRECEIVEBUFFER * 1000};
660+
bool use_v2transport = false;
660661
};
661662

662663
/** Information about a peer */
@@ -1098,7 +1099,7 @@ class CConnman
10981099
bool GetNetworkActive() const { return fNetworkActive; };
10991100
bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
11001101
void SetNetworkActive(bool active);
1101-
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant* grantOutbound, const char* strDest, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
1102+
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant* grantOutbound, const char* strDest, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
11021103
bool CheckIncomingNonce(uint64_t nonce);
11031104

11041105
// alias for thread safety annotations only, not defined
@@ -1314,7 +1315,7 @@ class CConnman
13141315
bool AlreadyConnectedToAddress(const CAddress& addr);
13151316

13161317
bool AttemptToEvictConnection();
1317-
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
1318+
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
13181319
void AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const;
13191320

13201321
void DeleteNode(CNode* pnode);

src/rpc/net.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ static RPCHelpMan addnode()
311311
if (command == "onetry")
312312
{
313313
CAddress addr;
314-
connman.OpenNetworkConnection(addr, /*fCountFailure=*/false, /*grantOutbound=*/nullptr, node_arg.c_str(), ConnectionType::MANUAL);
314+
connman.OpenNetworkConnection(addr, /*fCountFailure=*/false, /*grantOutbound=*/nullptr, node_arg.c_str(), ConnectionType::MANUAL, /*use_v2transport=*/false);
315315
return UniValue::VNULL;
316316
}
317317

test/functional/p2p_v2_transport.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2021-present The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
"""
6+
Test v2 transport
7+
"""
8+
9+
from test_framework.messages import NODE_P2P_V2
10+
from test_framework.test_framework import BitcoinTestFramework
11+
from test_framework.util import assert_equal
12+
13+
class V2TransportTest(BitcoinTestFramework):
14+
def set_test_params(self):
15+
self.setup_clean_chain=True
16+
self.num_nodes = 1
17+
self.extra_args = [["-v2transport=0"]]
18+
19+
def run_test(self):
20+
network_info = self.nodes[0].getnetworkinfo()
21+
assert_equal(int(network_info["localservices"], 16) & NODE_P2P_V2, 0)
22+
assert "P2P_V2" not in network_info["localservicesnames"]
23+
24+
self.restart_node(0, ["-v2transport=1"])
25+
network_info = self.nodes[0].getnetworkinfo()
26+
assert_equal(int(network_info["localservices"], 16) & NODE_P2P_V2, NODE_P2P_V2)
27+
assert "P2P_V2" in network_info["localservicesnames"]
28+
29+
if __name__ == '__main__':
30+
V2TransportTest().main()

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@
246246
'p2p_invalid_locator.py',
247247
'p2p_invalid_block.py',
248248
'p2p_invalid_tx.py',
249+
'p2p_v2_transport.py',
249250
'example_test.py',
250251
'wallet_txn_doublespend.py --legacy-wallet',
251252
'wallet_multisig_descriptor_psbt.py --descriptors',

0 commit comments

Comments
 (0)