Skip to content

Commit ce3bdd0

Browse files
committed
Merge #19316: [net] Cleanup logic around connection types
01e2830 [net] Remove unnecessary default args on CNode constructor (Amiti Uttarwar) bc5d65b [refactor] Remove IsOutboundDisconnectionCandidate (Amiti Uttarwar) 2f2e13b [net/refactor] Simplify multiple-connection checks (Amiti Uttarwar) 7f7b83d [net/refactor] Rework ThreadOpenConnections logic (Amiti Uttarwar) 35839e9 [net] Fix bug where AddrFetch connections would be counted as outbound full relay (Amiti Uttarwar) 4972c21 [net/refactor] Clarify logic for selecting connections in ThreadOpenConnections (Amiti Uttarwar) 60156f5 [net/refactor] Remove fInbound flag from CNode (Amiti Uttarwar) 7b322df [net/refactor] Remove m_addr_fetch member var from CNode (Amiti Uttarwar) 1492342 [net/refactor] Remove fFeeler flag from CNode (Amiti Uttarwar) 49efac5 [net/refactor] Remove m_manual_connection flag from CNode (Amiti Uttarwar) d3698b5 [net/refactor] Add connection type as a member var to CNode (Amiti Uttarwar) 46578c0 [doc] Describe different connection types (Amiti Uttarwar) 442abae [net/refactor] Add AddrFetch connections to ConnectionType enum (Amiti Uttarwar) af59feb [net/refactor] Extract m_addr_known logic from initializer list (Amiti Uttarwar) e1bc298 [net/refactor] Add block relay only connections to ConnectionType enum (Amiti Uttarwar) 0e52a65 [net/refactor] Add feeler connections to ConnectionType enum (Amiti Uttarwar) 1521c47 [net/refactor] Add manual connections to ConnectionType enum (Amiti Uttarwar) 26304b4 [net/refactor] Introduce an enum to distinguish type of connection (Amiti Uttarwar) 3f1b714 scripted-diff: Rename OneShot to AddrFetch (Amiti Uttarwar) Pull request description: **This is part 1 of #19315, which enables the ability to test `outbound` and `block-relay-only` connections from the functional tests.** Please see that PR for more information of overall functionality. **This PR simplifies how we manage different connection types.** It introduces an enum with the various types of connections so we can explicitly define the connection type. The existing system relies on a series of independent flags, then has asserts scattered around to ensure that conflicting flags are not enabled at the same time. I find this approach to be both brittle and confusing. While making these changes, I found a small bug due to the silent assumptions. This PR also proposes a rename from `OneShot` to `AddrFetch`. I find the name `OneShot` to be very confusing, especially when we also have `onetry` manual connections. Everyone I've talked to offline has agreed that the name is confusing, so I propose a potential alternative. I think this is a good opportunity for a rename since I'm creating an enum to explicitly define the connection types. (some context for the unfamiliar: `oneshot` or `addrfetch` connections are short-lived connections created on startup. They connect to the seed peers, send a `getaddr` to solicit addresses, then close the connection.) Overview of this PR: * rename `oneshot` to `addrfetch` * introduce `ConnectionType` enum * one by one, add different connection types to the enum * expose the `conn_type` on CNode, and use this to reduce reliance on flags (& asserts) * fix the bug in counting different type of connections * some additional cleanup to simplify logic and make expectations explicit/inclusive rather than implicit/exclusive. ACKs for top commit: jnewbery: utACK 01e2830 laanwj: Code review ACK 01e2830, the commits are pretty straightforward to follow, and I think this is a move in the right direction overall vasild: ACK 01e2830 sdaftuar: ACK 01e2830. fanquake: ACK 01e2830 - I don't have as much experience with the networking code but these changes look fairly straight forward, the new code seems more robust/understandable and the additional documentation is great. I'm glad that a followup branch is already underway. There might be some more review comments here later today, so keep an eye on the discussion, however I'm going to merge this now. jb55: wow this code was messy before... ACK 01e2830 Tree-SHA512: 7bb644a6ed5849913d777ebc2ff89133ca0fbef680355a9a344e07496a979e6f9ff21a958e8eea93dcd7d5c343682b0c7174b1a3de380a4247eaae73da436e15
2 parents cb1ee15 + 01e2830 commit ce3bdd0

File tree

9 files changed

+186
-140
lines changed

9 files changed

+186
-140
lines changed

src/chainparams.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class CMainParams : public CChainParams {
110110

111111
// Note that of those which support the service bits prefix, most only support a subset of
112112
// possible options.
113-
// This is fine at runtime as we'll fall back to using them as a oneshot if they don't support the
113+
// This is fine at runtime as we'll fall back to using them as an addrfetch if they don't support the
114114
// service bits we want, but we should get them updated to support all service bits wanted by any
115115
// release ASAP to avoid it where possible.
116116
vSeeds.emplace_back("seed.bitcoin.sipa.be"); // Pieter Wuille, only supports x1, x5, x9, and xd

src/net.cpp

Lines changed: 77 additions & 79 deletions
Large diffs are not rendered by default.

src/net.h

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ struct CSerializedNetMsg
117117
std::string m_type;
118118
};
119119

120+
/** Different types of connections to a peer. This enum encapsulates the
121+
* information we have available at the time of opening or accepting the
122+
* connection. Aside from INBOUND, all types are initiated by us. */
123+
enum class ConnectionType {
124+
INBOUND, /**< peer initiated connections */
125+
OUTBOUND, /**< full relay connections (blocks, addrs, txns) made automatically. Addresses selected from AddrMan. */
126+
MANUAL, /**< connections to addresses added via addnode or the connect command line argument */
127+
FEELER, /**< short lived connections used to test address validity */
128+
BLOCK_RELAY, /**< only relay blocks to these automatic outbound connections. Addresses selected from AddrMan. */
129+
ADDR_FETCH, /**< short lived connections used to solicit addrs when starting the node without a populated AddrMan */
130+
};
120131

121132
class NetEventsInterface;
122133
class CConnman
@@ -201,7 +212,7 @@ class CConnman
201212
bool GetNetworkActive() const { return fNetworkActive; };
202213
bool GetUseAddrmanOutgoing() const { return m_use_addrman_outgoing; };
203214
void SetNetworkActive(bool active);
204-
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, bool fOneShot = false, bool fFeeler = false, bool manual_connection = false, bool block_relay_only = false);
215+
void OpenNetworkConnection(const CAddress& addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound = nullptr, const char *strDest = nullptr, ConnectionType conn_type = ConnectionType::OUTBOUND);
205216
bool CheckIncomingNonce(uint64_t nonce);
206217

207218
bool ForNode(NodeId id, std::function<bool(CNode* pnode)> func);
@@ -351,8 +362,8 @@ class CConnman
351362
bool Bind(const CService& addr, unsigned int flags, NetPermissionFlags permissions);
352363
bool InitBinds(const std::vector<CService>& binds, const std::vector<NetWhitebindPermissions>& whiteBinds);
353364
void ThreadOpenAddedConnections();
354-
void AddOneShot(const std::string& strDest);
355-
void ProcessOneShot();
365+
void AddAddrFetch(const std::string& strDest);
366+
void ProcessAddrFetch();
356367
void ThreadOpenConnections(std::vector<std::string> connect);
357368
void ThreadMessageHandler();
358369
void AcceptConnection(const ListenSocket& hListenSocket);
@@ -373,7 +384,7 @@ class CConnman
373384
CNode* FindNode(const CService& addr);
374385

375386
bool AttemptToEvictConnection();
376-
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection, bool block_relay_only);
387+
CNode* ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type);
377388
void AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const;
378389

379390
void DeleteNode(CNode* pnode);
@@ -416,8 +427,8 @@ class CConnman
416427
std::atomic<bool> fNetworkActive{true};
417428
bool fAddressesInitialized{false};
418429
CAddrMan addrman;
419-
std::deque<std::string> vOneShots GUARDED_BY(cs_vOneShots);
420-
RecursiveMutex cs_vOneShots;
430+
std::deque<std::string> m_addr_fetches GUARDED_BY(m_addr_fetches_mutex);
431+
RecursiveMutex m_addr_fetches_mutex;
421432
std::vector<std::string> vAddedNodes GUARDED_BY(cs_vAddedNodes);
422433
RecursiveMutex cs_vAddedNodes;
423434
std::vector<CNode*> vNodes GUARDED_BY(cs_vNodes);
@@ -798,12 +809,8 @@ class CNode
798809
}
799810
// This boolean is unusued in actual processing, only present for backward compatibility at RPC/QT level
800811
bool m_legacyWhitelisted{false};
801-
bool fFeeler{false}; // If true this node is being used as a short lived feeler.
802-
bool fOneShot{false};
803-
bool m_manual_connection{false};
804812
bool fClient{false}; // set by version message
805813
bool m_limited_node{false}; //after BIP159, set by version message
806-
const bool fInbound;
807814
std::atomic_bool fSuccessfullyConnected{false};
808815
// Setting fDisconnect to true will cause the node to be disconnected the
809816
// next time DisconnectNodes() runs
@@ -816,6 +823,60 @@ class CNode
816823
std::atomic_bool fPauseRecv{false};
817824
std::atomic_bool fPauseSend{false};
818825

826+
bool IsOutboundOrBlockRelayConn() const {
827+
switch(m_conn_type) {
828+
case ConnectionType::OUTBOUND:
829+
case ConnectionType::BLOCK_RELAY:
830+
return true;
831+
case ConnectionType::INBOUND:
832+
case ConnectionType::MANUAL:
833+
case ConnectionType::ADDR_FETCH:
834+
case ConnectionType::FEELER:
835+
return false;
836+
}
837+
838+
assert(false);
839+
}
840+
841+
bool IsFullOutboundConn() const {
842+
return m_conn_type == ConnectionType::OUTBOUND;
843+
}
844+
845+
bool IsManualConn() const {
846+
return m_conn_type == ConnectionType::MANUAL;
847+
}
848+
849+
bool IsBlockOnlyConn() const {
850+
return m_conn_type == ConnectionType::BLOCK_RELAY;
851+
}
852+
853+
bool IsFeelerConn() const {
854+
return m_conn_type == ConnectionType::FEELER;
855+
}
856+
857+
bool IsAddrFetchConn() const {
858+
return m_conn_type == ConnectionType::ADDR_FETCH;
859+
}
860+
861+
bool IsInboundConn() const {
862+
return m_conn_type == ConnectionType::INBOUND;
863+
}
864+
865+
bool ExpectServicesFromConn() const {
866+
switch(m_conn_type) {
867+
case ConnectionType::INBOUND:
868+
case ConnectionType::MANUAL:
869+
case ConnectionType::FEELER:
870+
return false;
871+
case ConnectionType::OUTBOUND:
872+
case ConnectionType::BLOCK_RELAY:
873+
case ConnectionType::ADDR_FETCH:
874+
return true;
875+
}
876+
877+
assert(false);
878+
}
879+
819880
protected:
820881
mapMsgCmdSize mapSendBytesPerMsgCmd;
821882
mapMsgCmdSize mapRecvBytesPerMsgCmd GUARDED_BY(cs_vRecv);
@@ -826,7 +887,7 @@ class CNode
826887

827888
// flood relay
828889
std::vector<CAddress> vAddrToSend;
829-
const std::unique_ptr<CRollingBloomFilter> m_addr_known;
890+
std::unique_ptr<CRollingBloomFilter> m_addr_known = nullptr;
830891
bool fGetAddr{false};
831892
std::chrono::microseconds m_next_addr_send GUARDED_BY(cs_sendProcessing){0};
832893
std::chrono::microseconds m_next_local_addr_send GUARDED_BY(cs_sendProcessing){0};
@@ -890,14 +951,15 @@ class CNode
890951

891952
std::set<uint256> orphan_work_set;
892953

893-
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn = "", bool fInboundIn = false, bool block_relay_only = false);
954+
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in);
894955
~CNode();
895956
CNode(const CNode&) = delete;
896957
CNode& operator=(const CNode&) = delete;
897958

898959
private:
899960
const NodeId id;
900961
const uint64_t nLocalHostNonce;
962+
const ConnectionType m_conn_type;
901963

902964
//! Services offered to this peer.
903965
//!

src/net_processing.cpp

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ static void UpdatePreferredDownload(const CNode& node, CNodeState* state) EXCLUS
479479
nPreferredDownload -= state->fPreferredDownload;
480480

481481
// Whether this node should be marked as a preferred download node.
482-
state->fPreferredDownload = (!node.fInbound || node.HasPermission(PF_NOBAN)) && !node.fOneShot && !node.fClient;
482+
state->fPreferredDownload = (!node.IsInboundConn() || node.HasPermission(PF_NOBAN)) && !node.IsAddrFetchConn() && !node.fClient;
483483

484484
nPreferredDownload += state->fPreferredDownload;
485485
}
@@ -833,22 +833,15 @@ void UpdateLastBlockAnnounceTime(NodeId node, int64_t time_in_seconds)
833833
if (state) state->m_last_block_announcement = time_in_seconds;
834834
}
835835

836-
// Returns true for outbound peers, excluding manual connections, feelers, and
837-
// one-shots.
838-
static bool IsOutboundDisconnectionCandidate(const CNode& node)
839-
{
840-
return !(node.fInbound || node.m_manual_connection || node.fFeeler || node.fOneShot);
841-
}
842-
843836
void PeerLogicValidation::InitializeNode(CNode *pnode) {
844837
CAddress addr = pnode->addr;
845838
std::string addrName = pnode->GetAddrName();
846839
NodeId nodeid = pnode->GetId();
847840
{
848841
LOCK(cs_main);
849-
mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName), pnode->fInbound, pnode->m_manual_connection));
842+
mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName), pnode->IsInboundConn(), pnode->IsManualConn()));
850843
}
851-
if(!pnode->fInbound)
844+
if(!pnode->IsInboundConn())
852845
PushNodeVersion(*pnode, *connman, GetTime());
853846
}
854847

@@ -1982,14 +1975,14 @@ static void ProcessHeadersMessage(CNode& pfrom, CConnman& connman, ChainstateMan
19821975
// until we have a headers chain that has at least
19831976
// nMinimumChainWork, even if a peer has a chain past our tip,
19841977
// as an anti-DoS measure.
1985-
if (IsOutboundDisconnectionCandidate(pfrom)) {
1978+
if (pfrom.IsOutboundOrBlockRelayConn()) {
19861979
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
19871980
pfrom.fDisconnect = true;
19881981
}
19891982
}
19901983
}
19911984

1992-
if (!pfrom.fDisconnect && IsOutboundDisconnectionCandidate(pfrom) && nodestate->pindexBestKnownBlock != nullptr && pfrom.m_tx_relay != nullptr) {
1985+
if (!pfrom.fDisconnect && pfrom.IsOutboundOrBlockRelayConn() && nodestate->pindexBestKnownBlock != nullptr && pfrom.m_tx_relay != nullptr) {
19931986
// If this is an outbound full-relay peer, check to see if we should protect
19941987
// it from the bad/lagging chain logic.
19951988
// Note that block-relay-only peers are already implicitly protected, so we
@@ -2352,11 +2345,11 @@ void ProcessMessage(
23522345
vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
23532346
nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
23542347
nServices = ServiceFlags(nServiceInt);
2355-
if (!pfrom.fInbound)
2348+
if (!pfrom.IsInboundConn())
23562349
{
23572350
connman.SetServices(pfrom.addr, nServices);
23582351
}
2359-
if (!pfrom.fInbound && !pfrom.fFeeler && !pfrom.m_manual_connection && !HasAllDesirableServiceFlags(nServices))
2352+
if (pfrom.ExpectServicesFromConn() && !HasAllDesirableServiceFlags(nServices))
23602353
{
23612354
LogPrint(BCLog::NET, "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom.GetId(), nServices, GetDesirableServiceFlags(nServices));
23622355
pfrom.fDisconnect = true;
@@ -2383,20 +2376,20 @@ void ProcessMessage(
23832376
if (!vRecv.empty())
23842377
vRecv >> fRelay;
23852378
// Disconnect if we connected to ourself
2386-
if (pfrom.fInbound && !connman.CheckIncomingNonce(nNonce))
2379+
if (pfrom.IsInboundConn() && !connman.CheckIncomingNonce(nNonce))
23872380
{
23882381
LogPrintf("connected to self at %s, disconnecting\n", pfrom.addr.ToString());
23892382
pfrom.fDisconnect = true;
23902383
return;
23912384
}
23922385

2393-
if (pfrom.fInbound && addrMe.IsRoutable())
2386+
if (pfrom.IsInboundConn() && addrMe.IsRoutable())
23942387
{
23952388
SeenLocal(addrMe);
23962389
}
23972390

23982391
// Be shy and don't send version until we hear
2399-
if (pfrom.fInbound)
2392+
if (pfrom.IsInboundConn())
24002393
PushNodeVersion(pfrom, connman, GetAdjustedTime());
24012394

24022395
if (nVersion >= WTXID_RELAY_VERSION) {
@@ -2440,7 +2433,7 @@ void ProcessMessage(
24402433
UpdatePreferredDownload(pfrom, State(pfrom.GetId()));
24412434
}
24422435

2443-
if (!pfrom.fInbound && pfrom.IsAddrRelayPeer())
2436+
if (!pfrom.IsInboundConn() && pfrom.IsAddrRelayPeer())
24442437
{
24452438
// Advertise our address
24462439
if (fListen && !::ChainstateActive().IsInitialBlockDownload())
@@ -2484,8 +2477,7 @@ void ProcessMessage(
24842477
}
24852478

24862479
// Feeler connections exist only to verify if address is online.
2487-
if (pfrom.fFeeler) {
2488-
assert(pfrom.fInbound == false);
2480+
if (pfrom.IsFeelerConn()) {
24892481
pfrom.fDisconnect = true;
24902482
}
24912483
return;
@@ -2505,7 +2497,7 @@ void ProcessMessage(
25052497
{
25062498
pfrom.SetRecvVersion(std::min(pfrom.nVersion.load(), PROTOCOL_VERSION));
25072499

2508-
if (!pfrom.fInbound) {
2500+
if (!pfrom.IsInboundConn()) {
25092501
// Mark this node as currently connected, so we update its timestamp later.
25102502
LOCK(cs_main);
25112503
State(pfrom.GetId())->fCurrentlyConnected = true;
@@ -2614,7 +2606,7 @@ void ProcessMessage(
26142606
connman.AddNewAddresses(vAddrOk, pfrom.addr, 2 * 60 * 60);
26152607
if (vAddr.size() < 1000)
26162608
pfrom.fGetAddr = false;
2617-
if (pfrom.fOneShot)
2609+
if (pfrom.IsAddrFetchConn())
26182610
pfrom.fDisconnect = true;
26192611
return;
26202612
}
@@ -3509,7 +3501,7 @@ void ProcessMessage(
35093501
// to users' AddrMan and later request them by sending getaddr messages.
35103502
// Making nodes which are behind NAT and can only make outgoing connections ignore
35113503
// the getaddr message mitigates the attack.
3512-
if (!pfrom.fInbound) {
3504+
if (!pfrom.IsInboundConn()) {
35133505
LogPrint(BCLog::NET, "Ignoring \"getaddr\" from outbound connection. peer=%d\n", pfrom.GetId());
35143506
return;
35153507
}
@@ -3792,7 +3784,7 @@ bool PeerLogicValidation::MaybeDiscourageAndDisconnect(CNode& pnode)
37923784
return false;
37933785
}
37943786

3795-
if (pnode.m_manual_connection) {
3787+
if (pnode.IsManualConn()) {
37963788
// We never disconnect or discourage manual peers for bad behavior
37973789
LogPrintf("Warning: not punishing manually connected peer %d!\n", peer_id);
37983790
return false;
@@ -3913,7 +3905,7 @@ void PeerLogicValidation::ConsiderEviction(CNode& pto, int64_t time_in_seconds)
39133905
CNodeState &state = *State(pto.GetId());
39143906
const CNetMsgMaker msgMaker(pto.GetSendVersion());
39153907

3916-
if (!state.m_chain_sync.m_protect && IsOutboundDisconnectionCandidate(pto) && state.fSyncStarted) {
3908+
if (!state.m_chain_sync.m_protect && pto.IsOutboundOrBlockRelayConn() && state.fSyncStarted) {
39173909
// This is an outbound peer subject to disconnection if they don't
39183910
// announce a block with as much work as the current tip within
39193911
// CHAIN_SYNC_TIMEOUT + HEADERS_RESPONSE_TIME seconds (note: if
@@ -3975,7 +3967,7 @@ void PeerLogicValidation::EvictExtraOutboundPeers(int64_t time_in_seconds)
39753967
AssertLockHeld(cs_main);
39763968

39773969
// Ignore non-outbound peers, or nodes marked for disconnect already
3978-
if (!IsOutboundDisconnectionCandidate(*pnode) || pnode->fDisconnect) return;
3970+
if (!pnode->IsOutboundOrBlockRelayConn() || pnode->fDisconnect) return;
39793971
CNodeState *state = State(pnode->GetId());
39803972
if (state == nullptr) return; // shouldn't be possible, but just in case
39813973
// Don't evict our protected peers
@@ -4153,7 +4145,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
41534145
// Start block sync
41544146
if (pindexBestHeader == nullptr)
41554147
pindexBestHeader = ::ChainActive().Tip();
4156-
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
4148+
bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->IsAddrFetchConn()); // Download if this is a nice peer, or we have no nice peers and this one might do.
41574149
if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex) {
41584150
// Only actively request headers from a single peer, unless we're close to today.
41594151
if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
@@ -4338,7 +4330,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
43384330
bool fSendTrickle = pto->HasPermission(PF_NOBAN);
43394331
if (pto->m_tx_relay->nNextInvSend < current_time) {
43404332
fSendTrickle = true;
4341-
if (pto->fInbound) {
4333+
if (pto->IsInboundConn()) {
43424334
pto->m_tx_relay->nNextInvSend = std::chrono::microseconds{connman->PoissonNextSendInbound(nNow, INVENTORY_BROADCAST_INTERVAL)};
43434335
} else {
43444336
// Use half the delay for outbound peers, as there is less privacy concern for them.

src/rpc/net.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ static UniValue addnode(const JSONRPCRequest& request)
264264
if (strCommand == "onetry")
265265
{
266266
CAddress addr;
267-
node.connman->OpenNetworkConnection(addr, false, nullptr, strNode.c_str(), false, false, true);
267+
node.connman->OpenNetworkConnection(addr, false, nullptr, strNode.c_str(), ConnectionType::MANUAL);
268268
return NullUniValue;
269269
}
270270

0 commit comments

Comments
 (0)