diff --git a/src/init.cpp b/src/init.cpp index 89cea408d7..0085e5f6fe 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1897,10 +1897,13 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) return InitError(ResolveErrMsg("bind", bind_arg)); } + NetPermissionFlags all_permission_flags{NetPermissionFlags::None}; + for (const std::string& strBind : args.GetArgs("-whitebind")) { NetWhitebindPermissions whitebind; bilingual_str error; if (!NetWhitebindPermissions::TryParse(strBind, whitebind, error)) return InitError(error); + NetPermissions::AddFlag(all_permission_flags, whitebind.m_flags); connOptions.vWhiteBinds.push_back(whitebind); } @@ -1947,6 +1950,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) ConnectionDirection connection_direction; bilingual_str error; if (!NetWhitelistPermissions::TryParse(net, subnet, connection_direction, error)) return InitError(error); + NetPermissions::AddFlag(all_permission_flags, subnet.m_flags); if (connection_direction & ConnectionDirection::In) { connOptions.vWhitelistedRangeIncoming.push_back(subnet); } @@ -1955,6 +1959,12 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } } + if (NetPermissions::HasFlag(all_permission_flags, NetPermissionFlags::BlockFilters_Explicit)) { + if (g_enabled_filter_types.count(BlockFilterType::BASIC) != 1) { + return InitError(_("Cannot grant blockfilters permission without -blockfilterindex.")); + } + } + connOptions.vSeedNodes = args.GetArgs("-seednode"); // Initiate outbound connections unless connect=0 diff --git a/src/net_permissions.cpp b/src/net_permissions.cpp index 8f0042c141..28054db825 100644 --- a/src/net_permissions.cpp +++ b/src/net_permissions.cpp @@ -12,6 +12,7 @@ using common::ResolveErrMsg; const std::vector NET_PERMISSIONS_DOC{ "bloomfilter (allow requesting BIP37 filtered blocks and transactions)", + "blockfilters (serve compact block filters to peers per BIP157)", "noban (do not ban for misbehavior; implies download)", "forcerelay (relay transactions that are already in the mempool; implies relay)", "relay (relay even in -blocksonly mode, and unlimited transaction announcements)", @@ -48,6 +49,7 @@ static bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& if (commaSeparator != std::string::npos) readen++; // We read "," if (permission == "bloomfilter" || permission == "bloom") NetPermissions::AddFlag(flags, NetPermissionFlags::BloomFilter); + else if (permission == "blockfilters" || permission == "compactfilters" || permission == "cfilters") NetPermissions::AddFlag(flags, NetPermissionFlags::BlockFilters_Explicit); else if (permission == "noban") NetPermissions::AddFlag(flags, NetPermissionFlags::NoBan); else if (permission == "forcerelay") NetPermissions::AddFlag(flags, NetPermissionFlags::ForceRelay); else if (permission == "mempool") NetPermissions::AddFlag(flags, NetPermissionFlags::Mempool); @@ -92,6 +94,7 @@ static bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& std::vector NetPermissions::ToStrings(NetPermissionFlags flags) { std::vector strings; + if (NetPermissions::HasFlag(flags, NetPermissionFlags::BlockFilters)) strings.emplace_back("blockfilters"); if (NetPermissions::HasFlag(flags, NetPermissionFlags::BloomFilter)) strings.emplace_back("bloomfilter"); if (NetPermissions::HasFlag(flags, NetPermissionFlags::NoBan)) strings.emplace_back("noban"); if (NetPermissions::HasFlag(flags, NetPermissionFlags::ForceRelay)) strings.emplace_back("forcerelay"); diff --git a/src/net_permissions.h b/src/net_permissions.h index 33babd6204..280cbbd559 100644 --- a/src/net_permissions.h +++ b/src/net_permissions.h @@ -41,10 +41,15 @@ enum class NetPermissionFlags : uint32_t { // unlimited amounts of addrs. Addr = (1U << 7), + // Can query compact filters even if -peerblockfilters is false + BlockFilters = (1U << 8), + // Used to avoid an error when All is used to set BlockFilters + BlockFilters_Explicit = BlockFilters | (1U << 9), + // True if the user did not specifically set fine-grained permissions with // the -whitebind or -whitelist configuration options. Implicit = (1U << 31), - All = BloomFilter | ForceRelay | Relay | NoBan | Mempool | Download | Addr, + All = BloomFilter | ForceRelay | Relay | NoBan | Mempool | Download | Addr | BlockFilters, }; static inline constexpr NetPermissionFlags operator|(NetPermissionFlags a, NetPermissionFlags b) { diff --git a/src/net_processing.cpp b/src/net_processing.cpp index b530c9bacd..24a12d34d2 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1741,6 +1741,9 @@ void PeerManagerImpl::InitializeNode(const CNode& node, ServiceFlags our_service if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BloomFilter)) { our_services = static_cast(our_services | NODE_BLOOM); } + if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BlockFilters)) { + our_services = static_cast(our_services | NODE_COMPACT_FILTERS); + } PeerRef peer = std::make_shared(nodeid, our_services); { diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 3422cb8023..50a2561fb8 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -465,7 +465,8 @@ BOOST_AUTO_TEST_CASE(netpermissions_test) BOOST_CHECK_EQUAL(connection_direction, ConnectionDirection::Both); const auto strings = NetPermissions::ToStrings(NetPermissionFlags::All); - BOOST_CHECK_EQUAL(strings.size(), 7U); + BOOST_CHECK_EQUAL(strings.size(), 8U); + BOOST_CHECK(std::find(strings.begin(), strings.end(), "blockfilters") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "bloomfilter") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "forcerelay") != strings.end()); BOOST_CHECK(std::find(strings.begin(), strings.end(), "relay") != strings.end()); diff --git a/test/functional/p2p_permissions.py b/test/functional/p2p_permissions.py index c881dd6ff4..98123d22b4 100755 --- a/test/functional/p2p_permissions.py +++ b/test/functional/p2p_permissions.py @@ -81,7 +81,16 @@ class P2PPermissionsTests(BitcoinTestFramework): self.checkpermission( # all permission added ["-whitelist=all@127.0.0.1"], - ["forcerelay", "noban", "mempool", "bloomfilter", "relay", "download", "addr"]) + [ + "blockfilters", + "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)