From 2863d7dddb62d987b3e1c3b8bfad7083f0f774b2 Mon Sep 17 00:00:00 2001 From: brunoerg Date: Tue, 28 Nov 2023 12:36:47 -0300 Subject: [PATCH 1/7] net: store `-whitelist{force}relay` values in `CConnman` --- src/init.cpp | 2 ++ src/net.h | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index 988daefeec800..83d79450319a6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1775,6 +1775,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) connOptions.m_added_nodes = args.GetArgs("-addnode"); connOptions.nMaxOutboundLimit = *opt_max_upload; connOptions.m_peer_connect_timeout = peer_connect_timeout; + connOptions.whitelist_forcerelay = args.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY); + connOptions.whitelist_relay = args.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY); // Port to bind to if `-bind=addr` is provided without a `:port` suffix. const uint16_t default_bind_port = diff --git a/src/net.h b/src/net.h index e78e122c44f98..70abdbaaf83bb 100644 --- a/src/net.h +++ b/src/net.h @@ -1064,6 +1064,8 @@ class CConnman std::vector m_specified_outgoing; std::vector m_added_nodes; bool m_i2p_accept_incoming; + bool whitelist_forcerelay = DEFAULT_WHITELISTFORCERELAY; + bool whitelist_relay = DEFAULT_WHITELISTRELAY; }; void Init(const Options& connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex, !m_total_bytes_sent_mutex) @@ -1098,6 +1100,8 @@ class CConnman } } m_onion_binds = connOptions.onion_binds; + whitelist_forcerelay = connOptions.whitelist_forcerelay; + whitelist_relay = connOptions.whitelist_relay; } CConnman(uint64_t seed0, uint64_t seed1, AddrMan& addrman, const NetGroupManager& netgroupman, @@ -1551,6 +1555,18 @@ class CConnman */ std::vector m_onion_binds; + /** + * flag for adding 'forcerelay' permission to whitelisted inbound + * and manual peers with default permissions. + */ + bool whitelist_forcerelay; + + /** + * flag for adding 'relay' permission to whitelisted inbound + * and manual peers with default permissions. + */ + bool whitelist_relay; + /** * Mutex protecting m_i2p_sam_sessions. */ From 9133fd69a5cc9a0ab1a06a60d09f1b7e1039018e Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 7 Jul 2021 00:54:25 +0000 Subject: [PATCH 2/7] net: Move `NetPermissionFlags::Implicit` verification to `AddWhitelistPermissionFlags` --- src/net.cpp | 24 +++++++++++++----------- src/net.h | 7 +------ src/net_permissions.h | 5 +++++ 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 7c82f01d75730..1241c76e631fa 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -558,9 +558,18 @@ void CNode::CloseSocketDisconnect() m_i2p_sam_session.reset(); } -void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr) const { - for (const auto& subnet : vWhitelistedRange) { - if (subnet.m_subnet.Match(addr)) NetPermissions::AddFlag(flags, subnet.m_flags); +void CConnman::AddWhitelistPermissionFlags(NetPermissionFlags& flags, const CNetAddr &addr, const std::vector& ranges) const { + for (const auto& subnet : ranges) { + if (subnet.m_subnet.Match(addr)) { + NetPermissions::AddFlag(flags, subnet.m_flags); + } + } + if (NetPermissions::HasFlag(flags, NetPermissionFlags::Implicit)) { + NetPermissions::ClearFlag(flags, NetPermissionFlags::Implicit); + if (whitelist_forcerelay) NetPermissions::AddFlag(flags, NetPermissionFlags::ForceRelay); + if (whitelist_relay) NetPermissions::AddFlag(flags, NetPermissionFlags::Relay); + NetPermissions::AddFlag(flags, NetPermissionFlags::Mempool); + NetPermissions::AddFlag(flags, NetPermissionFlags::NoBan); } } @@ -1726,14 +1735,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr&& sock, { int nInbound = 0; - AddWhitelistPermissionFlags(permission_flags, addr); - if (NetPermissions::HasFlag(permission_flags, NetPermissionFlags::Implicit)) { - NetPermissions::ClearFlag(permission_flags, NetPermissionFlags::Implicit); - if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) NetPermissions::AddFlag(permission_flags, NetPermissionFlags::ForceRelay); - if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) NetPermissions::AddFlag(permission_flags, NetPermissionFlags::Relay); - NetPermissions::AddFlag(permission_flags, NetPermissionFlags::Mempool); - NetPermissions::AddFlag(permission_flags, NetPermissionFlags::NoBan); - } + AddWhitelistPermissionFlags(permission_flags, addr, vWhitelistedRange); { LOCK(m_nodes_mutex); diff --git a/src/net.h b/src/net.h index 70abdbaaf83bb..c491c47122ca5 100644 --- a/src/net.h +++ b/src/net.h @@ -53,11 +53,6 @@ class CNode; class CScheduler; struct bilingual_str; -/** Default for -whitelistrelay. */ -static const bool DEFAULT_WHITELISTRELAY = true; -/** Default for -whitelistforcerelay. */ -static const bool DEFAULT_WHITELISTFORCERELAY = false; - /** Time after which to disconnect, after waiting for a ping response (or inactivity). */ static constexpr std::chrono::minutes TIMEOUT_INTERVAL{20}; /** Run the feeler connection loop once every 2 minutes. **/ @@ -1343,7 +1338,7 @@ class CConnman bool AttemptToEvictConnection(); 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 std::vector& ranges) const; void DeleteNode(CNode* pnode); diff --git a/src/net_permissions.h b/src/net_permissions.h index b7f3bffe1c645..a61eddc121bcc 100644 --- a/src/net_permissions.h +++ b/src/net_permissions.h @@ -15,6 +15,11 @@ struct bilingual_str; extern const std::vector NET_PERMISSIONS_DOC; +/** Default for -whitelistrelay. */ +constexpr bool DEFAULT_WHITELISTRELAY = true; +/** Default for -whitelistforcerelay. */ +constexpr bool DEFAULT_WHITELISTFORCERELAY = false; + enum class NetPermissionFlags : uint32_t { None = 0, // Can query bloomfilter even if -peerbloomfilters is false From 8e06be347c5e14cbe75256eba170e0867f95f360 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 7 Jul 2021 00:57:50 +0000 Subject: [PATCH 3/7] net_processing: Move extra service flag into InitializeNode --- src/net.cpp | 9 ++------- src/net_processing.cpp | 5 +++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index 1241c76e631fa..64f4620eff3e8 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1790,15 +1790,10 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr&& sock, NodeId id = GetNewNodeId(); uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize(); - ServiceFlags nodeServices = nLocalServices; - if (NetPermissions::HasFlag(permission_flags, NetPermissionFlags::BloomFilter)) { - nodeServices = static_cast(nodeServices | NODE_BLOOM); - } - 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); + const bool use_v2transport(nLocalServices & NODE_P2P_V2); CNode* pnode = new CNode(id, std::move(sock), @@ -1816,7 +1811,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr&& sock, .use_v2transport = use_v2transport, }); pnode->AddRef(); - m_msgproc->InitializeNode(*pnode, nodeServices); + m_msgproc->InitializeNode(*pnode, nLocalServices); LogPrint(BCLog::NET, "connection from %s accepted\n", addr.ToStringAddrPort()); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index c8da927763443..0d45b85f6966a 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1571,6 +1571,11 @@ void PeerManagerImpl::InitializeNode(CNode& node, ServiceFlags our_services) m_node_states.emplace_hint(m_node_states.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(node.IsInboundConn())); assert(m_txrequest.Count(nodeid) == 0); } + + if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BloomFilter)) { + our_services = static_cast(our_services | NODE_BLOOM); + } + PeerRef peer = std::make_shared(nodeid, our_services); { LOCK(m_peer_mutex); From 66bc6e2d1749f43d7b314aa2784a06af78440170 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 7 Jul 2021 01:06:27 +0000 Subject: [PATCH 4/7] Accept "in" and "out" flags to -whitelist to allow whitelisting manual connections --- src/init.cpp | 22 +++++++++++++++------- src/net.cpp | 7 ++++++- src/net.h | 10 +++++++--- src/net_permissions.cpp | 28 ++++++++++++++++++++++++---- src/net_permissions.h | 3 ++- src/test/fuzz/net_permissions.cpp | 4 +++- src/test/netbase_tests.cpp | 18 ++++++++++++++---- 7 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 83d79450319a6..7ed24d5853f97 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -473,7 +473,7 @@ void SetupServerArgs(ArgsManager& argsman) argsman.AddArg("-blocknotify=", "Execute command when the best block changes (%s in cmd is replaced by block hash)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); #endif argsman.AddArg("-blockreconstructionextratxn=", strprintf("Extra transactions to keep in memory for compact block reconstructions (default: %u)", DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Automatic broadcast and rebroadcast of any transactions from inbound peers is disabled, unless the peer has the 'forcerelay' permission. RPC transactions are not affected. (default: %u)", DEFAULT_BLOCKSONLY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + argsman.AddArg("-blocksonly", strprintf("Whether to reject transactions from network peers. Disables automatic broadcast and rebroadcast of transactions, unless the source peer has the 'forcerelay' permission. RPC transactions are not affected. (default: %u)", DEFAULT_BLOCKSONLY), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-coinstatsindex", strprintf("Maintain coinstats index used by the gettxoutsetinfo RPC (default: %u)", DEFAULT_COINSTATSINDEX), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-conf=", strprintf("Specify path to read-only configuration file. Relative paths will be prefixed by datadir location (only useable from command line, not configuration file) (default: %s)", BITCOIN_CONF_FILENAME), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); argsman.AddArg("-datadir=", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); @@ -567,9 +567,11 @@ void SetupServerArgs(ArgsManager& argsman) "Use [host]:port notation for IPv6. Allowed permissions: " + Join(NET_PERMISSIONS_DOC, ", ") + ". " "Specify multiple permissions separated by commas (default: download,noban,mempool,relay). Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); - argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers connecting from the given IP address (e.g. 1.2.3.4) or " + argsman.AddArg("-whitelist=<[permissions@]IP address or network>", "Add permission flags to the peers using the given IP address (e.g. 1.2.3.4) or " "CIDR-notated network (e.g. 1.2.3.0/24). Uses the same permissions as " - "-whitebind. Can be specified multiple times." , ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); + "-whitebind. " + "Additional flags \"in\" and \"out\" control whether permissions apply to incoming connections and/or manual (default: incoming only). " + "Can be specified multiple times.", ArgsManager::ALLOW_ANY, OptionsCategory::CONNECTION); g_wallet_init_interface.AddWalletOptions(argsman); @@ -639,8 +641,8 @@ void SetupServerArgs(ArgsManager& argsman) OptionsCategory::NODE_RELAY); argsman.AddArg("-minrelaytxfee=", strprintf("Fees (in %s/kvB) smaller than this are considered zero fee for relaying, mining and transaction creation (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_MIN_RELAY_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); - argsman.AddArg("-whitelistforcerelay", strprintf("Add 'forcerelay' permission to whitelisted inbound peers with default permissions. This will relay transactions even if the transactions were already in the mempool. (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); - argsman.AddArg("-whitelistrelay", strprintf("Add 'relay' permission to whitelisted inbound peers with default permissions. This will accept relayed transactions even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); + argsman.AddArg("-whitelistforcerelay", strprintf("Add 'forcerelay' permission to whitelisted peers with default permissions. This will relay transactions even if the transactions were already in the mempool. (default: %d)", DEFAULT_WHITELISTFORCERELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); + argsman.AddArg("-whitelistrelay", strprintf("Add 'relay' permission to whitelisted peers with default permissions. This will accept relayed transactions even when not relaying transactions (default: %d)", DEFAULT_WHITELISTRELAY), ArgsManager::ALLOW_ANY, OptionsCategory::NODE_RELAY); argsman.AddArg("-blockmaxweight=", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION); @@ -1861,9 +1863,15 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) for (const auto& net : args.GetArgs("-whitelist")) { NetWhitelistPermissions subnet; + ConnectionDirection connection_direction; bilingual_str error; - if (!NetWhitelistPermissions::TryParse(net, subnet, error)) return InitError(error); - connOptions.vWhitelistedRange.push_back(subnet); + if (!NetWhitelistPermissions::TryParse(net, subnet, connection_direction, error)) return InitError(error); + if (connection_direction & ConnectionDirection::In) { + connOptions.vWhitelistedRangeIncoming.push_back(subnet); + } + if (connection_direction & ConnectionDirection::Out) { + connOptions.vWhitelistedRangeOutgoing.push_back(subnet); + } } connOptions.vSeedNodes = args.GetArgs("-seednode"); diff --git a/src/net.cpp b/src/net.cpp index 64f4620eff3e8..c7b851d59a3a6 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -519,6 +519,10 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo return nullptr; } + NetPermissionFlags permission_flags = NetPermissionFlags::None; + std::vector whitelist_permissions = conn_type == ConnectionType::MANUAL ? vWhitelistedRangeOutgoing : std::vector{}; + AddWhitelistPermissionFlags(permission_flags, addrConnect, whitelist_permissions); + // Add node NodeId id = GetNewNodeId(); uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize(); @@ -535,6 +539,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo conn_type, /*inbound_onion=*/false, CNodeOptions{ + .permission_flags = permission_flags, .i2p_sam_session = std::move(i2p_transient_session), .recv_flood_size = nReceiveFloodSize, .use_v2transport = use_v2transport, @@ -1735,7 +1740,7 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr&& sock, { int nInbound = 0; - AddWhitelistPermissionFlags(permission_flags, addr, vWhitelistedRange); + AddWhitelistPermissionFlags(permission_flags, addr, vWhitelistedRangeIncoming); { LOCK(m_nodes_mutex); diff --git a/src/net.h b/src/net.h index c491c47122ca5..46d9422695263 100644 --- a/src/net.h +++ b/src/net.h @@ -1048,7 +1048,8 @@ class CConnman uint64_t nMaxOutboundLimit = 0; int64_t m_peer_connect_timeout = DEFAULT_PEER_CONNECT_TIMEOUT; std::vector vSeedNodes; - std::vector vWhitelistedRange; + std::vector vWhitelistedRangeIncoming; + std::vector vWhitelistedRangeOutgoing; std::vector vWhiteBinds; std::vector vBinds; std::vector onion_binds; @@ -1084,7 +1085,8 @@ class CConnman LOCK(m_total_bytes_sent_mutex); nMaxOutboundLimit = connOptions.nMaxOutboundLimit; } - vWhitelistedRange = connOptions.vWhitelistedRange; + vWhitelistedRangeIncoming = connOptions.vWhitelistedRangeIncoming; + vWhitelistedRangeOutgoing = connOptions.vWhitelistedRangeOutgoing; { LOCK(m_added_nodes_mutex); // Attempt v2 connection if we support v2 - we'll reconnect with v1 if our @@ -1397,7 +1399,9 @@ class CConnman // Whitelisted ranges. Any node connecting from these is automatically // whitelisted (as well as those connecting to whitelisted binds). - std::vector vWhitelistedRange; + std::vector vWhitelistedRangeIncoming; + // Whitelisted ranges for outgoing connections. + std::vector vWhitelistedRangeOutgoing; unsigned int nSendBufferMaxSize{0}; unsigned int nReceiveFloodSize{0}; diff --git a/src/net_permissions.cpp b/src/net_permissions.cpp index a134a55264739..b01b2f643d3fa 100644 --- a/src/net_permissions.cpp +++ b/src/net_permissions.cpp @@ -21,9 +21,10 @@ const std::vector NET_PERMISSIONS_DOC{ namespace { // Parse the following format: "perm1,perm2@xxxxxx" -bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output, size_t& readen, bilingual_str& error) +static bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output, ConnectionDirection* output_connection_direction, size_t& readen, bilingual_str& error) { NetPermissionFlags flags = NetPermissionFlags::None; + ConnectionDirection connection_direction = ConnectionDirection::None; const auto atSeparator = str.find('@'); // if '@' is not found (ie, "xxxxx"), the caller should apply implicit permissions @@ -52,6 +53,15 @@ bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output, else if (permission == "all") NetPermissions::AddFlag(flags, NetPermissionFlags::All); else if (permission == "relay") NetPermissions::AddFlag(flags, NetPermissionFlags::Relay); else if (permission == "addr") NetPermissions::AddFlag(flags, NetPermissionFlags::Addr); + else if (permission == "in") connection_direction |= ConnectionDirection::In; + else if (permission == "out") { + if (output_connection_direction == nullptr) { + // Only NetWhitebindPermissions() should pass a nullptr. + error = _("whitebind may only be used for incoming connections (\"out\" was passed)"); + return false; + } + connection_direction |= ConnectionDirection::Out; + } else if (permission.length() == 0); // Allow empty entries else { error = strprintf(_("Invalid P2P permission: '%s'"), permission); @@ -61,7 +71,16 @@ bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output, readen++; } + // By default, whitelist only applies to incoming connections + if (connection_direction == ConnectionDirection::None) { + connection_direction = ConnectionDirection::In; + } else if (flags == NetPermissionFlags::None) { + error = strprintf(_("Only direction was set, no permissions: '%s'"), str); + return false; + } + output = flags; + if (output_connection_direction) *output_connection_direction = connection_direction; error = Untranslated(""); return true; } @@ -85,7 +104,7 @@ bool NetWhitebindPermissions::TryParse(const std::string& str, NetWhitebindPermi { NetPermissionFlags flags; size_t offset; - if (!TryParsePermissionFlags(str, flags, offset, error)) return false; + if (!TryParsePermissionFlags(str, flags, /*output_connection_direction=*/nullptr, offset, error)) return false; const std::string strBind = str.substr(offset); const std::optional addrBind{Lookup(strBind, 0, false)}; @@ -104,11 +123,12 @@ bool NetWhitebindPermissions::TryParse(const std::string& str, NetWhitebindPermi return true; } -bool NetWhitelistPermissions::TryParse(const std::string& str, NetWhitelistPermissions& output, bilingual_str& error) +bool NetWhitelistPermissions::TryParse(const std::string& str, NetWhitelistPermissions& output, ConnectionDirection& output_connection_direction, bilingual_str& error) { NetPermissionFlags flags; size_t offset; - if (!TryParsePermissionFlags(str, flags, offset, error)) return false; + // Only NetWhitebindPermissions should pass a nullptr for output_connection_direction. + if (!TryParsePermissionFlags(str, flags, &output_connection_direction, offset, error)) return false; const std::string net = str.substr(offset); const CSubNet subnet{LookupSubNet(net)}; diff --git a/src/net_permissions.h b/src/net_permissions.h index a61eddc121bcc..33babd62046e3 100644 --- a/src/net_permissions.h +++ b/src/net_permissions.h @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include #include @@ -88,7 +89,7 @@ class NetWhitebindPermissions : public NetPermissions class NetWhitelistPermissions : public NetPermissions { public: - static bool TryParse(const std::string& str, NetWhitelistPermissions& output, bilingual_str& error); + static bool TryParse(const std::string& str, NetWhitelistPermissions& output, ConnectionDirection& output_connection_direction, bilingual_str& error); CSubNet m_subnet; }; diff --git a/src/test/fuzz/net_permissions.cpp b/src/test/fuzz/net_permissions.cpp index ae343602e90af..1135d1f1d3b30 100644 --- a/src/test/fuzz/net_permissions.cpp +++ b/src/test/fuzz/net_permissions.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include #include #include @@ -31,8 +32,9 @@ FUZZ_TARGET(net_permissions) } NetWhitelistPermissions net_whitelist_permissions; + ConnectionDirection connection_direction; bilingual_str error_net_whitelist_permissions; - if (NetWhitelistPermissions::TryParse(s, net_whitelist_permissions, error_net_whitelist_permissions)) { + if (NetWhitelistPermissions::TryParse(s, net_whitelist_permissions, connection_direction, error_net_whitelist_permissions)) { (void)NetPermissions::ToStrings(net_whitelist_permissions.m_flags); (void)NetPermissions::AddFlag(net_whitelist_permissions.m_flags, net_permission_flags); assert(NetPermissions::HasFlag(net_whitelist_permissions.m_flags, net_permission_flags)); diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index fa70f62eb46dd..3422cb8023321 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -366,6 +366,7 @@ BOOST_AUTO_TEST_CASE(netpermissions_test) bilingual_str error; NetWhitebindPermissions whitebindPermissions; NetWhitelistPermissions whitelistPermissions; + ConnectionDirection connection_direction; // Detect invalid white bind BOOST_CHECK(!NetWhitebindPermissions::TryParse("", whitebindPermissions, error)); @@ -435,24 +436,33 @@ BOOST_AUTO_TEST_CASE(netpermissions_test) BOOST_CHECK(NetWhitebindPermissions::TryParse(",,@1.2.3.4:32", whitebindPermissions, error)); BOOST_CHECK_EQUAL(whitebindPermissions.m_flags, NetPermissionFlags::None); + BOOST_CHECK(!NetWhitebindPermissions::TryParse("out,forcerelay@1.2.3.4:32", whitebindPermissions, error)); + BOOST_CHECK(error.original.find("whitebind may only be used for incoming connections (\"out\" was passed)") != std::string::npos); + // Detect invalid flag BOOST_CHECK(!NetWhitebindPermissions::TryParse("bloom,forcerelay,oopsie@1.2.3.4:32", whitebindPermissions, error)); BOOST_CHECK(error.original.find("Invalid P2P permission") != std::string::npos); // Check netmask error - BOOST_CHECK(!NetWhitelistPermissions::TryParse("bloom,forcerelay,noban@1.2.3.4:32", whitelistPermissions, error)); + BOOST_CHECK(!NetWhitelistPermissions::TryParse("bloom,forcerelay,noban@1.2.3.4:32", whitelistPermissions, connection_direction, error)); BOOST_CHECK(error.original.find("Invalid netmask specified in -whitelist") != std::string::npos); // Happy path for whitelist parsing - BOOST_CHECK(NetWhitelistPermissions::TryParse("noban@1.2.3.4", whitelistPermissions, error)); + BOOST_CHECK(NetWhitelistPermissions::TryParse("noban@1.2.3.4", whitelistPermissions, connection_direction, error)); BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, NetPermissionFlags::NoBan); BOOST_CHECK(NetPermissions::HasFlag(whitelistPermissions.m_flags, NetPermissionFlags::NoBan)); - BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay@1.2.3.4/32", whitelistPermissions, error)); + BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay@1.2.3.4/32", whitelistPermissions, connection_direction, error)); BOOST_CHECK_EQUAL(whitelistPermissions.m_flags, NetPermissionFlags::BloomFilter | NetPermissionFlags::ForceRelay | NetPermissionFlags::NoBan | NetPermissionFlags::Relay); BOOST_CHECK(error.empty()); BOOST_CHECK_EQUAL(whitelistPermissions.m_subnet.ToString(), "1.2.3.4/32"); - BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay,mempool@1.2.3.4/32", whitelistPermissions, error)); + BOOST_CHECK(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay,mempool@1.2.3.4/32", whitelistPermissions, connection_direction, error)); + BOOST_CHECK(NetWhitelistPermissions::TryParse("in,relay@1.2.3.4", whitelistPermissions, connection_direction, error)); + BOOST_CHECK_EQUAL(connection_direction, ConnectionDirection::In); + BOOST_CHECK(NetWhitelistPermissions::TryParse("out,bloom@1.2.3.4", whitelistPermissions, connection_direction, error)); + BOOST_CHECK_EQUAL(connection_direction, ConnectionDirection::Out); + BOOST_CHECK(NetWhitelistPermissions::TryParse("in,out,bloom@1.2.3.4", whitelistPermissions, connection_direction, error)); + BOOST_CHECK_EQUAL(connection_direction, ConnectionDirection::Both); const auto strings = NetPermissions::ToStrings(NetPermissionFlags::All); BOOST_CHECK_EQUAL(strings.size(), 7U); From c985eb854cc86deb747caea5283c17cf51b6a983 Mon Sep 17 00:00:00 2001 From: brunoerg Date: Tue, 14 Mar 2023 10:18:47 -0300 Subject: [PATCH 5/7] test: add option to speed up tx relay/mempool sync when `self.noban_tx_relay=True`, the following flag `-whitelist=noban,in,out@127.0.0.1`is added to `extra_args` to speed up tx relay/mempool sync. --- test/functional/feature_cltv.py | 3 ++- test/functional/feature_csv_activation.py | 3 ++- test/functional/feature_dersig.py | 3 ++- test/functional/feature_fee_estimation.py | 9 +++++---- test/functional/interface_rest.py | 3 +-- test/functional/interface_zmq.py | 8 +++----- test/functional/mempool_packages.py | 3 ++- test/functional/p2p_feefilter.py | 6 +++--- test/functional/p2p_filter.py | 3 ++- test/functional/p2p_invalid_block.py | 3 ++- test/functional/p2p_segwit.py | 4 +++- test/functional/rpc_packages.py | 3 ++- test/functional/rpc_rawtransaction.py | 5 ++--- test/functional/test_framework/test_framework.py | 5 +++++ test/functional/wallet_abandonconflict.py | 3 +-- test/functional/wallet_address_types.py | 5 ++--- test/functional/wallet_avoid_mixing_output_types.py | 4 ++-- test/functional/wallet_avoidreuse.py | 5 ++--- test/functional/wallet_backup.py | 13 +++++++------ test/functional/wallet_balance.py | 5 ++--- test/functional/wallet_basic.py | 4 +++- test/functional/wallet_bumpfee.py | 3 ++- test/functional/wallet_fundrawtransaction.py | 5 ++--- test/functional/wallet_groups.py | 3 ++- test/functional/wallet_hd.py | 3 +-- test/functional/wallet_import_rescan.py | 4 +++- test/functional/wallet_importdescriptors.py | 5 ++--- test/functional/wallet_listreceivedby.py | 2 +- test/functional/wallet_listsinceblock.py | 2 +- test/functional/wallet_listtransactions.py | 6 +++--- test/functional/wallet_send.py | 7 ++++--- 31 files changed, 76 insertions(+), 64 deletions(-) diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py index 8c45fb5a4d07c..fb3f6622719e1 100755 --- a/test/functional/feature_cltv.py +++ b/test/functional/feature_cltv.py @@ -83,9 +83,10 @@ def cltv_validate(tx, height): class BIP65Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [[ f'-testactivationheight=cltv@{CLTV_HEIGHT}', - '-whitelist=noban@127.0.0.1', '-par=1', # Use only one script thread to get the exact reject reason for testing '-acceptnonstdtxn=1', # cltv_invalidate is nonstandard ]] diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py index 92e4187f3cd1f..bc1f9e8f2f211 100755 --- a/test/functional/feature_csv_activation.py +++ b/test/functional/feature_csv_activation.py @@ -95,8 +95,9 @@ class BIP68_112_113Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [[ - '-whitelist=noban@127.0.0.1', f'-testactivationheight=csv@{CSV_ACTIVATION_HEIGHT}', '-par=1', # Use only one script thread to get the exact reject reason for testing ]] diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py index 44c12b2a59b64..035e7151cad39 100755 --- a/test/functional/feature_dersig.py +++ b/test/functional/feature_dersig.py @@ -47,9 +47,10 @@ def unDERify(tx): class BIP66Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [[ f'-testactivationheight=dersig@{DERSIG_HEIGHT}', - '-whitelist=noban@127.0.0.1', '-par=1', # Use only one script thread to get the exact log msg for testing ]] self.setup_clean_chain = True diff --git a/test/functional/feature_fee_estimation.py b/test/functional/feature_fee_estimation.py index 4f56d585d3f69..ffc87f8b8bad0 100755 --- a/test/functional/feature_fee_estimation.py +++ b/test/functional/feature_fee_estimation.py @@ -132,11 +132,12 @@ def make_tx(wallet, utxo, feerate): class EstimateFeeTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 3 - # Force fSendTrickle to true (via whitelist.noban) + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [ - ["-whitelist=noban@127.0.0.1"], - ["-whitelist=noban@127.0.0.1", "-blockmaxweight=68000"], - ["-whitelist=noban@127.0.0.1", "-blockmaxweight=32000"], + [], + ["-blockmaxweight=68000"], + ["-blockmaxweight=32000"], ] def setup_network(self): diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py index b81eae25064d3..e9b513459f35d 100755 --- a/test/functional/interface_rest.py +++ b/test/functional/interface_rest.py @@ -53,8 +53,7 @@ def set_test_params(self): self.num_nodes = 2 self.extra_args = [["-rest", "-blockfilterindex=1"], []] # whitelist peers to speed up tx relay / mempool sync - for args in self.extra_args: - args.append("-whitelist=noban@127.0.0.1") + self.noban_tx_relay = True self.supports_cli = False def test_rest_request( diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py index 2358dd4387358..6fe088c2b0644 100755 --- a/test/functional/interface_zmq.py +++ b/test/functional/interface_zmq.py @@ -104,9 +104,8 @@ def caused_notification(self, notification): class ZMQTest (BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 - # This test isn't testing txn relay/timing, so set whitelist on the - # peers for instant txn relay. This speeds up the test run time 2-3x. - self.extra_args = [["-whitelist=noban@127.0.0.1"]] * self.num_nodes + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.zmq_port_base = p2p_port(self.num_nodes + 1) def skip_test_if_missing_module(self): @@ -138,8 +137,7 @@ def setup_zmq_test(self, services, *, recv_timeout=60, sync_blocks=True, ipv6=Fa socket.setsockopt(zmq.IPV6, 1) subscribers.append(ZMQSubscriber(socket, topic.encode())) - self.restart_node(0, [f"-zmqpub{topic}={address}" for topic, address in services] + - self.extra_args[0]) + self.restart_node(0, [f"-zmqpub{topic}={address}" for topic, address in services]) for i, sub in enumerate(subscribers): sub.socket.connect(services[i][1]) diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py index 95f7939412f07..dcb66b2ca1add 100755 --- a/test/functional/mempool_packages.py +++ b/test/functional/mempool_packages.py @@ -27,10 +27,11 @@ class MempoolPackagesTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [ [ "-maxorphantx=1000", - "-whitelist=noban@127.0.0.1", # immediate tx relay ], [ "-maxorphantx=1000", diff --git a/test/functional/p2p_feefilter.py b/test/functional/p2p_feefilter.py index 6b03cdf8775fd..bcba534f9a541 100755 --- a/test/functional/p2p_feefilter.py +++ b/test/functional/p2p_feefilter.py @@ -46,16 +46,16 @@ def clear_invs(self): class FeeFilterTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True # We lower the various required feerates for this test # to catch a corner-case where feefilter used to slightly undercut # mempool and wallet feerate calculation based on GetFee # rounding down 3 places, leading to stranded transactions. # See issue #16499 - # grant noban permission to all peers to speed up tx relay / mempool sync self.extra_args = [[ "-minrelaytxfee=0.00000100", - "-mintxfee=0.00000100", - "-whitelist=noban@127.0.0.1", + "-mintxfee=0.00000100" ]] * self.num_nodes def run_test(self): diff --git a/test/functional/p2p_filter.py b/test/functional/p2p_filter.py index 62d55cc101929..7c8ed58e51c73 100755 --- a/test/functional/p2p_filter.py +++ b/test/functional/p2p_filter.py @@ -94,9 +94,10 @@ def merkleblock_received(self, value): class FilterTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [[ '-peerbloomfilters', - '-whitelist=noban@127.0.0.1', # immediate tx relay ]] def generatetoscriptpubkey(self, scriptpubkey): diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py index 806fd9c6cbefd..8ec62ae5eefe2 100755 --- a/test/functional/p2p_invalid_block.py +++ b/test/functional/p2p_invalid_block.py @@ -32,7 +32,8 @@ class InvalidBlockRequestTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True - self.extra_args = [["-whitelist=noban@127.0.0.1"]] + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True def run_test(self): # Add p2p connection to node0 diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py index d316c4b602fa9..1c0c11d74c80a 100755 --- a/test/functional/p2p_segwit.py +++ b/test/functional/p2p_segwit.py @@ -213,9 +213,11 @@ class SegWitTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True # This test tests SegWit both pre and post-activation, so use the normal BIP9 activation. self.extra_args = [ - ["-acceptnonstdtxn=1", f"-testactivationheight=segwit@{SEGWIT_HEIGHT}", "-whitelist=noban@127.0.0.1", "-par=1"], + ["-acceptnonstdtxn=1", f"-testactivationheight=segwit@{SEGWIT_HEIGHT}", "-par=1"], ["-acceptnonstdtxn=0", f"-testactivationheight=segwit@{SEGWIT_HEIGHT}"], ] self.supports_cli = False diff --git a/test/functional/rpc_packages.py b/test/functional/rpc_packages.py index 664f2df3f19a0..3cd8f2fc11971 100755 --- a/test/functional/rpc_packages.py +++ b/test/functional/rpc_packages.py @@ -29,7 +29,8 @@ class RPCPackagesTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True - self.extra_args = [["-whitelist=noban@127.0.0.1"]] # noban speeds up tx relay + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True def assert_testres_equal(self, package_hex, testres_expected): """Shuffle package_hex and assert that the testmempoolaccept result matches testres_expected. This should only diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py index c12865b5e39b6..12697e9d0c3c1 100755 --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -73,9 +73,8 @@ def set_test_params(self): ["-txindex"], ["-fastprune", "-prune=1"], ] - # whitelist all peers to speed up tx relay / mempool sync - for args in self.extra_args: - args.append("-whitelist=noban@127.0.0.1") + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.supports_cli = False def setup_network(self): diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index d8ae20981da67..4f043084659d1 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -96,6 +96,7 @@ def __init__(self) -> None: """Sets test framework defaults. Do not override this method. Instead, override the set_test_params() method""" self.chain: str = 'regtest' self.setup_clean_chain: bool = False + self.noban_tx_relay: bool = False self.nodes: list[TestNode] = [] self.extra_args = None self.network_thread = None @@ -494,6 +495,10 @@ def get_bin_from_version(version, bin_name, bin_default): extra_confs = [[]] * num_nodes if extra_args is None: extra_args = [[]] * num_nodes + # Whitelist peers to speed up tx relay / mempool sync. Don't use it if testing tx relay or timing. + if self.noban_tx_relay: + for i in range(len(extra_args)): + extra_args[i] = extra_args[i] + ["-whitelist=noban,in,out@127.0.0.1"] if versions is None: versions = [None] * num_nodes if binary is None: diff --git a/test/functional/wallet_abandonconflict.py b/test/functional/wallet_abandonconflict.py index 26915077736d5..e69546bb821a6 100755 --- a/test/functional/wallet_abandonconflict.py +++ b/test/functional/wallet_abandonconflict.py @@ -28,8 +28,7 @@ def set_test_params(self): self.num_nodes = 2 self.extra_args = [["-minrelaytxfee=0.00001"], []] # whitelist peers to speed up tx relay / mempool sync - for args in self.extra_args: - args.append("-whitelist=noban@127.0.0.1") + self.noban_tx_relay = True def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py index be5b3ebadbaea..6b27b32dea023 100755 --- a/test/functional/wallet_address_types.py +++ b/test/functional/wallet_address_types.py @@ -79,9 +79,8 @@ def set_test_params(self): ["-changetype=p2sh-segwit"], [], ] - # whitelist all peers to speed up tx relay / mempool sync - for args in self.extra_args: - args.append("-whitelist=noban@127.0.0.1") + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.supports_cli = False def skip_test_if_missing_module(self): diff --git a/test/functional/wallet_avoid_mixing_output_types.py b/test/functional/wallet_avoid_mixing_output_types.py index 861765f452ba7..66fbf780e5683 100755 --- a/test/functional/wallet_avoid_mixing_output_types.py +++ b/test/functional/wallet_avoid_mixing_output_types.py @@ -112,15 +112,15 @@ def add_options(self, parser): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [ [ "-addresstype=bech32", - "-whitelist=noban@127.0.0.1", "-txindex", ], [ "-addresstype=p2sh-segwit", - "-whitelist=noban@127.0.0.1", "-txindex", ], ] diff --git a/test/functional/wallet_avoidreuse.py b/test/functional/wallet_avoidreuse.py index 9d3c55d6b66fa..4983bfda7f052 100755 --- a/test/functional/wallet_avoidreuse.py +++ b/test/functional/wallet_avoidreuse.py @@ -69,9 +69,8 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 2 - # This test isn't testing txn relay/timing, so set whitelist on the - # peers for instant txn relay. This speeds up the test run time 2-3x. - self.extra_args = [["-whitelist=noban@127.0.0.1"]] * self.num_nodes + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py index eb3e0ae7280e7..d03b08bcc40bb 100755 --- a/test/functional/wallet_backup.py +++ b/test/functional/wallet_backup.py @@ -50,13 +50,14 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 4 self.setup_clean_chain = True - # nodes 1, 2,3 are spenders, let's give them a keypool=100 - # whitelist all peers to speed up tx relay / mempool sync + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True + # nodes 1, 2, 3 are spenders, let's give them a keypool=100 self.extra_args = [ - ["-whitelist=noban@127.0.0.1", "-keypool=100"], - ["-whitelist=noban@127.0.0.1", "-keypool=100"], - ["-whitelist=noban@127.0.0.1", "-keypool=100"], - ["-whitelist=noban@127.0.0.1"], + ["-keypool=100"], + ["-keypool=100"], + ["-keypool=100"], + [], ] self.rpc_timeout = 120 diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py index af9270a321992..c322ae52c1cd0 100755 --- a/test/functional/wallet_balance.py +++ b/test/functional/wallet_balance.py @@ -53,15 +53,14 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [ # Limit mempool descendants as a hack to have wallet txs rejected from the mempool. # Set walletrejectlongchains=0 so the wallet still creates the transactions. ['-limitdescendantcount=3', '-walletrejectlongchains=0'], [], ] - # whitelist peers to speed up tx relay / mempool sync - for args in self.extra_args: - args.append("-whitelist=noban@127.0.0.1") def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py index f798eee365cfb..31d3c14e55bcc 100755 --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -32,8 +32,10 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 4 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [[ - "-dustrelayfee=0", "-walletrejectlongchains=0", "-whitelist=noban@127.0.0.1" + "-dustrelayfee=0", "-walletrejectlongchains=0" ]] * self.num_nodes self.setup_clean_chain = True self.supports_cli = False diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py index fea933a93b2b8..5b7db55f4553e 100755 --- a/test/functional/wallet_bumpfee.py +++ b/test/functional/wallet_bumpfee.py @@ -55,11 +55,12 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 2 self.setup_clean_chain = True + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [[ "-walletrbf={}".format(i), "-mintxfee=0.00002", "-addresstype=bech32", - "-whitelist=noban@127.0.0.1", ] for i in range(self.num_nodes)] def skip_test_if_missing_module(self): diff --git a/test/functional/wallet_fundrawtransaction.py b/test/functional/wallet_fundrawtransaction.py index d886a59ac15bb..ff4648e638e47 100755 --- a/test/functional/wallet_fundrawtransaction.py +++ b/test/functional/wallet_fundrawtransaction.py @@ -45,9 +45,8 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 4 self.setup_clean_chain = True - # This test isn't testing tx relay. Set whitelist on the peers for - # instant tx relay. - self.extra_args = [['-whitelist=noban@127.0.0.1']] * self.num_nodes + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.rpc_timeout = 90 # to prevent timeouts in `test_transaction_too_large` def skip_test_if_missing_module(self): diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py index bdb9081261a14..3b407c285d4cf 100755 --- a/test/functional/wallet_groups.py +++ b/test/functional/wallet_groups.py @@ -22,6 +22,8 @@ def add_options(self, parser): def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 5 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [ [], [], @@ -31,7 +33,6 @@ def set_test_params(self): ] for args in self.extra_args: - args.append("-whitelist=noban@127.0.0.1") # whitelist peers to speed up tx relay / mempool sync args.append(f"-paytxfee={20 * 1e3 / 1e8}") # apply feerate of 20 sats/vB across all nodes self.rpc_timeout = 480 diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py index 0f4b7cfcb1f58..52161043eacaf 100755 --- a/test/functional/wallet_hd.py +++ b/test/functional/wallet_hd.py @@ -23,8 +23,7 @@ def set_test_params(self): self.num_nodes = 2 self.extra_args = [[], ['-keypool=0']] # whitelist peers to speed up tx relay / mempool sync - for args in self.extra_args: - args.append("-whitelist=noban@127.0.0.1") + self.noban_tx_relay = True self.supports_cli = False diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py index e647fb2d5c224..2a9435b37060f 100755 --- a/test/functional/wallet_import_rescan.py +++ b/test/functional/wallet_import_rescan.py @@ -160,6 +160,8 @@ def set_test_params(self): self.num_nodes = 2 + len(IMPORT_NODES) self.supports_cli = False self.rpc_timeout = 120 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True def skip_test_if_missing_module(self): self.skip_if_no_wallet() @@ -177,7 +179,7 @@ def setup_network(self): self.import_deterministic_coinbase_privkeys() self.stop_nodes() - self.start_nodes(extra_args=[["-whitelist=noban@127.0.0.1"]] * self.num_nodes) + self.start_nodes() for i in range(1, self.num_nodes): self.connect_nodes(i, 0) diff --git a/test/functional/wallet_importdescriptors.py b/test/functional/wallet_importdescriptors.py index 1f1f92589cedc..420bdffc49461 100755 --- a/test/functional/wallet_importdescriptors.py +++ b/test/functional/wallet_importdescriptors.py @@ -36,12 +36,11 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 2 + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [["-addresstype=legacy"], ["-addresstype=bech32", "-keypool=5"] ] - # whitelist peers to speed up tx relay / mempool sync - for args in self.extra_args: - args.append("-whitelist=noban@127.0.0.1") self.setup_clean_chain = True self.wallet_names = [] diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py index 8ec21484d1caa..d0f1336a5ebca 100755 --- a/test/functional/wallet_listreceivedby.py +++ b/test/functional/wallet_listreceivedby.py @@ -22,7 +22,7 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 2 # whitelist peers to speed up tx relay / mempool sync - self.extra_args = [["-whitelist=noban@127.0.0.1"]] * self.num_nodes + self.noban_tx_relay = True def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py index a19a3ac2cbadf..fd586d546ef81 100755 --- a/test/functional/wallet_listsinceblock.py +++ b/test/functional/wallet_listsinceblock.py @@ -26,7 +26,7 @@ def set_test_params(self): self.num_nodes = 4 self.setup_clean_chain = True # whitelist peers to speed up tx relay / mempool sync - self.extra_args = [["-whitelist=noban@127.0.0.1"]] * self.num_nodes + self.noban_tx_relay = True def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py index 064ce12108878..c820eaa6f6090 100755 --- a/test/functional/wallet_listtransactions.py +++ b/test/functional/wallet_listtransactions.py @@ -26,9 +26,9 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 3 - # This test isn't testing txn relay/timing, so set whitelist on the - # peers for instant txn relay. This speeds up the test run time 2-3x. - self.extra_args = [["-whitelist=noban@127.0.0.1", "-walletrbf=0"]] * self.num_nodes + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True + self.extra_args = [["-walletrbf=0"]] * self.num_nodes def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py index 6ce2a56bfcbbc..4d1b080be4912 100755 --- a/test/functional/wallet_send.py +++ b/test/functional/wallet_send.py @@ -30,10 +30,11 @@ def add_options(self, parser): def set_test_params(self): self.num_nodes = 2 - # whitelist all peers to speed up tx relay / mempool sync + # whitelist peers to speed up tx relay / mempool sync + self.noban_tx_relay = True self.extra_args = [ - ["-whitelist=127.0.0.1","-walletrbf=1"], - ["-whitelist=127.0.0.1","-walletrbf=1"], + ["-walletrbf=1"], + ["-walletrbf=1"] ] getcontext().prec = 8 # Satoshi precision for Decimal From e6b8f19de9a6d1c477d0bbda18d17794cd81a6f4 Mon Sep 17 00:00:00 2001 From: brunoerg Date: Mon, 7 Aug 2023 17:57:18 -0300 Subject: [PATCH 6/7] test: add coverage for whitelisting manual connections --- test/functional/p2p_permissions.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/functional/p2p_permissions.py b/test/functional/p2p_permissions.py index 6153e4a1566b8..80a27943fdfdc 100755 --- a/test/functional/p2p_permissions.py +++ b/test/functional/p2p_permissions.py @@ -83,7 +83,14 @@ def run_test(self): ["-whitelist=all@127.0.0.1"], ["forcerelay", "noban", "mempool", "bloomfilter", "relay", "download", "addr"]) + for flag, permissions in [(["-whitelist=noban,out@127.0.0.1"], ["noban", "download"]), (["-whitelist=noban@127.0.0.1"], [])]: + self.restart_node(0, flag) + self.connect_nodes(0, 1) + peerinfo = self.nodes[0].getpeerinfo()[0] + assert_equal(peerinfo['permissions'], permissions) + self.stop_node(1) + self.nodes[1].assert_start_raises_init_error(["-whitelist=in,out@127.0.0.1"], "Only direction was set, no permissions", match=ErrorMatch.PARTIAL_REGEX) self.nodes[1].assert_start_raises_init_error(["-whitelist=oopsie@127.0.0.1"], "Invalid P2P permission", match=ErrorMatch.PARTIAL_REGEX) self.nodes[1].assert_start_raises_init_error(["-whitelist=noban@127.0.0.1:230"], "Invalid netmask specified in", match=ErrorMatch.PARTIAL_REGEX) self.nodes[1].assert_start_raises_init_error(["-whitebind=noban@127.0.0.1/10"], "Cannot resolve -whitebind address", match=ErrorMatch.PARTIAL_REGEX) From 0a533613fb44207053796fd01a9f4b523a3153d4 Mon Sep 17 00:00:00 2001 From: brunoerg Date: Thu, 19 Oct 2023 17:53:29 -0300 Subject: [PATCH 7/7] docs: add release notes for #27114 --- doc/release-notes-27114.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 doc/release-notes-27114.md diff --git a/doc/release-notes-27114.md b/doc/release-notes-27114.md new file mode 100644 index 0000000000000..980ffd78a44f2 --- /dev/null +++ b/doc/release-notes-27114.md @@ -0,0 +1,2 @@ +- Additional flags "in" and "out" have been added to `-whitelist` to control whether + permissions apply to incoming connections and/or manual (default: incoming only). \ No newline at end of file