From 76f055d9099399ce0d0449218f6e116ac691add8 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 15 Nov 2019 05:36:24 +0000 Subject: [PATCH 1/4] net: Add blockfilters white{bind,list} permission flag --- src/init.cpp | 10 ++++++++++ src/net.cpp | 3 +++ src/net_permissions.cpp | 2 ++ src/net_permissions.h | 7 ++++++- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 1122496539..457480c7a6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1761,10 +1761,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); } @@ -1808,9 +1811,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 903fedb2fb..9d97f40d13 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1042,6 +1042,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..3295af99dd 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); 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) { From e529e00643740e8d7b0691bd3c7bc948f6a54bee Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 7 Jun 2020 22:48:26 +0000 Subject: [PATCH 2/4] Include "blockfilters" in NetPermissions::ToStrings as appropriate --- src/net_permissions.cpp | 1 + src/test/netbase_tests.cpp | 3 ++- test/functional/p2p_permissions.py | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/net_permissions.cpp b/src/net_permissions.cpp index 3295af99dd..a795ea4983 100644 --- a/src/net_permissions.cpp +++ b/src/net_permissions.cpp @@ -73,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/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..bbf1d923d2 100755 --- a/test/functional/p2p_permissions.py +++ b/test/functional/p2p_permissions.py @@ -81,7 +81,7 @@ 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) From 21a7f5ad0cbd835e7b2c5244599e5ad85d15ea2e Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Sun, 7 Jun 2020 22:52:06 +0000 Subject: [PATCH 3/4] Refactor to avoid conflicts in new p2p permissions --- src/net_permissions.h | 1 + src/test/netbase_tests.cpp | 23 ++++++++++++++--------- test/functional/p2p_permissions.py | 11 ++++++++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/net_permissions.h b/src/net_permissions.h index 38e528e1dd..6d895715e6 100644 --- a/src/net_permissions.h +++ b/src/net_permissions.h @@ -16,6 +16,7 @@ struct bilingual_str; extern const std::vector NET_PERMISSIONS_DOC; enum class NetPermissionFlags : uint32_t { + // NOTE: When adding here, be sure to update net_permissions.cpp's NetPermissions::ToStrings too None = 0, // Can query bloomfilter even if -peerbloomfilters is false BloomFilter = (1U << 1), diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 7ae8c8287f..3b6227fb38 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -465,15 +465,20 @@ 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(), 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()); - BOOST_CHECK(std::find(strings.begin(), strings.end(), "noban") != strings.end()); - BOOST_CHECK(std::find(strings.begin(), strings.end(), "mempool") != strings.end()); - BOOST_CHECK(std::find(strings.begin(), strings.end(), "download") != strings.end()); - BOOST_CHECK(std::find(strings.begin(), strings.end(), "addr") != strings.end()); + const std::vector expected_strings{ + "blockfilters", + "bloomfilter", + "forcerelay", + "relay", + "noban", + "mempool", + "download", + "addr", + }; + BOOST_CHECK_EQUAL(strings.size(), expected_strings.size()); + for (const auto& expected : expected_strings) { + BOOST_CHECK(std::find(strings.begin(), strings.end(), expected) != strings.end()); + } } BOOST_AUTO_TEST_CASE(netbase_dont_resolve_strings_with_embedded_nul_characters) diff --git a/test/functional/p2p_permissions.py b/test/functional/p2p_permissions.py index bbf1d923d2..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"], - ["blockfilters", "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) From fdf53a874d0b80f8e14f19ec0353ebbd1d2f1f88 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 12 Nov 2020 02:03:28 +0000 Subject: [PATCH 4/4] Diff-minimise --- src/net_permissions.h | 1 - src/test/netbase_tests.cpp | 23 +++++++++-------------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/net_permissions.h b/src/net_permissions.h index 6d895715e6..38e528e1dd 100644 --- a/src/net_permissions.h +++ b/src/net_permissions.h @@ -16,7 +16,6 @@ struct bilingual_str; extern const std::vector NET_PERMISSIONS_DOC; enum class NetPermissionFlags : uint32_t { - // NOTE: When adding here, be sure to update net_permissions.cpp's NetPermissions::ToStrings too None = 0, // Can query bloomfilter even if -peerbloomfilters is false BloomFilter = (1U << 1), diff --git a/src/test/netbase_tests.cpp b/src/test/netbase_tests.cpp index 3b6227fb38..7ae8c8287f 100644 --- a/src/test/netbase_tests.cpp +++ b/src/test/netbase_tests.cpp @@ -465,20 +465,15 @@ 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); - const std::vector expected_strings{ - "blockfilters", - "bloomfilter", - "forcerelay", - "relay", - "noban", - "mempool", - "download", - "addr", - }; - BOOST_CHECK_EQUAL(strings.size(), expected_strings.size()); - for (const auto& expected : expected_strings) { - BOOST_CHECK(std::find(strings.begin(), strings.end(), expected) != strings.end()); - } + 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()); + BOOST_CHECK(std::find(strings.begin(), strings.end(), "noban") != strings.end()); + BOOST_CHECK(std::find(strings.begin(), strings.end(), "mempool") != strings.end()); + BOOST_CHECK(std::find(strings.begin(), strings.end(), "download") != strings.end()); + BOOST_CHECK(std::find(strings.begin(), strings.end(), "addr") != strings.end()); } BOOST_AUTO_TEST_CASE(netbase_dont_resolve_strings_with_embedded_nul_characters)