Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: Add CNodeOptions and increase constness #25962

Merged
merged 4 commits into from
Sep 2, 2022

Conversation

ajtowns
Copy link
Contributor

@ajtowns ajtowns commented Aug 31, 2022

Adds CNodeOptions to make it easier to add optional parameters to the CNode constructor, and makes prefer_evict and m_permissionFlags actually const.

src/net.h Outdated Show resolved Hide resolved
Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK

Why not put all arguments in CNodeOptions? It seems a bit confusing to have some arguments passed directly and some via CNodeOptions. Also, if both are used, then it is unclear which way should be used by a newly added argument in the future.

@hebasto
Copy link
Member

hebasto commented Aug 31, 2022

Concept ACK.

@ajtowns
Copy link
Contributor Author

ajtowns commented Aug 31, 2022

Why not put all arguments in CNodeOptions?

It's only the optional arguments that are in there, which I think is a pretty reasonable dividing line, and also limits the code changes needed.

@DrahtBot
Copy link
Contributor

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #25923 (p2p: always provide CNodeStateStats and getpeerinfo/netinfo/gui updates by jonatack)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only the optional arguments that are in there, which I think is a pretty reasonable dividing line, and also limits the code changes needed.

I see. Maybe it makes sense to put all arguments in CNodeOptions, but even as it is this PR seems like an improvement over master. Would be happy to review also if all arguments are passed via CNodeOptions.

src/net.cpp Outdated Show resolved Hide resolved
src/net.cpp Outdated Show resolved Hide resolved
@@ -334,6 +334,13 @@ class V1TransportSerializer : public TransportSerializer {
void prepareForTransport(CSerializedNetMsg& msg, std::vector<unsigned char>& header) const override;
};

struct CNodeOptions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: (feel free to ignore) If this is defined inside CNode, then callers would use CNode::Options instead of CNodeOptions and inside the class it would be just Options instead of CNodeOptions. Also, if/when CNode is renamed to something else, it would not be necessary to rename CNodeOptions too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately there's a gcc/clang bug that means this doesn't work right:

class X
{
public:
    struct Y
    {
        int foo = 42;
    };

    int SomeFunc(Y y = {});
};

gives:

$ g++ -std=c++17 -Wall -W -c -o lame.o lame.cpp
lame.cpp:11:25: error: could not convert ‘<brace-enclosed initializer list>()’ from ‘<brace-enclosed initializer list>’ to ‘X::Y’
   11 |     int SomeFunc(Y y = {});
      |                         ^
      |                         |
      |                         <brace-enclosed initializer list>

$ clang -std=c++17 -Wall -W -c -o lame.o lame.cpp
lame.cpp:11:25: error: default member initializer for 'foo' needed within definition of enclosing class 'X' outside of member functions
    int SomeFunc(Y y = {});
                        ^
lame.cpp:7:13: note: default member initializer declared here
        int foo = 42;
            ^
1 error generated.

Moving Y outside of X fixes this. https://stackoverflow.com/a/53423881/ has more details.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Omitting = {} from SomeFunc() definition seems to resolve this, but then callers need to pass {} at the end if they don't wish to pass optional arguments. Or if all arguments are passed via the Options variable, then it will be ok.

@naumenkogs
Copy link
Member

Concept ACK. Will do code review once the pending feedback is resolved.

@ajtowns ajtowns force-pushed the 202208-cnodeoptions branch from 77a33f5 to 2f3602b Compare September 1, 2022 09:17
Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 2f3602b

@@ -310,7 +311,8 @@ auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional<N
addr_bind,
addr_name,
conn_type,
inbound_onion);
inbound_onion,
CNodeOptions{ .permission_flags = permission_flags });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: here and below, could omit CNodeOptions, like done in net.cpp:

Suggested change
CNodeOptions{ .permission_flags = permission_flags });
{ .permission_flags = permission_flags });

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe not: CI is upset:

./net.h:523:5: note:   no known conversion for argument 10 from ‘<brace-enclosed initializer list>’ to ‘CNodeOptions&&’

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't omit it here because std::make_unique<CNode>(...) can't resolve to a specific function without knowing what type { .permission_flags = .. } is going to be. (Could omit it in the else clause, but figured it was better to have those two clauses be as similar as possible)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you can't omit it when using .foo = std::move(unique_ptr) either, as gcc 8 gives errors. https://godbolt.org/z/rbn6csbax

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't omit it here because std::make_unique<CNode>(...) can't resolve to a specific function without knowing what type { .permission_flags = .. } is going to be.

This is ok, but an alternative is to switch from make_unique<CNode> to new CNode

@jonatack
Copy link
Member

jonatack commented Sep 1, 2022

Review ACK modulo the CI issue

@ajtowns ajtowns force-pushed the 202208-cnodeoptions branch from 2f3602b to 377e9cc Compare September 1, 2022 11:00
Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 377e9cc per git range-diff 52dcb1d 2f3602b 377e9cc

Some clang-format nits if you repush

diff --git a/src/net.cpp b/src/net.cpp
index 6659b64246..138486e468 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -556,7 +556,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
                              pszDest ? pszDest : "",
                              conn_type,
                              /*inbound_onion=*/false,
-                             CNodeOptions{ .i2p_sam_session = std::move(i2p_transient_session) });
+                             CNodeOptions{.i2p_sam_session = std::move(i2p_transient_session)});
     pnode->AddRef();

@@ -1029,8 +1027,8 @@ void CConnman::CreateNodeFromAcceptedSocket(std::unique_ptr<Sock>&& sock,
                              ConnectionType::INBOUND,
                              inbound_onion,
                              CNodeOptions{
-                               .permission_flags = permission_flags,
-                               .prefer_evict = discouraged,
+                                 .permission_flags = permission_flags,
+                                 .prefer_evict = discouraged,
                              });
diff --git a/src/test/fuzz/util.h b/src/test/fuzz/util.h
index 6d652c922b..46cd422cf4 100644
--- a/src/test/fuzz/util.h
+++ b/src/test/fuzz/util.h
@@ -312,7 +312,7 @@ auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional<N
                                        addr_name,
                                        conn_type,
                                        inbound_onion,
-                                       CNodeOptions{ .permission_flags = permission_flags });
+                                       CNodeOptions{.permission_flags = permission_flags});
     } else {
         return CNode{node_id,
                      sock,
@@ -323,7 +323,7 @@ auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional<N
                      addr_name,
                      conn_type,
                      inbound_onion,
-                     CNodeOptions{ .permission_flags = permission_flags }};
+                     CNodeOptions{.permission_flags = permission_flags}};
     }
 }

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 377e9cc

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK 377e9cc. Looks good and feel free to ignore suggestions!

@@ -556,7 +556,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
pszDest ? pszDest : "",
conn_type,
/*inbound_onion=*/false,
std::move(i2p_transient_session));
CNodeOptions{ .i2p_sam_session = std::move(i2p_transient_session) });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In commit "net: add CNodeOptions for optional CNode constructor params" (9dccc33)

I'd shorten this as follows, but it's also reasonable to keep if you think the struct name is helpful.

--- a/src/net.cpp
+++ b/src/net.cpp
@@ -556,7 +556,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
                              pszDest ? pszDest : "",
                              conn_type,
                              /*inbound_onion=*/false,
-                             CNodeOptions{ .i2p_sam_session = std::move(i2p_transient_session) });
+                             { .i2p_sam_session = std::move(i2p_transient_session) });
     pnode->AddRef();
 
     // We're making a new connection, harvest entropy from the time (and our peer count)

The short version is nice because it's basically a substitute for having named arguments in c++.

Same comment also applies to later commits, as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, but I don't think this is possible until we drop support for gcc 8? #25962 (comment)

@@ -310,7 +311,8 @@ auto ConsumeNode(FuzzedDataProvider& fuzzed_data_provider, const std::optional<N
addr_bind,
addr_name,
conn_type,
inbound_onion);
inbound_onion,
CNodeOptions{ .permission_flags = permission_flags });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't omit it here because std::make_unique<CNode>(...) can't resolve to a specific function without knowing what type { .permission_flags = .. } is going to be.

This is ok, but an alternative is to switch from make_unique<CNode> to new CNode

@naumenkogs
Copy link
Member

ACK 377e9cc

@maflcko maflcko merged commit ea67232 into bitcoin:master Sep 2, 2022
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Sep 2, 2022
@bitcoin bitcoin locked and limited conversation to collaborators Sep 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants