-
Notifications
You must be signed in to change notification settings - Fork 37.4k
rpc: use CScheduler for HTTPRPCTimer #32796
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
base: master
Are you sure you want to change the base?
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/32796. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, 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. |
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.
lgtm ACK 7bc20b1
Could start title with rpc:
?
src/httprpc.cpp
Outdated
@@ -38,22 +42,16 @@ static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; | |||
class HTTPRPCTimer : public RPCTimerBase | |||
{ | |||
public: | |||
HTTPRPCTimer(struct event_base* eventBase, std::function<void()>& func, int64_t millis) : | |||
ev(eventBase, false, func) | |||
HTTPRPCTimer(NodeContext* context, std::function<void()>& func, int64_t millis) |
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.
HTTPRPCTimer(NodeContext* context, std::function<void()>& func, int64_t millis) | |
HTTPRPCTimer(NodeContext& context, std::function<void()>& func, int64_t millis) |
nit: When unconditionally and immediately dereferencing, it could make sense to disallow nullptr. You can achieve this, for example, by using *Assert(m_context)
in the constructor call below
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.
great comment thanks, taken
# CScheduler relies on condition_variable::wait_until() which is slightly | ||
# less accurate than libevent's event trigger. We'll give it 2 | ||
# seconds to execute a 1 second scheduled event. |
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.
7bc20b1
to
466722c
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.
lgtm ACK 466722c 🎱
Show signature
Signature:
untrusted comment: signature from minisign secret key on empty file; verify via: minisign -Vm "${path_to_any_empty_file}" -P RWTRmVTMeKV5noAMqVlsMugDDCyyTSbA3Re5AkUrhvLVln0tSaFWglOw -x "${path_to_this_whole_four_line_signature_blob}"
RUTRmVTMeKV5npGrKx1nqXCw5zeVHdtdYURB/KlyA/LMFgpNCs+SkW9a8N95d+U4AP1RJMi+krxU1A3Yux4bpwZNLvVBKy0wLgM=
trusted comment: lgtm ACK 466722cbe5d6c9ddf35d1590b749d19ec115684e 🎱
BIFmQ7bHKY+gQInqAOOTQFAXFxXQJHAH2aGv/XMhziokLGtp5GIeKdYYzaDYg9TthqPZmgwLUlYlQk4qGLzXDg==
src/httprpc.cpp
Outdated
}; | ||
|
||
class HTTPRPCTimerInterface : public RPCTimerInterface | ||
{ | ||
public: | ||
explicit HTTPRPCTimerInterface(struct event_base* _base) : base(_base) | ||
explicit HTTPRPCTimerInterface(const std::any& context) : m_context(std::any_cast<NodeContext*>(context)) |
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.
explicit HTTPRPCTimerInterface(const std::any& context) : m_context(std::any_cast<NodeContext*>(context)) | |
explicit HTTPRPCTimerInterface(const std::any& context) | |
: m_context{*Assert(std::any_cast<NodeContext*>(context))} |
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: Could probably assert early on construction, rather than when a timer is created, but either is equally fine.
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 taken this, thanks.
new constructor is
explicit HTTPRPCTimerInterface(const std::any& context)
: m_context{*Assert(std::any_cast<NodeContext*>(context))}
so its like "passed in an any
which i convert to a NodeContext
pointer which I assert is not null, then de-reference back to a NodeContext
and store that as a reference in the class
# CScheduler relies on condition_variable::wait_until() which is slightly | ||
# less accurate than libevent's event trigger. We'll give it 2 | ||
# seconds to execute a 1 second scheduled event. | ||
time.sleep(2) |
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.
if this turns out problematic (intermittently fail), one could also try mockscheduler
.
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.
Good idea, but would that reduce confidence in the test coverage for RPCRunLater()
etc?
This removes the dependency on libevent for scheduled events, like re-locking a wallet some time after decryption.
466722c
to
e70c208
Compare
re-ACK e70c208 💱 Show signatureSignature:
|
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
@@ -127,7 +127,10 @@ def run_test(self): | |||
nodes[0].keypoolrefill(3) | |||
|
|||
# test walletpassphrase timeout | |||
time.sleep(1.1) | |||
# CScheduler relies on condition_variable::wait_until() which is slightly | |||
# less accurate than libevent's event trigger. We'll give it 2 |
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.
Seems weird to mention libevent here as a point of reference since it's in the past after this change is applied. I would put this in the commit message and just say that it's not accurate enough here.
@@ -26,6 +28,8 @@ | |||
#include <string> | |||
#include <vector> | |||
|
|||
|
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: new blank line seems unnecessary
}; | ||
|
||
class HTTPRPCTimerInterface : public RPCTimerInterface | ||
{ | ||
public: | ||
explicit HTTPRPCTimerInterface(struct event_base* _base) : base(_base) | ||
explicit HTTPRPCTimerInterface(const std::any& context) | ||
: m_context{*Assert(std::any_cast<NodeContext*>(context))} |
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.
Did you consider avoiding the dependency to node context and just give the Inteface it's own CScheduler
instead?
This removes the dependency on libevent for events scheduled by RPC commands, like re-locking a wallet some time after decryption with
walletpassphrase
.This PR is cherry-picked from #32061 and is part of removing libevent from the project
This does result in a slightly less reliable timing compared to libevent as described in #32793. In the test I added a little bit more time for the event to execute. I don't think this a big deal but reviewers lemme know what you think.