diff --git a/src/init.cpp b/src/init.cpp index 2a3bea1372..c5bc3b96d6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1781,10 +1781,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); } @@ -1828,9 +1831,16 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) NetWhitelistPermissions subnet; bilingual_str error; if (!NetWhitelistPermissions::TryParse(net, subnet, error)) return InitError(error); + NetPermissions::AddFlag(all_permission_flags, subnet.m_flags); connOptions.vWhitelistedRange.push_back(subnet); } + 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.cpp b/src/net.cpp index 866b31879f..187dd81ad6 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1052,6 +1052,9 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr&& sock, if (NetPermissions::HasFlag(permission_flags, NetPermissionFlags::BloomFilter)) { nodeServices = static_cast(nodeServices | NODE_BLOOM); } + if (NetPermissions::HasFlag(permission_flags, NetPermissionFlags::BlockFilters)) { + nodeServices = static_cast(nodeServices | NODE_COMPACT_FILTERS); + } const bool inbound_onion = std::find(m_onion_binds.begin(), m_onion_binds.end(), addr_bind) != m_onion_binds.end(); CNode* pnode = new CNode(id, diff --git a/src/net_permissions.cpp b/src/net_permissions.cpp index f829e56aa2..a795ea4983 100644 --- a/src/net_permissions.cpp +++ b/src/net_permissions.cpp @@ -10,6 +10,7 @@ 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)", @@ -45,6 +46,7 @@ bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output, 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); @@ -71,6 +73,7 @@ bool TryParsePermissionFlags(const std::string& str, NetPermissionFlags& output, std::vector NetPermissions::ToStrings(NetPermissionFlags flags) { std::vector strings; + if (NetPermissions::HasFlag(flags, NetPermissionFlags::BlockFilters)) strings.push_back("blockfilters"); if (NetPermissions::HasFlag(flags, NetPermissionFlags::BloomFilter)) strings.push_back("bloomfilter"); if (NetPermissions::HasFlag(flags, NetPermissionFlags::NoBan)) strings.push_back("noban"); if (NetPermissions::HasFlag(flags, NetPermissionFlags::ForceRelay)) strings.push_back("forcerelay"); diff --git a/src/net_permissions.h b/src/net_permissions.h index b7f3bffe1c..38e528e1dd 100644 --- a/src/net_permissions.h +++ b/src/net_permissions.h @@ -35,10 +35,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/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 7e91819ddc..7ae8c8287f 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(NetWhitelistPermissions::TryParse("bloom,forcerelay,noban,relay,mempool@1.2.3.4/32", whitelistPermissions, error)); 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 f84bbf67e6..8b749d0f6c 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", + ]) self.stop_node(1) self.nodes[1].assert_start_raises_init_error(["-whitelist=oopsie@127.0.0.1"], "Invalid P2P permission", match=ErrorMatch.PARTIAL_REGEX)