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

Pause mining during JoinSplit creation #1932

Merged
merged 1 commit into from
Mar 2, 2017

Conversation

aniemerg
Copy link
Contributor

@aniemerg aniemerg commented Dec 8, 2016

Closes #1522 .

@ebfull
Copy link
Contributor

ebfull commented Dec 8, 2016

Awesome!

Is there no way to disable mining via the RPC? (To avoid the scenario where this code would re-enable mining that has been disabled in some other way.)

@aniemerg
Copy link
Contributor Author

aniemerg commented Dec 9, 2016

So, as best as I understand it, mining is enabled/disabled in the rpc via setgenerate(). If we were to use setgenerate(), we'd have to first check whether mining is enabled with getgenerate(), store that in a flag, disable mining, and then after the joinsplit, re-enable mining if appropriate. I can certainly take that approach (and submit a PR to that effect).

I avoided doing that, because it seemed slightly more complex, but also because this approach avoids changing mapArgs, as it would under the above rpc approach. Since mapArgs appears intended to reflect the parameter state set by the user, I wanted to avoid writing code that would change it. Suppose, for example, the user starts a z_sendmany, and then sends an rpc command to disable mining. Under the RPC approach I described above, it's possible that upon the completion of the joinsplit that mining is re-enabled against the wishes of the user.

@str4d str4d added memory management I-performance Problems and improvements with respect to performance A-pow Area: Proof-of-Work and mining labels Dec 16, 2016
@str4d str4d changed the title 1522 pause mining for joinsplit Pause mining during JoinSplit creation Dec 16, 2016
@str4d str4d added this to the 1.0.5 milestone Dec 16, 2016
Copy link
Contributor

@str4d str4d 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, but at least one necessary change.

@@ -697,6 +702,9 @@ bool AsyncRPCOperation_sendmany::main_impl() {
}

sign_send_raw_transaction(obj);
#ifdef ENABLE_WALLET
GenerateBitcoins(GetBoolArg("-gen",false), pwalletMain, (int)GetArg("-genproclimit", -1));
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be GetArg("-genproclimit", 1) to match the documented default for -genproclimit (see init.cpp). The defaults in rpcmining.cpp for setgenerate and getmininginfo are inconsistent, and also not actually documented there.

@@ -144,6 +145,10 @@ bool AsyncRPCOperation_sendmany::main_impl() {

assert(isfromtaddr_ != isfromzaddr_);

#ifdef ENABLE_WALLET
Copy link
Contributor

Choose a reason for hiding this comment

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

If #1795 is merged before this PR, change this #ifdef and the one below to:

#if defined(ENABLE_WALLET) && defined(ENABLE_MINING)

@@ -144,6 +145,10 @@ bool AsyncRPCOperation_sendmany::main_impl() {

assert(isfromtaddr_ != isfromzaddr_);

#ifdef ENABLE_WALLET
GenerateBitcoins(false, NULL, 0);
#endif
Copy link
Contributor

Choose a reason for hiding this comment

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

If #1965 is merged before this PR, change this entire #ifdef block to:

#ifdef ENABLE_MINING
  #ifdef ENABLE_WALLET
    GenerateBitcoins(false, NULL, 0);
  #else
    GenerateBitcoins(false, 0);
  #endif
#endif

and likewise below.

@aniemerg
Copy link
Contributor Author

aniemerg commented Jan 6, 2017

Should address desired changes. #1795 and #1965 should be merged first.

@ebfull
Copy link
Contributor

ebfull commented Jan 18, 2017

Thank you @aniemerg! ACK

@zkbot r+

@zkbot
Copy link
Contributor

zkbot commented Jan 18, 2017

📌 Commit 92e4b29 has been approved by ebfull

@ebfull
Copy link
Contributor

ebfull commented Jan 18, 2017

@zkbot r-

@ebfull
Copy link
Contributor

ebfull commented Jan 18, 2017

(Merging #1863 and #1965 first, will require additional review.)

Copy link
Contributor

@bitcartel bitcartel left a comment

Choose a reason for hiding this comment

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

NACK. Thanks for the PR @aniemerg. After review, I see an issue which blocks this PR and two that are concept NACKs (which we can defer)

  1. Bug
  2. Test
  3. Concept: Addresses Pause mining while doing a JoinSplit #1522 but does it solve the problem?
  4. Concept: Design Pattern

Let me expand upon these:

  1. Bug

Mining is halted upon entering the operation's main_impl(). However, mining is only restored at the end of the function when a transaction has been created successfully. There are a bunch of errors that could occur between those two points. If there is an error, mining never restarts. One possible fix for this is to have the stopping and restarting in main(), surrounding the try catch block which calls main_impl().

  1. Test

Perhaps modify one of the Python qa rpc tests to check that the miner threads are disabled when a JoinSplit is in progress?

  1. Concept: Addresses Pause mining while doing a JoinSplit #1522 but does it solve the problem?

Ticket #1522 states "when a JoinSplit starts we should cancel all mining threads". This PR patches the async operation used by z_sendmany, but a user could make an rpc call to 'zcbenchmark createjoinsplit' which does not halt mining.

If there are parallel joinsplits, which we can do by re-enabling the option to have multiple async worker threads, there is a race condition where one joinsplit tx completes successfully and re-enables mining, while another joinsplit tx is still being processed.

  1. Concept: Design Pattern

Why should an async operation care or even know about the miner? We should try to avoid unnecessary coupling between two subsystems. It would be better if the JSDescription class signaled to interested listeners, like the miner, that it was about to generate a JoinSplit and signal again when it has finished (say in JSDescription::Randomized or create a wrapper which we call).

To handle the race condition mentioned in (3), you could use an atomic counter which the halt signal handler will increment and the resume signal handler decrements. At launch state, the counter is 0 which the miner treats as a green light to mine. If there are parallel JoinSplits, the counter will increase but when all the JoinSplits have finished, the counter will be back at 0 and mining can resume.

So next steps...

Please fix (1) and if possible, add a test (2) to confirm that mining threads stop and restart when a JoinSplit is created.

Would be great if you could implement a solution like described in (4). Since that's a bigger chunk of work and other members of the team might have some ideas, that might be best broken off into a new ticket, or added to #1522, and have this PR be a temporary/partial solution to the problem i.e. we leave #1522 open.

@aniemerg Hope the above makes sense, let me know otherwise.

@ebfull Thoughts on above and next steps?

@ebfull
Copy link
Contributor

ebfull commented Jan 19, 2017

Given the time requirements for 1.0.5 I will need to bump this to 1.0.6.

@ebfull ebfull modified the milestones: 1.0.6, 1.0.5 Jan 19, 2017
@bitcartel bitcartel added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 7, 2017
@bitcartel
Copy link
Contributor

Waiting for #1863 and #1965 to be merged first.

@bitcartel
Copy link
Contributor

We should have a test for this.

@bitcartel bitcartel modified the milestones: 1.0.7, 1.0.6 Feb 9, 2017
@aniemerg
Copy link
Contributor Author

aniemerg commented Feb 9, 2017

Regarding a test, I've been unsure how to accomplish that using the rpc testing framework. The way that this PR currently works is to turn off mining in a way that isn't revealed when using rpc commands such as getgenerate. So I am not sure how to write the most natural test -- that is, turn on mining, start a joinsplit, and check to see that mining is off.

@daira
Copy link
Contributor

daira commented Feb 11, 2017

Re @bitcartel's point 3, I don't think it's a problem if zcbenchmark createjoinsplit doesn't pause mining. That RPC is intended to be used with a node (and machine, since it measures wall clock time) that is otherwise completely idle; just pausing mining on an active node would not be sufficient to get an accurate result.

@arcalinea
Copy link
Contributor

@aniemerg if we can fix @bitcartel's first point, then we'll merge and open another ticket to address point 4.
If we can fix the first point by mid-week, we'll include this in 1.0.7.

@aniemerg
Copy link
Contributor Author

@arcalinea commit 54c92a6 was intended to fix @bitcartel 's first point. I believe it still needs review.

Copy link
Contributor

@daira daira left a comment

Choose a reason for hiding this comment

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

utACK, but please squash when merging.

@arcalinea arcalinea force-pushed the 1522-pause-mining-for-joinsplit branch from 54c92a6 to 49c2cec Compare March 2, 2017 00:56
@arcalinea
Copy link
Contributor

arcalinea commented Mar 2, 2017

Squashed the commits. Can we get one more review before merging though? (@str4d?)

Copy link
Contributor

@str4d str4d left a comment

Choose a reason for hiding this comment

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

utACK, assuming a new ticket is opened for point 4.

@arcalinea
Copy link
Contributor

arcalinea commented Mar 2, 2017

Thanks. Opened ticket #2145 for point 4, merging

@zkbot r+

@zkbot
Copy link
Contributor

zkbot commented Mar 2, 2017

📌 Commit 49c2cec has been approved by arcalinea

@zkbot
Copy link
Contributor

zkbot commented Mar 2, 2017

⌛ Testing commit 49c2cec with merge 312fbd9...

zkbot added a commit that referenced this pull request Mar 2, 2017
…alinea

Pause mining during JoinSplit creation

Closes #1522 .
@zkbot
Copy link
Contributor

zkbot commented Mar 2, 2017

💡 This pull request was already approved, no need to approve it again.

  • This pull request is currently being tested. If there's no response from the continuous integration service, you may use retry to trigger a build again.

@zkbot
Copy link
Contributor

zkbot commented Mar 2, 2017

📌 Commit 49c2cec has been approved by arcalinea

@zkbot
Copy link
Contributor

zkbot commented Mar 2, 2017

☀️ Test successful - zcash

@zkbot zkbot merged commit 49c2cec into zcash:master Mar 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-pow Area: Proof-of-Work and mining I-performance Problems and improvements with respect to performance memory management S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants