-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Refactoring CRPCCommand with enum category #13945
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
Refactoring CRPCCommand with enum category #13945
Conversation
CI failed because of tabs instead o spaces, sorry I am not a python (which version?!) developer; going to solve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kind of weak concept ACK, but current implementation is a bit off.
Please read developer-notes.md and update code according.
Also squash commits.
src/rpc/server.h
Outdated
@@ -128,13 +128,29 @@ void RPCRunLater(const std::string& name, std::function<void(void)> func, int64_ | |||
|
|||
typedef UniValue(*rpcfn_type)(const JSONRPCRequest& jsonRequest); | |||
|
|||
typedef enum{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use enum class
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, if you use enum class
, get rid of the eRPCCategory_
prefix (since then it will be namespaced already).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't add bitcoin-specific things (such as these categories) in rpc/server.h
, the base RPC code is supposed to be independent of any specific use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using enum class
in cf190f5
src/rpc/server.h
Outdated
@@ -128,13 +128,29 @@ void RPCRunLater(const std::string& name, std::function<void(void)> func, int64_ | |||
|
|||
typedef UniValue(*rpcfn_type)(const JSONRPCRequest& jsonRequest); | |||
|
|||
typedef enum{ | |||
eRPCCategory_blockchain = 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use tabs.
now CI it is failing because of:
I don't know how to instruct EDIT: should be solved (now using enum class) with 4d56e9b |
Note to reviewers: This pull request conflicts with the following ones:
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. |
src/rpc/server.cpp
Outdated
"wallet", | ||
"zmq", | ||
"test" | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation means that the list here has to be in sync with the enum definition. I think it would be much more robust and readable if you had here a big switch
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done cf190f5
src/rpc/server.h
Outdated
@@ -128,13 +128,29 @@ void RPCRunLater(const std::string& name, std::function<void(void)> func, int64_ | |||
|
|||
typedef UniValue(*rpcfn_type)(const JSONRPCRequest& jsonRequest); | |||
|
|||
typedef enum{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, if you use enum class
, get rid of the eRPCCategory_
prefix (since then it will be namespaced already).
A drawback of this is that it centralizes knowledge of the command categories in the source code; right now, a module such as the wallet can register its own commands in its own category, without having to update a central file. This is a good form of decoupling. This is not as bad for categories as it would be for, say, commands themselves, but still. |
@laanwj the target of this refactoring, is right to centralise the knowledge of the command categories, to avoid misuse of categories, like it was done for |
I am going to squash commits, let me know if everything is ok |
5604cfb
to
cbfa3a0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK. A few nits.
src/rpc/rpccategory.cpp
Outdated
namespace rpccategory | ||
{ | ||
|
||
std::string Label (const RPCCategory category); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you mean the empty line (line 10) between {
and std::string
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I mean removing std::string Label (const RPCCategory category);
, you already declare it at rpccategory.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done 189bdae
src/rpc/rpccategory.h
Outdated
namespace rpccategory | ||
{ | ||
|
||
extern std::string Label (const RPCCategory category); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove extern
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm… extern
(ok I'm old style C developer) means declared elsewhere
, infact the prototype is declared in src/rpc/rpccategory.cpp
, and the definition also in src/rpc/rpccategory.cpp
. What's wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extern
on function is redundant, it is already extern
if you don't implement it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done 189bdae
src/rpc/rpccategory.cpp
Outdated
|
||
std::string Label (const RPCCategory category); | ||
|
||
std::string Label (const RPCCategory category) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove extra space between Label
and (
. There are many other places need to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done 477b083
src/rpc/rpccategory.cpp
Outdated
std::string Label (const RPCCategory category) | ||
{ | ||
#ifdef HANDLE_CASE_RETURN | ||
#error "HANDLE_CASE_RETURN already defined" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you will miss it, in case of unpredictable mistakes ;-)
src/rpc/rpccategory.cpp
Outdated
HANDLE_CASE_RETURN (RPCCategory, test); | ||
// if you are missing a case, you'll have a warning here | ||
} | ||
#undef HANDLE_CASE_RETURN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need to undef this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok right now, it's not necessary, but i meant to define a local MACRO: define and use as you like, and undefined when you don't need anymore.
src/rpc/rpccategory.h
Outdated
@@ -0,0 +1,33 @@ | |||
// Copyright (c) 2010 Satoshi Nakamoto | |||
// Copyright (c) 2009-2018 The Bitcoin Core developers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Copyright (c) 2018 The Bitcoin Core developers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in c9f15c1
src/rpc/rpccategory.cpp
Outdated
@@ -0,0 +1,39 @@ | |||
// Copyright (c) 2009-2010 Satoshi Nakamoto | |||
// Copyright (c) 2009-2018 The Bitcoin Core developers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Copyright (c) 2018 The Bitcoin Core developers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in c9f15c1
src/rpc/server.cpp
Outdated
@@ -158,7 +158,7 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& | |||
std::vector<std::pair<std::string, const CRPCCommand*> > vCommands; | |||
|
|||
for (const auto& entry : mapCommands) | |||
vCommands.push_back(make_pair(entry.second->category + entry.first, entry.second)); | |||
vCommands.push_back(std::make_pair(rpccategory::Label (entry.second->category) + entry.first, entry.second)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: emplace_back
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you explain better? thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you're touching this line, you can use c++11 emplace_back to have better performance: vCommands.emplace_back(rpccategory::Label(entry.second->category) + entry.first, entry.second);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done c13fe25
src/rpc/server.h
Outdated
@@ -17,6 +17,8 @@ | |||
|
|||
#include <univalue.h> | |||
|
|||
#include <rpc/rpccategory.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this after #include <rpc/protocol.h>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doing in the next commit, thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done 7e5453d
src/rpc/rpccategory.h
Outdated
|
||
enum class RPCCategory | ||
{ | ||
blockchain = 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you have to set this to 0
, also compile time constants should be ALL_UPPER_CASE
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, it's not necessary infact, I am going to remove the zero initialization (it was necessary before, when I was using an array to transform enum to std::string);
(done in 7659882)
About ALL_UPPER_CASE
for compile time constants, should be
doesn't mean must
and as it is written in https://github.com/bitcoin/bitcoin/blob/master/doc/developer-notes.md
I think this is near the case:
are not required when doing so would need changes to significant pieces of existing code.
and worst and more: consider the fact that, in the case those constants to be uppercase, an extra runtime (!) code would be neccessary to the function rpccategory::Label
to make lowercase the result.
But ok, because of that, I'll explain in a comment in enum class RPCCategory
that the constant identifiers are used exactly as the output
wip: please don't merge |
wip: waiting more suggestions, before new squash |
Now I don't understand why CI is failing. But I have to go to sleep EDIT: it was for missing |
src/rpc/rpccategory.cpp
Outdated
namespace rpccategory | ||
{ | ||
|
||
std::string Label (const RPCCategory category); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I mean removing std::string Label (const RPCCategory category);
, you already declare it at rpccategory.h
src/rpc/server.cpp
Outdated
@@ -158,7 +158,7 @@ std::string CRPCTable::help(const std::string& strCommand, const JSONRPCRequest& | |||
std::vector<std::pair<std::string, const CRPCCommand*> > vCommands; | |||
|
|||
for (const auto& entry : mapCommands) | |||
vCommands.push_back(make_pair(entry.second->category + entry.first, entry.second)); | |||
vCommands.push_back(std::make_pair(rpccategory::Label (entry.second->category) + entry.first, entry.second)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you're touching this line, you can use c++11 emplace_back to have better performance: vCommands.emplace_back(rpccategory::Label(entry.second->category) + entry.first, entry.second);
src/rpc/rpccategory.h
Outdated
namespace rpccategory | ||
{ | ||
|
||
extern std::string Label (const RPCCategory category); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extern
on function is redundant, it is already extern
if you don't implement it.
src/rpc/rpccategory.cpp
Outdated
HANDLE_CASE_RETURN (RPCCategory, test); | ||
// if you are missing a case, you'll have a warning here | ||
} | ||
assert (0); // never fall down here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to #include <cassert>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done c1418aa
I am going to squash commits. The point is that if, I’ll make those identifiers uppercase, I have to make them lowercase in same place; and I have these options:
Another option could be, to leave them in upper case, for example:
But we cannot know the impact and the implications, such modification in the output, could have in external software. Because of those points, I think it should be better to leave them in lowercase. Anyway let, me know |
854672b
to
4eec7a1
Compare
squashed |
utACK 4eec7a1c3421acc9d31c4c0f93ca6ec376e0847a |
Hi @promag thanks for your review. I would say, the only place where I spoke about performance, were together with the adjective This PR, title starts with Which categories and how many we have now in Bitcoin RPC commands? Actually it's not easy to respond in deterministic way to the above question; maybe the only way, is to run Adding a global variable for each possible properties (hidden, deprecated, etc… properties) as you suggest, can be a good solution, but it can be a nightmare for maintenance, or maybe (if necessary) it can be done, in next steps, not now. Like an example, consider also, that without this Without this PR; how Bitcoin will handle the next "blockhain" category? (take care about the typo). Thanks :-) |
You can write a test that asserts the possible categories. |
And documentation. Or the above test. |
@promag do you really think that adding a PR documentation similar to this, will help?
just joking… do you? :-p EDIT: renamed to |
Another consideration from another perspective: right now in branch master 271b379 searching for the hard coded string namespace rpccommand
{
const std::string WALLET="wallet";
} // namespace "rpccommand" and substitute the 61 hard coded Am I wrong? |
506b2ee
to
89a497d
Compare
89a497d
to
733ee98
Compare
This is a squash of the below commits: - enum ERPCCategory, CRPCCommand::Label - wip: CRPCCommand.category from type string to enum - wip: CRPCCommands construct with enum - refactoring with enum ok - missing test category in qt for cmd rpcNestedTest - wip: text formatting: tabs to spaces. - wip: refactor using `enum class` C++11. Update CRPCCommand::Label () using a switch case - wip: check-rpc-mappings.py fix regex to new format Now it's catching the format: ' { RPCCategory::control, "help", &help, {"command"} },' before was catching: ' { "control", "help", &help, {"command"} },' - wip: add src/rpc/rpccategory.h|cpp - removed CRCPCommand::Label for rpccategory::Label - moved `#include <rpc/rpccategory.h>` - removed unneccessary RPCCategory initializiation - comments and one assert(0) - // Copyright (c) 2018 The Bitcoin Core developers for files: src/rpc/rpccategory.h|cpp as suggested from github user ken2812221 - wip: missing `#include <cassert>` - using `emplace_back` C++11 - remove old-style C `extern` - remove spaces after function names - remove unnecessary call to RPCCategory::Label (cherry picked from commit 4eec7a1c3421acc9d31c4c0f93ca6ec376e0847a) enum RPCCategory uppercase, rpccategory:Label lowercase fix test/lint/check-rpc-mappings.py to uppercase remove unnecessary comments, and false instead of 0 std::string category to RPCCategory category Using boost::optional<RPCCategory> remove src/rpc/server.cpp Capitalize() call Capitalization is done by hand in rpccategory::Label()
removed also an un unnecessary forward declaration
733ee98
to
04e70f2
Compare
@isghe that's unrelated to this PR, and IMO this can be closed. |
Sorry, there seems to be no agreement to do this, in which case we prefer not making a change to the code. |
Thanks for your reviews; I am happy because this PR, inspired #14020 , and I did learn new things on C++ programming (emplace and optional), and about test in python. |
refactoring
CRPCCommand
changing the type of its membercategory
fromstd::string
to atypedef enum ERPCCategory
.The behaviour should be exactly the same with a very very small, in any way irrelevant, speed dump.
I am doing this, in preparation to add attributes, likes
visibility
andstate
toCRPCCommand
structure, to avoid using category names, for overridden informations like visibility or deprecation.For example, from v0.16.0 the command
getinfo
switched its category fromcontrol
tohidden
, while I think the idea was to let it tocontrol
category, with attributes similar tovisibility = false
andstate = deprecated
Thanks,
Isidoro Ghezzi
p.s:
Also take care I'm never testing on QT. (I simply never configure nor compile on QT); anyway I was able to catch the QT command
rpcNestedTest
.regtest
andmacOS
EDITs:
enum class
it's giving right error trying to assign by mistake to a std::string :-) cf190f5regtest
onubuntu
andmacOS