-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
wallet: early listener set #5355
Conversation
The wallet api is not really something I pay much attention to, ask the GUI people. I think currently it's dsc mostly. I'm OK with the patch myself, and if nobody from the GUI comments it'll go in. |
After giving it a second thought I think this is an easy way to handle device init stuff (like passphrase entry on host) without any massive refactoring. @MaxXor @xmrdsc ? Do you think it can be approved? :) |
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
The GUI PR which makes use of this PR is here: monero-project/monero-gui#2037 |
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
Looks fine to me - does not seem to influence existing behaviour from the perspective of the GUI. |
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
Looks good to me as well! |
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
How is the lifetime of the wallet pointer handled? This should be a |
@vtnerd TBH I don't see an easy way a Moreover, callbacks usually don't hold strong references to the owners to avoid circular references, right? I thought that the callback doesn't use the wallet pointer unless it is invoked by the wallet itself - pointer should be valid in that case. Currently, I see only one alternative - call Or how do you think this could work? I am out of easy ideas right now. |
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
@vtnerd ping |
As the changes look good for GUI guys, can we maybe approve pls ? :) |
I said "Looks fine to me" in the sense that you found a solution that does not require changes to our existing logic in the GUI, which is nice. I cannot really vouch for the quality of C++ itself - others are more experienced :) |
Improving the wallet pointer lifetimes are likely out-of-scope for this patch and should be slowly updated to improve lifetime guarantees of pointers. Using smart pointers for this listener parameter are possible I think. The GUI PR creates the listener on the stack, which gets destroyed when the function leaves scope. Doesn't that cause a dangling reference? It might be working based that block of code if the memory is not re-used. It looks like you want sole ownership of the listener? The semantics aren't clear at all from this change. Just take the listener by
|
I agree that it could be improved, but not by this patch. The callback is reset to a new valid callback as the wallet is created. Callback needs to exist only while wallet is being created / restored. It is reset after that by the manager.
I do not require sole ownership, that would be unnecessary limitation. Callback could be manager itself. Listener is already in API as plain pointer, that would break the GUI. Shared_ptr could deallocate pointer which cannot be deallocated because it could be owned by GUI (plain pointer breaks relation).
Sure, I know. But I have no idea how that helps without refactoring smart pointers for listener. Could you maybe scratch the idea in pseudocode how that would work? |
This will be difficult to maintain - the chunk of code creating a temporary listener has to rely on a sequence of events elsewhere and it won't be obvious to someone modifying that constructor about a dangling reference possibility in some other arbitrary file. In this particular situation the dangling reference modification is probably unlikely to happen, but this type of brittleness is a common way to introduce UB through maintenance. At a glance it seems like there has to be a way to update the construction sequence going on here - a temporary listener just during construction is odd - but that might require some decent re-arranging.
What exactly? How to use Use |
One thing to make certain - if |
This PR only adds an option to set a listener during the wallet creation. Previosly, it was allowed only after the creation, but in the same way (raw pointer). So it is basically the same logic. Temporary listener is thing of GUI PR which handles the temporary nature in the GUI Wallet contructor. But thats maybe for a different GUI PR discussion.
Hmm and that's a problematic point, I think. We would basically force all wallet API users to migrate to smart pointers on listeners with this PR. The smart pointers proposition breaks backward compatibility on the public API which maybe should not happen besides major version change. GUI is one known API user but there may be others (e.g., exchanges?). Take simplewallet as an example (not API related, just as a design choice). It is itself a listener. By the smart pointers change we would force the simplewallet creator to use smart pointer for storing simplewallet. Adding smart pointer would break API user logic as they deallocate listeners on their own now (probably). I would like to avoid introducing API-breaking changes, which are probably more dangerous for third parties. |
The listener is set to the wallet so it could be both permanent and temporary. Temporary justifies its purpose by allowing to catch passphrase request during wallet creation with existing API without any major overhaul needed. Permanent could be set by the API user. In fact this PR does not make a difference whether it is temporary or permanent. GUI PR uses it as temporary because their own code // src/libwalletqt/WalletManager.cpp
m_currentWallet = new Wallet(w); takes ownership of I mean the way this PR works is in line with existing API which also takes listener as raw pointer. So there are no logic changes in that. Adding smart pointers to one place and breaking API with it is IMO dangerous. |
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
- passphrase entry on host added, requires early listener setting monero-project/monero#5355 - wallet open and create from device shows splash to indicate possible long process - create from device is async to support passphrase entry
@vtnerd do you think that the newest changes I've made address objections you've had? |
@moneromooo-monero what do you think? |
I assume you meant the
The changes should be minimal for upstream, but it is difficult to say with certainty.
I don't see where
The primary frustration as a reviewer was having to dig through the implementation to try and determine how the lifetime of the pointers are supposed to work (who was supposed to be responsible for cleanup, etc.). It seems that the pointer lifetime is managed by the client who must destroy the
Taking ownership of
Part of my feedback was giving recommendations for future changes/directions, not necessarily immediately requesting changes. Using smart ptrs generally helps with guidance on ownership in the absence of explicit documentation. |
Correct, this one. I hope it makes it more clear and safer.
I had to dig it too, it seems that
Thanks for the feedback anyway! I like using smart pointers and taking inspiration from other developers. This definitely could be place to refactor next time. |
(rebased) |
I've added simple user action request tracking which is helpful for GUI - to let user know that action on the device is required. GUI needs also callback on button pressed event e.g., to hide processing splash (as user action was already performed). @moneromooo-monero do you pls think this PR could go in? 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.
Reviewed
API changes to enable passphrase entry on host via API (e.g., for GUI) - callback triggers request for passphrase if required. If callback is set before opening / creating wallet from a device it can set the passphrase to the device.
I had to add another callback method to set wallet obj after it is created as callbacks usually need to hold it.
@moneromooo-monero what do you think about this approach?