mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-06-02 15:32:34 +02:00
net: use V2Transport when NODE_P2P_V2 service flag is present
Co-authored-by: Dhruv Mehta <856960+dhruv@users.noreply.github.com>
This commit is contained in:
parent
a4706bc877
commit
62d21ee097
38
src/net.cpp
38
src/net.cpp
@ -439,7 +439,7 @@ static CAddress GetBindAddress(const Sock& sock)
|
|||||||
return addr_bind;
|
return addr_bind;
|
||||||
}
|
}
|
||||||
|
|
||||||
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
|
CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type, bool use_v2transport)
|
||||||
{
|
{
|
||||||
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
||||||
assert(conn_type != ConnectionType::INBOUND);
|
assert(conn_type != ConnectionType::INBOUND);
|
||||||
@ -457,7 +457,8 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "trying connection %s lastseen=%.1fhrs\n",
|
LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "trying %s connection %s lastseen=%.1fhrs\n",
|
||||||
|
use_v2transport ? "v2" : "v1",
|
||||||
pszDest ? pszDest : addrConnect.ToStringAddrPort(),
|
pszDest ? pszDest : addrConnect.ToStringAddrPort(),
|
||||||
Ticks<HoursDouble>(pszDest ? 0h : Now<NodeSeconds>() - addrConnect.nTime));
|
Ticks<HoursDouble>(pszDest ? 0h : Now<NodeSeconds>() - addrConnect.nTime));
|
||||||
|
|
||||||
@ -580,6 +581,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
|
|||||||
CNodeOptions{
|
CNodeOptions{
|
||||||
.i2p_sam_session = std::move(i2p_transient_session),
|
.i2p_sam_session = std::move(i2p_transient_session),
|
||||||
.recv_flood_size = nReceiveFloodSize,
|
.recv_flood_size = nReceiveFloodSize,
|
||||||
|
.use_v2transport = use_v2transport,
|
||||||
});
|
});
|
||||||
pnode->AddRef();
|
pnode->AddRef();
|
||||||
|
|
||||||
@ -1794,6 +1796,10 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
|
const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end();
|
||||||
|
// The V2Transport transparently falls back to V1 behavior when an incoming V1 connection is
|
||||||
|
// detected, so use it whenever we signal NODE_P2P_V2.
|
||||||
|
const bool use_v2transport(nodeServices & NODE_P2P_V2);
|
||||||
|
|
||||||
CNode* pnode = new CNode(id,
|
CNode* pnode = new CNode(id,
|
||||||
std::move(sock),
|
std::move(sock),
|
||||||
addr,
|
addr,
|
||||||
@ -1807,6 +1813,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
|
|||||||
.permission_flags = permission_flags,
|
.permission_flags = permission_flags,
|
||||||
.prefer_evict = discouraged,
|
.prefer_evict = discouraged,
|
||||||
.recv_flood_size = nReceiveFloodSize,
|
.recv_flood_size = nReceiveFloodSize,
|
||||||
|
.use_v2transport = use_v2transport,
|
||||||
});
|
});
|
||||||
pnode->AddRef();
|
pnode->AddRef();
|
||||||
m_msgproc->InitializeNode(*pnode, nodeServices);
|
m_msgproc->InitializeNode(*pnode, nodeServices);
|
||||||
@ -1855,7 +1862,7 @@ bool CConnman::AddConnection(const std::string& address, ConnectionType conn_typ
|
|||||||
CSemaphoreGrant grant(*semOutbound, true);
|
CSemaphoreGrant grant(*semOutbound, true);
|
||||||
if (!grant) return false;
|
if (!grant) return false;
|
||||||
|
|
||||||
OpenNetworkConnection(CAddress(), false, &grant, address.c_str(), conn_type);
|
OpenNetworkConnection(CAddress(), false, &grant, address.c_str(), conn_type, /*use_v2transport=*/false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2289,7 +2296,7 @@ void CConnman::ProcessAddrFetch()
|
|||||||
CAddress addr;
|
CAddress addr;
|
||||||
CSemaphoreGrant grant(*semOutbound, true);
|
CSemaphoreGrant grant(*semOutbound, true);
|
||||||
if (grant) {
|
if (grant) {
|
||||||
OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH);
|
OpenNetworkConnection(addr, false, &grant, strDest.c_str(), ConnectionType::ADDR_FETCH, /*use_v2transport=*/false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2391,7 +2398,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||||||
for (const std::string& strAddr : connect)
|
for (const std::string& strAddr : connect)
|
||||||
{
|
{
|
||||||
CAddress addr(CService(), NODE_NONE);
|
CAddress addr(CService(), NODE_NONE);
|
||||||
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL);
|
OpenNetworkConnection(addr, false, nullptr, strAddr.c_str(), ConnectionType::MANUAL, /*use_v2transport=*/false);
|
||||||
for (int i = 0; i < 10 && i < nLoop; i++)
|
for (int i = 0; i < 10 && i < nLoop; i++)
|
||||||
{
|
{
|
||||||
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
|
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
|
||||||
@ -2694,7 +2701,9 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
|
|||||||
// Don't record addrman failure attempts when node is offline. This can be identified since all local
|
// Don't record addrman failure attempts when node is offline. This can be identified since all local
|
||||||
// network connections (if any) belong in the same netgroup, and the size of `outbound_ipv46_peer_netgroups` would only be 1.
|
// network connections (if any) belong in the same netgroup, and the size of `outbound_ipv46_peer_netgroups` would only be 1.
|
||||||
const bool count_failures{((int)outbound_ipv46_peer_netgroups.size() + outbound_privacy_network_peers) >= std::min(nMaxConnections - 1, 2)};
|
const bool count_failures{((int)outbound_ipv46_peer_netgroups.size() + outbound_privacy_network_peers) >= std::min(nMaxConnections - 1, 2)};
|
||||||
OpenNetworkConnection(addrConnect, count_failures, &grant, /*strDest=*/nullptr, conn_type);
|
// Use BIP324 transport when both us and them have NODE_V2_P2P set.
|
||||||
|
const bool use_v2transport(addrConnect.nServices & GetLocalServices() & NODE_P2P_V2);
|
||||||
|
OpenNetworkConnection(addrConnect, count_failures, &grant, /*strDest=*/nullptr, conn_type, use_v2transport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2783,7 +2792,7 @@ void CConnman::ThreadOpenAddedConnections()
|
|||||||
}
|
}
|
||||||
tried = true;
|
tried = true;
|
||||||
CAddress addr(CService(), NODE_NONE);
|
CAddress addr(CService(), NODE_NONE);
|
||||||
OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), ConnectionType::MANUAL);
|
OpenNetworkConnection(addr, false, &grant, info.strAddedNode.c_str(), ConnectionType::MANUAL, /*use_v2transport=*/false);
|
||||||
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
|
if (!interruptNet.sleep_for(std::chrono::milliseconds(500)))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2795,7 +2804,7 @@ void CConnman::ThreadOpenAddedConnections()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if successful, this moves the passed grant to the constructed node
|
// if successful, this moves the passed grant to the constructed node
|
||||||
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type)
|
void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *pszDest, ConnectionType conn_type, bool use_v2transport)
|
||||||
{
|
{
|
||||||
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
AssertLockNotHeld(m_unused_i2p_sessions_mutex);
|
||||||
assert(conn_type != ConnectionType::INBOUND);
|
assert(conn_type != ConnectionType::INBOUND);
|
||||||
@ -2817,7 +2826,7 @@ void CConnman::OpenNetworkConnection(const CAddress& addrConnect, bool fCountFai
|
|||||||
} else if (FindNode(std::string(pszDest)))
|
} else if (FindNode(std::string(pszDest)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
|
CNode* pnode = ConnectNode(addrConnect, pszDest, fCountFailure, conn_type, use_v2transport);
|
||||||
|
|
||||||
if (!pnode)
|
if (!pnode)
|
||||||
return;
|
return;
|
||||||
@ -3579,6 +3588,15 @@ ServiceFlags CConnman::GetLocalServices() const
|
|||||||
return nLocalServices;
|
return nLocalServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::unique_ptr<Transport> MakeTransport(NodeId id, bool use_v2transport, bool inbound) noexcept
|
||||||
|
{
|
||||||
|
if (use_v2transport) {
|
||||||
|
return std::make_unique<V2Transport>(id, /*initiating=*/!inbound, SER_NETWORK, INIT_PROTO_VERSION);
|
||||||
|
} else {
|
||||||
|
return std::make_unique<V1Transport>(id, SER_NETWORK, INIT_PROTO_VERSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CNode::CNode(NodeId idIn,
|
CNode::CNode(NodeId idIn,
|
||||||
std::shared_ptr<Sock> sock,
|
std::shared_ptr<Sock> sock,
|
||||||
const CAddress& addrIn,
|
const CAddress& addrIn,
|
||||||
@ -3589,7 +3607,7 @@ CNode::CNode(NodeId idIn,
|
|||||||
ConnectionType conn_type_in,
|
ConnectionType conn_type_in,
|
||||||
bool inbound_onion,
|
bool inbound_onion,
|
||||||
CNodeOptions&& node_opts)
|
CNodeOptions&& node_opts)
|
||||||
: m_transport{std::make_unique<V1Transport>(idIn, SER_NETWORK, INIT_PROTO_VERSION)},
|
: m_transport{MakeTransport(idIn, node_opts.use_v2transport, conn_type_in == ConnectionType::INBOUND)},
|
||||||
m_permission_flags{node_opts.permission_flags},
|
m_permission_flags{node_opts.permission_flags},
|
||||||
m_sock{sock},
|
m_sock{sock},
|
||||||
m_connected{GetTime<std::chrono::seconds>()},
|
m_connected{GetTime<std::chrono::seconds>()},
|
||||||
|
@ -657,6 +657,7 @@ struct CNodeOptions
|
|||||||
std::unique_ptr<i2p::sam::Session> i2p_sam_session = nullptr;
|
std::unique_ptr<i2p::sam::Session> i2p_sam_session = nullptr;
|
||||||
bool prefer_evict = false;
|
bool prefer_evict = false;
|
||||||
size_t recv_flood_size{DEFAULT_MAXRECEIVEBUFFER * 1000};
|
size_t recv_flood_size{DEFAULT_MAXRECEIVEBUFFER * 1000};
|
||||||
|
bool use_v2transport = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Information about a peer */
|
/** Information about a peer */
|
||||||
@ -1098,7 +1099,7 @@ public:
|
|||||||
bool GetNetworkActive() const { return fNetworkActive; };
|
bool GetNetworkActive() const { return fNetworkActive; };
|
||||||
bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
|
bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
|
||||||
void SetNetworkActive(bool active);
|
void SetNetworkActive(bool active);
|
||||||
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant* grantOutbound, const char* strDest, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
|
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);
|
||||||
bool CheckIncomingNonce(uint64_t nonce);
|
bool CheckIncomingNonce(uint64_t nonce);
|
||||||
|
|
||||||
// alias for thread safety annotations only, not defined
|
// alias for thread safety annotations only, not defined
|
||||||
@ -1314,7 +1315,7 @@ private:
|
|||||||
bool AlreadyConnectedToAddress(const CAddress& addr);
|
bool AlreadyConnectedToAddress(const CAddress& addr);
|
||||||
|
|
||||||
bool AttemptToEvictConnection();
|
bool AttemptToEvictConnection();
|
||||||
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
|
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex);
|
||||||
void AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const;
|
void AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const;
|
||||||
|
|
||||||
void DeleteNode(CNode* pnode);
|
void DeleteNode(CNode* pnode);
|
||||||
|
@ -311,7 +311,7 @@ static RPCHelpMan addnode()
|
|||||||
if (command == "onetry")
|
if (command == "onetry")
|
||||||
{
|
{
|
||||||
CAddress addr;
|
CAddress addr;
|
||||||
connman.OpenNetworkConnection(addr, /*fCountFailure=*/false, /*grantOutbound=*/nullptr, node_arg.c_str(), ConnectionType::MANUAL);
|
connman.OpenNetworkConnection(addr, /*fCountFailure=*/false, /*grantOutbound=*/nullptr, node_arg.c_str(), ConnectionType::MANUAL, /*use_v2transport=*/false);
|
||||||
return UniValue::VNULL;
|
return UniValue::VNULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
30
test/functional/p2p_v2_transport.py
Executable file
30
test/functional/p2p_v2_transport.py
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# Copyright (c) 2021-present The Bitcoin Core developers
|
||||||
|
# Distributed under the MIT software license, see the accompanying
|
||||||
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
"""
|
||||||
|
Test v2 transport
|
||||||
|
"""
|
||||||
|
|
||||||
|
from test_framework.messages import NODE_P2P_V2
|
||||||
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
|
from test_framework.util import assert_equal
|
||||||
|
|
||||||
|
class V2TransportTest(BitcoinTestFramework):
|
||||||
|
def set_test_params(self):
|
||||||
|
self.setup_clean_chain=True
|
||||||
|
self.num_nodes = 1
|
||||||
|
self.extra_args = [["-v2transport=0"]]
|
||||||
|
|
||||||
|
def run_test(self):
|
||||||
|
network_info = self.nodes[0].getnetworkinfo()
|
||||||
|
assert_equal(int(network_info["localservices"], 16) & NODE_P2P_V2, 0)
|
||||||
|
assert "P2P_V2" not in network_info["localservicesnames"]
|
||||||
|
|
||||||
|
self.restart_node(0, ["-v2transport=1"])
|
||||||
|
network_info = self.nodes[0].getnetworkinfo()
|
||||||
|
assert_equal(int(network_info["localservices"], 16) & NODE_P2P_V2, NODE_P2P_V2)
|
||||||
|
assert "P2P_V2" in network_info["localservicesnames"]
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
V2TransportTest().main()
|
@ -246,6 +246,7 @@ BASE_SCRIPTS = [
|
|||||||
'p2p_invalid_locator.py',
|
'p2p_invalid_locator.py',
|
||||||
'p2p_invalid_block.py',
|
'p2p_invalid_block.py',
|
||||||
'p2p_invalid_tx.py',
|
'p2p_invalid_tx.py',
|
||||||
|
'p2p_v2_transport.py',
|
||||||
'example_test.py',
|
'example_test.py',
|
||||||
'wallet_txn_doublespend.py --legacy-wallet',
|
'wallet_txn_doublespend.py --legacy-wallet',
|
||||||
'wallet_multisig_descriptor_psbt.py --descriptors',
|
'wallet_multisig_descriptor_psbt.py --descriptors',
|
||||||
|
Loading…
Reference in New Issue
Block a user