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

Parse params directly instead of through node (partial revert #10244) #35

Merged
merged 4 commits into from
Aug 26, 2020

Conversation

ryanofsky
Copy link
Contributor

@ryanofsky ryanofsky commented Jul 16, 2020

This PR is part of the process separation project.


This is a partial revert of bitcoin/bitcoin#10244. It changes gui code to go back to using gArgs and Params() functions directly instead of using interfaces::Node to handle arguments.

These changes were originally pushed as part of bitcoin/bitcoin#19461. Motivation is to support a new GUI process connecting to an already running node process. Details are explained in commit messages, but in addition to spawning a new bitcoin-node process, we want bitcoin-gui to connect to an existing bitcoin-node process. So for that reason it should be able to parse its own parameters, rather than rely on the node.

@ryanofsky ryanofsky changed the title gui: Partially revert #10244 gArgs and Params changes Partially revert bitcoin/bitcoin#10244 gArgs and Params changes Jul 16, 2020
@ryanofsky ryanofsky changed the title Partially revert bitcoin/bitcoin#10244 gArgs and Params changes Partially revert #10244 gArgs and Params changes Jul 16, 2020
@Sjors
Copy link
Member

Sjors commented Jul 17, 2020

Concept ACK. The reasoning as explained in the commit message makes sense to me. Maybe a better PR title would be "Parse params directly instead of through node (partial revert #10244)". And then in the PR description: "In addition to spawning a new bitcoin-node process, we want bitcoin-gui to connect to an existing bitcoin-node proces. So for that reason it should be able to parse its own parameters, rather than rely on the node."

src/qt/test/test_main.cpp Outdated Show resolved Hide resolved
return;
}
if (!m_node.softSetArg("-prune", prune_val)) {
if (!gArgs.SoftSetArg("-prune", prune_val)) {
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 this use this->node().context()->args instead of the global, which should be gone hopefully 🔜 ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: #35 (comment)

Can't this use this->node().context()->args instead of the global, which should be gone hopefully 🔜 ?

After bitcoin/bitcoin#10102, there is no NodeContext in the gui process. An ArgsManager reference could be passed to OptionsModel if desired, though.

@hebasto
Copy link
Member

hebasto commented Jul 17, 2020

I'll try to describe the desired behavior as I understand it.

When a bitcoin-gui process starts there are two possibilities: (a) to spawn a new bitcoin-node process and connect to it, or (b) to connect to an existing bitcoin-node process.

In variant (a) the bitcoin-gui process parses arguments (from the command line and from a config file) and passes them to the bitcoin-node process, which in turn does not even look into the config file.

In variant (b) the existing bitcoin-node process already has parsed its arguments (from the command line and from a config file), and the bitcoin-gui process parses its own command-line arguments and (the same?) config file.

Did I understand the concept correct?

How the possible conflicts between different process parsed arguments should be resolved?

@ryanofsky ryanofsky changed the title Partially revert #10244 gArgs and Params changes Parse params directly instead of through node (partial revert #10244) Jul 17, 2020
Copy link
Contributor Author

@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.

Updated 5adf00e -> 49b993d (pr/ipc-guiarg.1 -> pr/ipc-guiarg.2, compare) with test simplification suggested by Marco, and 3 more commits pulled from bitcoin/bitcoin#19461


re: Sjors #35 (comment)

Maybe a better PR title [...]

Thanks! Used your title and description.


re: hebasto #35 (comment)

I'll try to describe the desired behavior as I understand it. [...]

Yes that's a good description of bitcoin/bitcoin#19461.

How the possible conflicts between different process parsed arguments should be resolved?

This PR doesn't actually change how arguments are interpreted, it just allows them to be sent differently in bitcoin/bitcoin#19461. Like you described above, in that PR if the gui process spawns a new node process, it forwards the arguments and there are no conflicts. But as mentioned in the PR description for bitcoin/bitcoin#19461 "there are rough edges" in that PR and "if node command line options are passed to bitcoin-gui and bitcoin-gui connects to an exiting bitcoin-node process instead of spawning a new one, the node options will be silently ignored." More ideally, passing mismatched node options to bitcoin-gui would trigger errors or warnings. Adding this error checking could be a new commit in bitcoin/bitcoin#19461 or a followup PR.

return;
}
if (!m_node.softSetArg("-prune", prune_val)) {
if (!gArgs.SoftSetArg("-prune", prune_val)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: #35 (comment)

Can't this use this->node().context()->args instead of the global, which should be gone hopefully 🔜 ?

After bitcoin/bitcoin#10102, there is no NodeContext in the gui process. An ArgsManager reference could be passed to OptionsModel if desired, though.

src/qt/test/test_main.cpp Outdated Show resolved Hide resolved
@hebasto
Copy link
Member

hebasto commented Jul 17, 2020

Concept ACK.

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

Reviewed commits:

  • - 551c508 "gui: Partially revert #10244 gArgs and Params changes"
  • - 9139f5b "gui: Remove unused interfaces::Node references"
  • - 0cc3492 "gui: Replace interface::Node references with pointers"
  • - 49b993d "gui: Delay interfaces::Node initialization"

@hebasto
Copy link
Member

hebasto commented Jul 19, 2020

Not passing an interfaces::Node argument to the BitcoinApplication and OptionsModel constructors implies that the internal states of the constructed objects with m_node initialized to nullptr are consistent and legitimate. Therefore, their node() getters shouldn't include assert(m_node). I think the responsibility to check the pointer should be moved to callers.

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

ACK 49b993d, tested on Linux Mint 20 (x86_64, Qt 5.12.8).

49b993d
I think the m_shutdown member should be dropped due to the following reasons:

  • currently, the SplashScreen::shutdown() could be called only after entering to the main event loop, i.e., after the first app.exec() call; therefore, SplashScreen::setNode() will always see the initial value of the m_shutdown
  • if in the future more complicated behavior will be introduced, SplashScreen::setNode() and SplashScreen::shutdown() are potentially data-racy, and the m_shutdown member could require be protected by a mutex

nano-nit: why not apply clang-format-diff.py for each commit?

@ryanofsky
Copy link
Contributor Author

Thanks for reviewing! I looked into many things but wound up not making changes for reasons described below.

re: #35 (comment)

Not passing an interfaces::Node argument to the BitcoinApplication and OptionsModel constructors implies that the internal states of the constructed objects with m_node initialized to nullptr are consistent and legitimate. Therefore, their node() getters shouldn't include assert(m_node).

I don't think this follows. It's ok for functions to have preconditions, and this is a pretty straightforward precondition to have for an accessor returning a reference.

I think the responsibility to check the pointer should be moved to callers.

We might just have a style disagreement here, but if there are specific changes you are looking for, maybe you could post them or describe them in more detail. I don't think we need to have pointers and null checks in places where the pointers can never be null. There's only one place in the PR that actually needs to check for a null node: the splash screen code handling the Q keypress needs to check if the node is connected before sending it a shutdown request. Everywhere else, references and not pointers are more appropriate and have been retained.

re: #35 (review)

I think the m_shutdown member should be dropped due to the following reasons:

m_shutdown is needed so the splash screen can be shown instantly without waiting for anything and the Q key can function requesting a shutdown as soon as possible. Maybe this change could be moved to bitcoin/bitcoin#19461, but you could also say the same about all other changes in this PR. I hope the cleanups in this PR make sense by themselves, but the actual motivation for this PR is to enable bitcoin/bitcoin#19461.

the m_shutdown member could require be protected by a mutex

A mutex would only be required if Qt signals are used incorrectly. GUI state should be accessed by one thread.

nano-nit: why not apply clang-format-diff.py for each commit?

I read diffs to understand changes and having unrelated formatting changes mixed into commits makes this harder.

@hebasto
Copy link
Member

hebasto commented Jul 21, 2020

I think the m_shutdown member should be dropped due to the following reasons:

m_shutdown is needed so the splash screen can be shown instantly without waiting for anything and the Q key can function requesting a shutdown as soon as possible.

I understand this motivation. But the splash screen is not derived from QDialog with its own event loop, it is derived from QWidget and it will wait for the main event loop which starts in

app.exec();

@ryanofsky
Copy link
Contributor Author

I think the m_shutdown member should be dropped due to the following reasons:

m_shutdown is needed so the splash screen can be shown instantly without waiting for anything and the Q key can function requesting a shutdown as soon as possible.

I understand this motivation. But the splash screen is not derived from QDialog with its own event loop, it is derived from QWidget and it will wait for the main event loop which starts in

app.exec();

What is this comment referring to and what is it asking for? I think we both agree handling a null pointer in the splashscreen is not strictly needed here. It's needed to handle the delayed gui->node connection implemented in bitcoin/bitcoin#19461. The point of all the changes in this PR is to reduce size and complexity of bitcoin/bitcoin#19461. I think it makes sense to handle null node pointer in the splash screen here in this PR which is first introducing the pointer variable, even though the variable won't have a null value until bitcoin/bitcoin#19461.

@promag
Copy link
Contributor

promag commented Jul 27, 2020

Concept ACK.

@luke-jr
Copy link
Member

luke-jr commented Jul 31, 2020

Concept ACK

@hebasto
Copy link
Member

hebasto commented Aug 1, 2020

@ryanofsky Mind rebasing? (no DrahtBot's notifications in this repo for now)

@ryanofsky
Copy link
Contributor Author

Rebased 49b993d -> 1a0875f (pr/ipc-guiarg.2 -> pr/ipc-guiarg.3, compare) due to conflicts with bitcoin/bitcoin#19561 and bitcoin/bitcoin#15935

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

re-ACK 1a0875f, only rebased since my previous review (verified with git range-diff).

@ryanofsky
Copy link
Contributor Author

Rebased 1a0875f -> 37b7eba (pr/ipc-guiarg.3 -> pr/ipc-guiarg.4, compare) due to conflict with bitcoin/bitcoin#19098

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

re-ACK 37b7eba, only rebased since my previous review (verified with git range-diff).

Copy link
Contributor

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

crACK 333507a 🦌

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

crACK 333507a1f3 🦌
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUgqNQv7BdH9+5Rmi/cztRlIzz//JI94OOHZY3r2lQ6GovtiSTstsj4eeGarqfNL
v5JOwpXU5NXyJ62BevybdeOwukJTsycj+N8ozCs8HP8ts6H4ji+DA0jpEQA8HBH3
vuLwZI2cV4UrYSebBAJsQZxEpsHqX+eFEhgxUUoZypSgGNDt6A4SuXOKBeT5uU+v
aWjPs5sfsuCiFrMC7opq9/9rIzGNEAnf4zla748NLhbKof+W3HdH5+i1dPSf4tNl
pKdlnt0AoJfuRTlior37qPftEWazXypvupxRnMZ92YRRD+qVrgiTn6c2K6+SvH0G
IhY1//3dYqzPczpR8aAv9igOL1iN2svjrdxm8fPFIU5/feKi92al5RqeXFBUtGLs
ZzJ3XY3paOnMm0A1Zy790TXyOc07Trxu/c3Xe90vR6DKqUoqvKj/443uMLxlMZdj
OCEbjVJJ5jXCadwdQtQmA9uceNj22Hep9AfSdvExflPRq8gq7Q5PzdB5SaNh7VBE
rb2JCP5V
=OHa6
-----END PGP SIGNATURE-----

Timestamp of file with hash 726f1597cbef5b840b8b43b9a0c4aada8e06894a7a3803c798f9d71e3ef4d656 -

//! needs to be called after selectParams() because the settings file
//! location is network-specific.
virtual bool initSettings(std::string& error) = 0;

//! Get the (assumed) blockchain size.
virtual uint64_t getAssumedBlockchainSize() = 0;
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 427c8da

why is this not removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: #35 (comment)

in commit 427c8da

why is this not removed?

Good catch, removed now

@@ -457,11 +460,11 @@ int GuiMain(int argc, char* argv[])

/// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these
// Command-line options take precedence:
node->setupServerArgs();
SetupServerArgs(*node->context());
Copy link
Contributor

Choose a reason for hiding this comment

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

commit 427c8da: The documentation for context() says "Useful for testing". Did you mean to write node_context instead?

Suggested change
SetupServerArgs(*node->context());
SetupServerArgs(node_context);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: https://github.com/bitcoin-core/gui/pull/35/files#r471397426

commit 427c8da: The documentation for context() says "Useful for testing". Did you mean to write node_context instead?

Changed, agree this is a little better. SetupServerArgs should really not be using NodeContext at all (argument is removed in bitcoin/bitcoin#10102), but for this PR which is not in the GUI repository, I wanted to avoid changing non-gui code.

Copy link
Contributor Author

@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.

Thanks for review!

Updated 333507a -> 3ae9b4a (pr/ipc-guiarg.5 -> pr/ipc-guiarg.6, compare) with suggestions

//! needs to be called after selectParams() because the settings file
//! location is network-specific.
virtual bool initSettings(std::string& error) = 0;

//! Get the (assumed) blockchain size.
virtual uint64_t getAssumedBlockchainSize() = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: #35 (comment)

in commit 427c8da

why is this not removed?

Good catch, removed now

@@ -457,11 +460,11 @@ int GuiMain(int argc, char* argv[])

/// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these
// Command-line options take precedence:
node->setupServerArgs();
SetupServerArgs(*node->context());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: https://github.com/bitcoin-core/gui/pull/35/files#r471397426

commit 427c8da: The documentation for context() says "Useful for testing". Did you mean to write node_context instead?

Changed, agree this is a little better. SetupServerArgs should really not be using NodeContext at all (argument is removed in bitcoin/bitcoin#10102), but for this PR which is not in the GUI repository, I wanted to avoid changing non-gui code.

@maflcko maflcko closed this Aug 19, 2020
@maflcko
Copy link
Contributor

maflcko commented Aug 19, 2020

re-run ci

Change gui code to use gArgs, Params() functions directly instead of going
through interfaces::Node.

Remotely accessing bitcoin-node ArgsManager from bitcoin-gui works fine in
bitcoin/bitcoin#10102, when bitcoin-gui spawns a new
bitcoin-node process and controls its startup, but for bitcoin-gui to support
-ipcconnect option in bitcoin/bitcoin#19461 and connect
to an existing bitcoin-node process, it needs ability to parse arguments itself
before connecting out.

This change also simplifies bitcoin/bitcoin#10102 a
bit, by making the bitcoin-gui -> bitcoin-node startup sequence more similar to
the bitcoin-node -> bitcoin-wallet startup sequence where the parent process
parses arguments and passes them to the child process instead of the parent
process using the child process to parse arguments.
Remove Node references no longer needed after previous commit
No change in behavior. Replacing references with pointers allows Node interface
creation to be delayed until later during gui startup next commit to support
implementing -ipcconnect option
This is needed to allow bitcoin-gui to connect to existing node process with
-ipcconnect instead of spawning a new process. It's possible to spawn a new
bitcoin-node process without knowing the current data dir or network, but
connecting to an existing bitcoin-node requires knowing the datadir and network
first.
Copy link
Contributor

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

will re-review after rebase


/// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these
// Command-line options take precedence:
node->setupServerArgs();
SetupServerArgs(node_context);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Could add an unused reference to the argsmanager that is supposed to be used by gui code (instead of the global).

Would either be const ArgsManager& args = *node_context.args or = gArgs?

Feel free to ingore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: #35 (comment)

nit: Could add an unused reference to the argsmanager that is supposed to be used by gui code (instead of the global).

I started implementing this but stopped because there are a number of other uses of gArgs in this function that I thought it would be better not to change here to avoid increasing the size of the PR.

Bigger picture, gArgs is used pretty widely in many parts of qt code and I think that if it's going to be removed, it'd be best to do it in a focused PR updating all the references at the same time.

SetupUIArgs(gArgs);
std::string error;
if (!node->parseParameters(argc, argv, error)) {
node->initError(strprintf(Untranslated("Error parsing command line arguments: %s\n"), error));
if (!gArgs.ParseParameters(argc, argv, error)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: (if feedback is addressed)

Could use

Suggested change
if (!gArgs.ParseParameters(argc, argv, error)) {
if (!args.ParseParameters(argc, argv, error)) {

here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: #35 (comment)

Could use

(same feedback)

@DrahtBot
Copy link
Contributor

🐙 This pull request conflicts with the target branch and needs rebase.

Want to unsubscribe from rebase notifications on this pull request? Just convert this pull request to a "draft".

Copy link
Contributor Author

@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.

Thanks for review

Rebased 3ae9b4a -> 519cae8 (pr/ipc-guiarg.6 -> pr/ipc-guiarg.7, compare) due to conflict with bitcoin/bitcoin#19779


/// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these
// Command-line options take precedence:
node->setupServerArgs();
SetupServerArgs(node_context);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: #35 (comment)

nit: Could add an unused reference to the argsmanager that is supposed to be used by gui code (instead of the global).

I started implementing this but stopped because there are a number of other uses of gArgs in this function that I thought it would be better not to change here to avoid increasing the size of the PR.

Bigger picture, gArgs is used pretty widely in many parts of qt code and I think that if it's going to be removed, it'd be best to do it in a focused PR updating all the references at the same time.

SetupUIArgs(gArgs);
std::string error;
if (!node->parseParameters(argc, argv, error)) {
node->initError(strprintf(Untranslated("Error parsing command line arguments: %s\n"), error));
if (!gArgs.ParseParameters(argc, argv, error)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

re: #35 (comment)

Could use

(same feedback)

@maflcko
Copy link
Contributor

maflcko commented Aug 26, 2020

re-ACK 519cae8, only change is rebase and addressed nits of my previous review last week 🌄

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

re-ACK 519cae8fd6, only change is rebase and addressed nits of my previous review last week 🌄
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUj6Ggv+LwP3f/BQc39c/CE6YAwsMHH0yuGCrTpPSZ2Mg4LFVAMNs5Frf7X/WTK3
knd0Wqn8uXL1ohllgYw/RpANRre871edpLXP9DANpAF1mkFM8oQIwLesi2B26TWK
eQWmTbXHeXzmx3TDeyRlNbnd7YQjYWv46qaLaqgtstSzTM5KQG24D2qLL85YgdvK
iGzfDQqNsfVlt8KQa1edWtMi/tbnSKIERKdC1oGjBdWbg/hliwabsDpjaFtgACSS
CwWyz4yVrKcN3fd9KRkkA+InJIdCGxNx2Tkqvof1f7d3P9RZ3OSlVhz6b7/Z2V6a
kucVgTo/bFOdza6AQ+7K6yT3fuYOyhRvwUY2U9CD1heLUFVdaDouCVwqj1AsSTU7
/eqMwOmldW/hrxxVM+Pnm767VryXYMSkOzjBUlEKjrBgSaQSR9PPe4gZ2spAzDYX
R4CIzdXuxLnmYqgY6ynhaQI//XlBg+Kj68oNYcT/ccKuEkMreYjmnta3T7vtiB3b
SONP0kHM
=zDRb
-----END PGP SIGNATURE-----

Timestamp of file with hash ecc68c0f8f95794d4615f84e2642dbc3ee12d9db23d521fe606e763336bf3551 -

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.

7 participants