Skip to content

Commit 4da26fb

Browse files
committed
Merge bitcoin/bitcoin#21506: p2p, refactor: make NetPermissionFlags an enum class
7075f60 scripted-diff: update noban documentation in net_processing.cpp (Jon Atack) a95540c scripted-diff: rename NetPermissionFlags enumerators (Jon Atack) 810d092 p2p, refactor: make NetPermissionFlags a uint32 enum class (Jon Atack) 7b55a94 p2p: NetPermissions::HasFlag() pass flags param by value (Jon Atack) 91f6e6e scripted-diff: add NetPermissionFlags scopes where not already present (Jon Atack) Pull request description: While reviewing #20196, I noticed the `NetPermissionFlags` enums are frequently called as if they were scoped, yet are still global. This patch upgrades `NetPermissionFlags` to a scoped class enum and updates the enumerator naming, similarly to #19771. See https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#enum-enumerations for more info. This change would eliminate the class of bugs like bitcoin/bitcoin#20196 (comment) and #21644, as only defined operations on the flags would compile. ACKs for top commit: laanwj: Code review ACK 7075f60 vasild: ACK 7075f60 Tree-SHA512: 7fcea66ee499f059efc78c934b5f729b3c8573fe304dee2c27c837c2f662b89324790568246d75b2a574cf9f059b42d3551d928996862f4358055eb43521e6f4
2 parents 1ed859e + 7075f60 commit 4da26fb

File tree

9 files changed

+126
-118
lines changed

9 files changed

+126
-118
lines changed

src/net.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,7 @@ bool CConnman::AttemptToEvictConnection()
10051005

10061006
LOCK(cs_vNodes);
10071007
for (const CNode* node : vNodes) {
1008-
if (node->HasPermission(PF_NOBAN))
1008+
if (node->HasPermission(NetPermissionFlags::NoBan))
10091009
continue;
10101010
if (!node->IsInboundConn())
10111011
continue;
@@ -1062,7 +1062,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
10621062

10631063
const CAddress addr_bind = GetBindAddress(hSocket);
10641064

1065-
NetPermissionFlags permissionFlags = NetPermissionFlags::PF_NONE;
1065+
NetPermissionFlags permissionFlags = NetPermissionFlags::None;
10661066
hListenSocket.AddSocketPermissionFlags(permissionFlags);
10671067

10681068
CreateNodeFromAcceptedSocket(hSocket, permissionFlags, addr_bind, addr);
@@ -1077,12 +1077,12 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket,
10771077
int nMaxInbound = nMaxConnections - m_max_outbound;
10781078

10791079
AddWhitelistPermissionFlags(permissionFlags, addr);
1080-
if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_ISIMPLICIT)) {
1081-
NetPermissions::ClearFlag(permissionFlags, PF_ISIMPLICIT);
1082-
if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) NetPermissions::AddFlag(permissionFlags, PF_FORCERELAY);
1083-
if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) NetPermissions::AddFlag(permissionFlags, PF_RELAY);
1084-
NetPermissions::AddFlag(permissionFlags, PF_MEMPOOL);
1085-
NetPermissions::AddFlag(permissionFlags, PF_NOBAN);
1080+
if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::Implicit)) {
1081+
NetPermissions::ClearFlag(permissionFlags, NetPermissionFlags::Implicit);
1082+
if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) NetPermissions::AddFlag(permissionFlags, NetPermissionFlags::ForceRelay);
1083+
if (gArgs.GetBoolArg("-whitelistrelay", DEFAULT_WHITELISTRELAY)) NetPermissions::AddFlag(permissionFlags, NetPermissionFlags::Relay);
1084+
NetPermissions::AddFlag(permissionFlags, NetPermissionFlags::Mempool);
1085+
NetPermissions::AddFlag(permissionFlags, NetPermissionFlags::NoBan);
10861086
}
10871087

10881088
{
@@ -1111,7 +1111,7 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket,
11111111

11121112
// Don't accept connections from banned peers.
11131113
bool banned = m_banman && m_banman->IsBanned(addr);
1114-
if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_NOBAN) && banned)
1114+
if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && banned)
11151115
{
11161116
LogPrint(BCLog::NET, "connection from %s dropped (banned)\n", addr.ToString());
11171117
CloseSocket(hSocket);
@@ -1120,7 +1120,7 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket,
11201120

11211121
// Only accept connections from discouraged peers if our inbound slots aren't (almost) full.
11221122
bool discouraged = m_banman && m_banman->IsDiscouraged(addr);
1123-
if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::PF_NOBAN) && nInbound + 1 >= nMaxInbound && discouraged)
1123+
if (!NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::NoBan) && nInbound + 1 >= nMaxInbound && discouraged)
11241124
{
11251125
LogPrint(BCLog::NET, "connection from %s dropped (discouraged)\n", addr.ToString());
11261126
CloseSocket(hSocket);
@@ -1141,7 +1141,7 @@ void CConnman::CreateNodeFromAcceptedSocket(SOCKET hSocket,
11411141
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
11421142

11431143
ServiceFlags nodeServices = nLocalServices;
1144-
if (NetPermissions::HasFlag(permissionFlags, PF_BLOOMFILTER)) {
1144+
if (NetPermissions::HasFlag(permissionFlags, NetPermissionFlags::BloomFilter)) {
11451145
nodeServices = static_cast<ServiceFlags>(nodeServices | NODE_BLOOM);
11461146
}
11471147

@@ -2253,7 +2253,7 @@ void CConnman::ThreadI2PAcceptIncoming()
22532253
continue;
22542254
}
22552255

2256-
CreateNodeFromAcceptedSocket(conn.sock->Release(), NetPermissionFlags::PF_NONE,
2256+
CreateNodeFromAcceptedSocket(conn.sock->Release(), NetPermissionFlags::None,
22572257
CAddress{conn.me, NODE_NONE}, CAddress{conn.peer, NODE_NONE});
22582258
}
22592259
}
@@ -2411,7 +2411,7 @@ bool CConnman::Bind(const CService &addr, unsigned int flags, NetPermissionFlags
24112411
return false;
24122412
}
24132413

2414-
if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !NetPermissions::HasFlag(permissions, NetPermissionFlags::PF_NOBAN)) {
2414+
if (addr.IsRoutable() && fDiscover && !(flags & BF_DONT_ADVERTISE) && !NetPermissions::HasFlag(permissions, NetPermissionFlags::NoBan)) {
24152415
AddLocal(addr, LOCAL_BIND);
24162416
}
24172417

@@ -2425,7 +2425,7 @@ bool CConnman::InitBinds(
24252425
{
24262426
bool fBound = false;
24272427
for (const auto& addrBind : binds) {
2428-
fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::PF_NONE);
2428+
fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR), NetPermissionFlags::None);
24292429
}
24302430
for (const auto& addrBind : whiteBinds) {
24312431
fBound |= Bind(addrBind.m_service, (BF_EXPLICIT | BF_REPORT_ERROR), addrBind.m_flags);
@@ -2434,12 +2434,12 @@ bool CConnman::InitBinds(
24342434
struct in_addr inaddr_any;
24352435
inaddr_any.s_addr = htonl(INADDR_ANY);
24362436
struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2437-
fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::PF_NONE);
2438-
fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::PF_NONE);
2437+
fBound |= Bind(CService(inaddr6_any, GetListenPort()), BF_NONE, NetPermissionFlags::None);
2438+
fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE, NetPermissionFlags::None);
24392439
}
24402440

24412441
for (const auto& addr_bind : onion_binds) {
2442-
fBound |= Bind(addr_bind, BF_EXPLICIT | BF_DONT_ADVERTISE, NetPermissionFlags::PF_NONE);
2442+
fBound |= Bind(addr_bind, BF_EXPLICIT | BF_DONT_ADVERTISE, NetPermissionFlags::None);
24432443
}
24442444

24452445
return fBound;

src/net.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ class CNode
402402
std::unique_ptr<TransportDeserializer> m_deserializer;
403403
std::unique_ptr<TransportSerializer> m_serializer;
404404

405-
NetPermissionFlags m_permissionFlags{PF_NONE};
405+
NetPermissionFlags m_permissionFlags{NetPermissionFlags::None};
406406
std::atomic<ServiceFlags> nServices{NODE_NONE};
407407
SOCKET hSocket GUARDED_BY(cs_hSocket);
408408
/** Total size of all vSendMsg entries */

src/net_permissions.cpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ namespace {
2323
// The parse the following format "perm1,perm2@xxxxxx"
2424
bool TryParsePermissionFlags(const std::string str, NetPermissionFlags& output, size_t& readen, bilingual_str& error)
2525
{
26-
NetPermissionFlags flags = PF_NONE;
26+
NetPermissionFlags flags = NetPermissionFlags::None;
2727
const auto atSeparator = str.find('@');
2828

2929
// if '@' is not found (ie, "xxxxx"), the caller should apply implicit permissions
3030
if (atSeparator == std::string::npos) {
31-
NetPermissions::AddFlag(flags, PF_ISIMPLICIT);
31+
NetPermissions::AddFlag(flags, NetPermissionFlags::Implicit);
3232
readen = 0;
3333
}
3434
// else (ie, "perm1,perm2@xxxxx"), let's enumerate the permissions by splitting by ',' and calculate the flags
@@ -44,14 +44,14 @@ bool TryParsePermissionFlags(const std::string str, NetPermissionFlags& output,
4444
readen += len; // We read "perm1"
4545
if (commaSeparator != std::string::npos) readen++; // We read ","
4646

47-
if (permission == "bloomfilter" || permission == "bloom") NetPermissions::AddFlag(flags, PF_BLOOMFILTER);
48-
else if (permission == "noban") NetPermissions::AddFlag(flags, PF_NOBAN);
49-
else if (permission == "forcerelay") NetPermissions::AddFlag(flags, PF_FORCERELAY);
50-
else if (permission == "mempool") NetPermissions::AddFlag(flags, PF_MEMPOOL);
51-
else if (permission == "download") NetPermissions::AddFlag(flags, PF_DOWNLOAD);
52-
else if (permission == "all") NetPermissions::AddFlag(flags, PF_ALL);
53-
else if (permission == "relay") NetPermissions::AddFlag(flags, PF_RELAY);
54-
else if (permission == "addr") NetPermissions::AddFlag(flags, PF_ADDR);
47+
if (permission == "bloomfilter" || permission == "bloom") NetPermissions::AddFlag(flags, NetPermissionFlags::BloomFilter);
48+
else if (permission == "noban") NetPermissions::AddFlag(flags, NetPermissionFlags::NoBan);
49+
else if (permission == "forcerelay") NetPermissions::AddFlag(flags, NetPermissionFlags::ForceRelay);
50+
else if (permission == "mempool") NetPermissions::AddFlag(flags, NetPermissionFlags::Mempool);
51+
else if (permission == "download") NetPermissions::AddFlag(flags, NetPermissionFlags::Download);
52+
else if (permission == "all") NetPermissions::AddFlag(flags, NetPermissionFlags::All);
53+
else if (permission == "relay") NetPermissions::AddFlag(flags, NetPermissionFlags::Relay);
54+
else if (permission == "addr") NetPermissions::AddFlag(flags, NetPermissionFlags::Addr);
5555
else if (permission.length() == 0); // Allow empty entries
5656
else {
5757
error = strprintf(_("Invalid P2P permission: '%s'"), permission);
@@ -71,13 +71,13 @@ bool TryParsePermissionFlags(const std::string str, NetPermissionFlags& output,
7171
std::vector<std::string> NetPermissions::ToStrings(NetPermissionFlags flags)
7272
{
7373
std::vector<std::string> strings;
74-
if (NetPermissions::HasFlag(flags, PF_BLOOMFILTER)) strings.push_back("bloomfilter");
75-
if (NetPermissions::HasFlag(flags, PF_NOBAN)) strings.push_back("noban");
76-
if (NetPermissions::HasFlag(flags, PF_FORCERELAY)) strings.push_back("forcerelay");
77-
if (NetPermissions::HasFlag(flags, PF_RELAY)) strings.push_back("relay");
78-
if (NetPermissions::HasFlag(flags, PF_MEMPOOL)) strings.push_back("mempool");
79-
if (NetPermissions::HasFlag(flags, PF_DOWNLOAD)) strings.push_back("download");
80-
if (NetPermissions::HasFlag(flags, PF_ADDR)) strings.push_back("addr");
74+
if (NetPermissions::HasFlag(flags, NetPermissionFlags::BloomFilter)) strings.push_back("bloomfilter");
75+
if (NetPermissions::HasFlag(flags, NetPermissionFlags::NoBan)) strings.push_back("noban");
76+
if (NetPermissions::HasFlag(flags, NetPermissionFlags::ForceRelay)) strings.push_back("forcerelay");
77+
if (NetPermissions::HasFlag(flags, NetPermissionFlags::Relay)) strings.push_back("relay");
78+
if (NetPermissions::HasFlag(flags, NetPermissionFlags::Mempool)) strings.push_back("mempool");
79+
if (NetPermissions::HasFlag(flags, NetPermissionFlags::Download)) strings.push_back("download");
80+
if (NetPermissions::HasFlag(flags, NetPermissionFlags::Addr)) strings.push_back("addr");
8181
return strings;
8282
}
8383

src/net_permissions.h

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <netaddress.h>
66

77
#include <string>
8+
#include <type_traits>
89
#include <vector>
910

1011
#ifndef BITCOIN_NET_PERMISSIONS_H
@@ -14,52 +15,59 @@ struct bilingual_str;
1415

1516
extern const std::vector<std::string> NET_PERMISSIONS_DOC;
1617

17-
enum NetPermissionFlags {
18-
PF_NONE = 0,
18+
enum class NetPermissionFlags : uint32_t {
19+
None = 0,
1920
// Can query bloomfilter even if -peerbloomfilters is false
20-
PF_BLOOMFILTER = (1U << 1),
21+
BloomFilter = (1U << 1),
2122
// Relay and accept transactions from this peer, even if -blocksonly is true
2223
// This peer is also not subject to limits on how many transaction INVs are tracked
23-
PF_RELAY = (1U << 3),
24+
Relay = (1U << 3),
2425
// Always relay transactions from this peer, even if already in mempool
2526
// Keep parameter interaction: forcerelay implies relay
26-
PF_FORCERELAY = (1U << 2) | PF_RELAY,
27+
ForceRelay = (1U << 2) | Relay,
2728
// Allow getheaders during IBD and block-download after maxuploadtarget limit
28-
PF_DOWNLOAD = (1U << 6),
29+
Download = (1U << 6),
2930
// Can't be banned/disconnected/discouraged for misbehavior
30-
PF_NOBAN = (1U << 4) | PF_DOWNLOAD,
31+
NoBan = (1U << 4) | Download,
3132
// Can query the mempool
32-
PF_MEMPOOL = (1U << 5),
33+
Mempool = (1U << 5),
3334
// Can request addrs without hitting a privacy-preserving cache
34-
PF_ADDR = (1U << 7),
35+
Addr = (1U << 7),
3536

3637
// True if the user did not specifically set fine grained permissions
37-
PF_ISIMPLICIT = (1U << 31),
38-
PF_ALL = PF_BLOOMFILTER | PF_FORCERELAY | PF_RELAY | PF_NOBAN | PF_MEMPOOL | PF_DOWNLOAD | PF_ADDR,
38+
Implicit = (1U << 31),
39+
All = BloomFilter | ForceRelay | Relay | NoBan | Mempool | Download | Addr,
3940
};
41+
static inline constexpr NetPermissionFlags operator|(NetPermissionFlags a, NetPermissionFlags b)
42+
{
43+
using t = typename std::underlying_type<NetPermissionFlags>::type;
44+
return static_cast<NetPermissionFlags>(static_cast<t>(a) | static_cast<t>(b));
45+
}
4046

4147
class NetPermissions
4248
{
4349
public:
4450
NetPermissionFlags m_flags;
4551
static std::vector<std::string> ToStrings(NetPermissionFlags flags);
46-
static inline bool HasFlag(const NetPermissionFlags& flags, NetPermissionFlags f)
52+
static inline bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
4753
{
48-
return (flags & f) == f;
54+
using t = typename std::underlying_type<NetPermissionFlags>::type;
55+
return (static_cast<t>(flags) & static_cast<t>(f)) == static_cast<t>(f);
4956
}
5057
static inline void AddFlag(NetPermissionFlags& flags, NetPermissionFlags f)
5158
{
52-
flags = static_cast<NetPermissionFlags>(flags | f);
59+
flags = flags | f;
5360
}
54-
//! ClearFlag is only called with `f` == NetPermissionFlags::PF_ISIMPLICIT.
61+
//! ClearFlag is only called with `f` == NetPermissionFlags::Implicit.
5562
//! If that should change in the future, be aware that ClearFlag should not
56-
//! be called with a subflag of a multiflag, e.g. NetPermissionFlags::PF_RELAY
57-
//! or NetPermissionFlags::PF_DOWNLOAD, as that would leave `flags` in an
63+
//! be called with a subflag of a multiflag, e.g. NetPermissionFlags::Relay
64+
//! or NetPermissionFlags::Download, as that would leave `flags` in an
5865
//! invalid state corresponding to none of the existing flags.
5966
static inline void ClearFlag(NetPermissionFlags& flags, NetPermissionFlags f)
6067
{
61-
assert(f == NetPermissionFlags::PF_ISIMPLICIT);
62-
flags = static_cast<NetPermissionFlags>(flags & ~f);
68+
assert(f == NetPermissionFlags::Implicit);
69+
using t = typename std::underlying_type<NetPermissionFlags>::type;
70+
flags = static_cast<NetPermissionFlags>(static_cast<t>(flags) & ~static_cast<t>(f));
6371
}
6472
};
6573

0 commit comments

Comments
 (0)