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

"PSBT Operations" dialog #18027

Merged
merged 5 commits into from Jun 21, 2020
Merged

Conversation

gwillen
Copy link
Contributor

@gwillen gwillen commented Jan 30, 2020

Add a "PSBT Operations" dialog, reached from the "Load PSBT..." menu item, giving options to sign or broadcast the loaded PSBT as appropriate, as well as copying the result to the clipboard or saving it to a file.

This is based on Sjors' #17509, and depends on that PR going in first. (It effectively replaces the small "load PSBT" dialog from that PR with a more feature-rich one.)

Some notes:

  • The way I display status information is maybe unusual (a status bar, rather than messageboxes.) I think it's helpful to have the information in it be persistent rather than transitory. But if people dislike it, I would probably move the "current state of the transaction" info to the top line of the main label, and the "what action just happened, and did it succeed" info into a messagebox.
  • I don't really know much about the translation/localization stuff. I put tr() in all the places it seemed like it ought to go. I did not attempt to translate the result of TransactionErrorString (which is shared by GUI and non-GUI code); I don't know if that's correct, but it matches the "error messages in logs should be googleable in English" heuristic. I don't know whether there are things I should be doing to reduce translator effort (like minimizing the total number of distinct message strings I use, or something.)
  • I don't really know how (if?) automated testing is applied to GUI code. I can make a list of PSBTs exercising all the codepaths for manual testing, if that's the right approach. Input appreciated.

@fanquake fanquake added the GUI label Jan 30, 2020
Copy link
Member

@Sjors Sjors left a comment

Concept ACK

Code at b58e6f7 looks mostly alright, but Travis is very sad.

The first time I compiled this on macOS I get a cryptic error when I select the menu item:

2020-01-30 11:09:43.908 bitcoin-qt[619:453974] +[NSXPCSharedListener endpointForReply:withListenerName:]: an error occurred while attempting to obtain endpoint for listener 'com.apple.view-bridge': Connection interrupted

It worked fine the second time, so perhaps just some unrelated issue due to earlier code I compiled.

Schermafbeelding 2020-01-30 om 11 18 56

Ideally disable the sign button if there's nothing we can sign.

display status information is maybe unusual (a status bar, rather than messageboxes.)

I like it.

Currently this only changes the Load PSBT flow. Do you also want to apply this dialog to the send / bump fee flow? I'm fine with doing that later too.

You could also add a menu option to open a PSBT that's currently on the clipboard (e.g. handy when you need to save it as binary).

@@ -317,6 +317,8 @@ void BitcoinGUI::createActions()
signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
verifyMessageAction = new QAction(tr("&Verify message..."), this);
verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
m_load_psbt_action = new QAction(tr("Load PSBT..."), this);
Copy link
Member

@Sjors Sjors Jan 30, 2020

Choose a reason for hiding this comment

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

You should pick a letter to turn into the keyboard shortcut (works on some operating systems, not macOS). E.g. "&Load PSBT..." if L` isn't taken.

Copy link
Contributor Author

@gwillen gwillen Feb 1, 2020

Choose a reason for hiding this comment

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

Just went with L -- it's hard for me to check what's going on here since I'm on a Mac, but I don't see it as being taken. (I didn't add a shortcut for loading from clipboard, since L is taken, C is taken, I could use P for PSBT but it seems kind of unnatural.

@@ -0,0 +1,52 @@
// Copyright (c) 2011-2014 The Bitcoin Core developers
Copy link
Member

@Sjors Sjors Jan 30, 2020

Choose a reason for hiding this comment

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

Nit: fix year

Copy link
Contributor Author

@gwillen gwillen Feb 1, 2020

Choose a reason for hiding this comment

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

Done.

@@ -14,7 +14,7 @@ std::string TransactionErrorString(const TransactionError err)
case TransactionError::OK:
return "No error";
case TransactionError::MISSING_INPUTS:
return "Missing inputs";
return "Inputs missing or spent";
Copy link
Member

@Sjors Sjors Jan 30, 2020

Choose a reason for hiding this comment

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

Cleaning these error messages could probably be its own commit.

Copy link
Contributor Author

@gwillen gwillen Jan 30, 2020

Choose a reason for hiding this comment

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

Yeah, agreed, will fix.


switch (analysis.next) {
case PSBTRole::UPDATER: {
showStatus(tr("Transaction is missing some information about inputs."), StatusLevel::WARNING);
Copy link
Member

@Sjors Sjors Jan 30, 2020

Choose a reason for hiding this comment

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

I wonder if these strings can be moved to a place where the RPC can also use them.

Copy link
Contributor Author

@gwillen gwillen Jan 30, 2020

Choose a reason for hiding this comment

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

That would make sense actually, yeah. I could move them to wherever AnalyzePSBT is. What would the impact of this be on translation issues? I know that tr() is only used for GUI strings, and _() is used for non-GUI strings -- is there precedent for shared strings?

Copy link
Member

@Sjors Sjors Feb 1, 2020

Choose a reason for hiding this comment

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

I'm not sure actually. @laanwj, @hebasto?

Copy link
Member

@hebasto hebasto Feb 1, 2020

Choose a reason for hiding this comment

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

@gwillen

I know that tr() is only used for GUI strings, and _() is used for non-GUI strings -- is there precedent for shared strings?

Actually, bilingual_str type from util/translation.h supports both original and translated strings. More details are available in #16362 and #16224.

You could use something like this:

#include <util/translation.h>

bilingual_str bs = _("Transaction is missing some information about inputs.");
showStatus(bs.translated, StatusLevel::WARNING);
LogPrintf(bs.original);

return tx_description.toStdString();
}

void PSBTOperationsDialog::showStatus(const QString &msg, StatusLevel level) {
Copy link
Member

@Sjors Sjors Jan 30, 2020

Choose a reason for hiding this comment

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

Should we create a OperationsDialog class to make this stuff reusable? (can wait of course)

Copy link
Contributor Author

@gwillen gwillen Jan 30, 2020

Choose a reason for hiding this comment

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

I'm happy to go either way, are there other existing dialogs we'd immediately want to adopt it for? I do like it better than messageboxes, I tried to make it as drop-in as possible a replacement for them.


#include <iostream>

size_t CountPSBTUnsignedInputs(const PartiallySignedTransaction &psbt) {
Copy link
Member

@Sjors Sjors Jan 30, 2020

Choose a reason for hiding this comment

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

Maybe move this to psbt.h?

Copy link
Contributor Author

@gwillen gwillen Jan 30, 2020

Choose a reason for hiding this comment

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

Can do, was dithering about what to do with it.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 30, 2020

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

No conflicts as of last run.

@gwillen
Copy link
Contributor Author

gwillen commented Jan 30, 2020

Ideally disable the sign button if there's nothing we can sign.

Can I determine that without actually trying to sign? I was assuming that (1) I cannot, and (2) I shouldn't try to actually sign for real just to see if it works. (Or do you mean just disable the button at the point where we are asked to sign, try, and fail?)

Currently this only changes the Load PSBT flow. Do you also want to apply this dialog to the send / bump fee flow? I'm fine with doing that later too.

I'd rather do that separately, I am trying really hard to cure myself of the disease of biting off way more than I can reasonably do in one go.

You could also add a menu option to open a PSBT that's currently on the clipboard (e.g. handy when you need to save it as binary).

This I'd be happy to add, since it's a very small change. Just another item below "Load PSBT...", perhaps "Load PSBT from clipboard..."?

@Sjors
Copy link
Member

Sjors commented Jan 30, 2020

I indeed wouldn't try actually signing. But you e.g. tell if a wallet is watch-only, and the new ScriptPubKeyManager's can tell if they can sign for things.

@gwillen
Copy link
Contributor Author

gwillen commented Jan 30, 2020

Aha, and the Travis failure is the same issue we were talking about yesterday in #bitcoin-core-dev, I got scooped by #17261 and need to rebase again and fix errors, will do. EDIT: Oh, I think actually the Travis failure is just because master was already failing Travis at the moment I made the PR. So I think it will pass as soon as I push again.

@gwillen
Copy link
Contributor Author

gwillen commented Feb 1, 2020

Ok, I'm adding a check so that we do not enable the sign button (and we show a helpful note) if the current wallet is privateKeysDisabled().

I would like to use ScriptPubKeyMan to get a better verdict, but it doesn't seem like the functionality I need is quite there. It looks like what I want is something like CWallet::GetSigningProvider, which calls CanProvide on each ScriptPubKeyMan in the wallet; except that the implementation of LegacyScriptPubKeyMan::CanProvide looks like it can return true in cases where we can't actually sign, but "We can still provide some stuff if we have the script". So I can't tell if there's a call I can make that just answers the question "do we believe that this wallet can sign", without myself looping over all our ScriptPubKeyMans, and trying ProduceSignature with each with a DUMMY_SIGNATURE_CREATOR. Obviously if this is true, a better approach would be to enhance the CWallet/ScriptPubKeyMan interface to provide this, but I think that's best left for another PR. (Or if this is already provided and I'm not seeing how, please fill me in.)

@gwillen
Copy link
Contributor Author

gwillen commented Feb 1, 2020

Actually, here's an approach that seems like it should work -- FillPSBT already does basically all this work for us, since it does all the signing using a HidingSigningProvider, and allows us to tell it not to sign. So if I correctly understand the behavior of HidingSigningProvider, I think this should already tell us how many inputs we could sign, it just doesn't expose the result. If that seems correct to you, I can expose that from FillPSBT, and determine that way where there's anything for us to do here. @Sjors do you know whether this sounds correct?

EDIT: No, this does not work. LegacyScriptPubKeyMan::CanProvide is playing some clever games with ProduceSignature in order to answer the "could we sign" question, and I don't want to duplicate those clever games into the PSBT logic.

SON OF EDIT: Ok, a slightly different method does work -- in FillPSBT we can effectively check whether keys are available by whether pwallet->GetSigningProvider returns anything. This ultimately calls LegacyScriptPubKeyMan::CanProvide, which has the apparent issue I described above -- it says it returns true if we don't have keys, but we do have the script -- but I don't understand exactly what that means to try to produce an example that would confuse it.

I do at least have something that works on the obvious cases now.

@gwillen gwillen force-pushed the feature-psbt-ops-dialog branch from b58e6f7 to 078e3ca Compare Feb 1, 2020
@gwillen
Copy link
Contributor Author

gwillen commented Feb 1, 2020

Updated:

  • Disable sign button unless !privateKeysDisabled() and GetSigningProvider() != nullptr (I'm not sure how perfect a proxy that is for "we can sign" but it worked on my positive and negative test cases.)
  • Added "load from clipboard" option.
  • Added shortcut key in menu.
  • Separated error message fixes into their own commit.
  • Moved CountPSBTUnsignedInputs into psbt.h.

Did not change:

  • Send/bumpfee flow (would rather save for another PR)
  • Factoring out PSBT completeness description strings (not a bad idea, but could someone advise me on how that interacts with translation?)
  • Factoring out "OperationsDialog" (would probably rather save for another PR, and would like to understand where else we might use it first.)

Other notes:

  • Regarding the transient error Sjors got when clicking the menu item, all I can find when googling is that it's some transient issue that shows up for some people on OS X Catalina in multiple apps, with no obvious cause. I have no real insight there.

Please take another look?

@promag
Copy link
Member

promag commented Feb 3, 2020

Concept ACK.

@gwillen gwillen force-pushed the feature-psbt-ops-dialog branch from 078e3ca to 3e7ca1e Compare Feb 8, 2020
@gwillen
Copy link
Contributor Author

gwillen commented Feb 8, 2020

Speculatively attempting to fix the Windows-only fails without a Windows machine to test on. It looks like MinGW defines "ERROR" as a macro, so I can't give an enum constant that name. And it looks like the Visual Studio project file for building Bitcoin-QT is not autogenerated from the Makefiles, but has to be manually updated, so I've attempted to update it.

luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Feb 9, 2020
In FillPSBT, optionally report the number of inputs we successfully
signed, as an out parameter. If "sign" is false, instead report the
number of inputs for which GetSigningProvider does not return nullptr.
(This is a potentially overbroad estimate of inputs we could sign.)

Github-Pull: bitcoin#18027
Rebased-From: 665c8e6
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Feb 9, 2020
Add a "PSBT Operations" dialog, reached from the "Load PSBT..." menu
item, giving options to sign or broadcast the loaded PSBT as
appropriate, as well as copying the result to the clipboard or saving
it to a file.

Github-Pull: bitcoin#18027
Rebased-From: 3a9939c
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Feb 9, 2020
Sjors
Sjors approved these changes Feb 10, 2020
Copy link
Member

@Sjors Sjors left a comment

tACK 3e7ca1e (conditional on original PR being merged)

Would be nice to add change detection in the PSBT summary, but it can wait for a followup.

showStatus(tr("Transaction is missing some information about inputs."), StatusLevel::WARN);
break;
}
case PSBTRole::SIGNER: {
Copy link
Member

@Sjors Sjors Feb 10, 2020

Choose a reason for hiding this comment

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

When all inputs have "next": "finalizer" the transaction itself may still be "next": "signer". This seems to be a bug (@achow101 or feature?) in analyzepsbt. If it's a bug, we can ignore it for this PR, if it's a feature, we should handle it, though imo it can wait for a followup.

Copy link
Contributor Author

@gwillen gwillen Feb 12, 2020

Choose a reason for hiding this comment

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

I am going to assume this is a bug, so I'm happy to push to a followup. I have been tempted to try to rewrite the flow of AnalyzePSBT, with an eye to simplifying it and making its correctness easier to check.

Copy link
Member

@achow101 achow101 Feb 27, 2020

Choose a reason for hiding this comment

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

Sounds like a bug

Copy link
Member

@Sjors Sjors Feb 28, 2020

Choose a reason for hiding this comment

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

@laanwj
Copy link
Member

laanwj commented Feb 10, 2020

Concept ACK!

@Sjors
Copy link
Member

Sjors commented Feb 12, 2020

Mmm, it's misinterpreting a 2-of-3 multisig with two signed outputs. Probably related to my earlier comment. This is more annoying though, because it means I can't broadcast without the third signature.
Schermafbeelding 2020-02-12 om 19 30 41

@gwillen
Copy link
Contributor Author

gwillen commented Feb 12, 2020

@Sjors are you able to supply me with an exact process to reproduce this? (Or an exact description -- is this a 2-of-3 using keys A, B, C, where both A and B have already signed, and you have C in your wallet, so it should be signable?)

I don't think I'm relying on analyzepsbt for this determination -- I will have to look back at the code, but I should be saying that we can sign as long as GetSigningProvider does not return nullptr. So this might just be a simple bug, or I might have misunderstood something fundamental about when we can and can't sign, but either way I'll take a look, thanks!

@Sjors
Copy link
Member

Sjors commented Feb 12, 2020

It's a watch-only wallet with a 2-of-3 multisig (three hardware wallets). Two of them signed.

You probably want to call finalize on a copy of the PSBT just to see if it's complete.

@gwillen
Copy link
Contributor Author

gwillen commented Feb 12, 2020

What is it misinterpreting? That is, what do you expect it to say? (If it's a watch-only wallet, then "this wallet does not have the right keys" should really say "this wallet cannot make signatures", because it's supposed to check privateKeysDisabled() first.)

@Sjors
Copy link
Member

Sjors commented Feb 12, 2020

The Broadcast Transaction button should not be disabled. I can finalize it with the RPC and testmempoolaccept is happy. The rest of the info is fine I suppose.

gwillen added 3 commits Jun 19, 2020
Add a "PSBT Operations" dialog, reached from the "Load PSBT..." menu
item, giving options to sign or broadcast the loaded PSBT as
appropriate, as well as copying the result to the clipboard or saving
it to a file.
@gwillen gwillen force-pushed the feature-psbt-ops-dialog branch from ca2144f to 931dd47 Compare Jun 19, 2020
@gwillen
Copy link
Contributor Author

gwillen commented Jun 19, 2020

It seems like @jb55's issue is consistent with FillPSBT not finalizing the transaction like I expected that it would, variably depending on which wallet is loaded. (@jb55, is one or both of the wallets a descriptor wallet by any chance?) FinalizePSBT calls SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, SIGHASH_ALL); on every input, whereas FillPSBT seems to bottom out in calls to SignPSBTInput(HidingSigningProvider([some signing provider], !sign, !bip32derivs), psbtx, i, sighash_type);. I would have hoped those would ultimately do the same thing, but this code is twisty, dark and deep... (And I'm nervous about the way that the ScriptPubKeyMan interface results in a somewhat complex web of signing logic getting semi-duplicated across each SPKM implementation. The wallet signing logic was just about beyond my comprehension already, before the addition of another layer.)

There are really two issues: (1) we're trying to finalize the transaction when we load it, so that we know whether it's ready or not, but failing. (2) our two information sources are not in sync (one of them we are calculating directly, the other we are getting from AnalyzePSBT, which appears to do its own finalization when checking if all signatures are present.)

I think I called FillPSBT because I wanted to know whether it thinks the PSBT is complete, and I assumed it would finalize in the process (and I think this might have been true before the SPKM refactor, though I'm not really very sure.)

So I think the fix to (1) is for me to add a call to FinalizePSBT in openWithPSBT before I call fillPSBT, which I have just done. And as for (2) I think it's okay to ignore it for now (it's not ideal that we can theoretically display conflicting information like this, but it's purely a display issue and shouldn't happen unless something else is buggy.)

The fix is harmless even if I'm wrong, so I think it's okay to call it good at this point. But I would still really really like a repro test case to play with, @jb55. (If I have correctly deduced fillPSBT's behavior, I find it surprising.)

Can we officially declare this PR done and ready (and pray that this is the last time it will need a rebase?) :-)

@instagibbs
Copy link
Member

instagibbs commented Jun 19, 2020

concept ACK fix, going to test again

@instagibbs
Copy link
Member

instagibbs commented Jun 19, 2020

tested ACK 931dd47

Tested across multiple Core wallets and HWI

@Sjors
Copy link
Member

Sjors commented Jun 19, 2020

re-tACK 931dd47

@jonatack
Copy link
Member

jonatack commented Jun 19, 2020

Concept ACK

Copy link
Member

@achow101 achow101 left a comment

ACK 931dd47

@@ -617,6 +620,14 @@ TransactionError LegacyScriptPubKeyMan::FillPSBT(PartiallySignedTransaction& psb
SignatureData sigdata;
input.FillSignatureData(sigdata);
SignPSBTInput(HidingSigningProvider(this, !sign, !bip32derivs), psbtx, i, sighash_type);

bool signed_one = PSBTInputSigned(input);
if (n_signed && (signed_one || !sign)) {
Copy link
Member

@achow101 achow101 Jun 19, 2020

Choose a reason for hiding this comment

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

The intent is to indicate whether signing happened, or whether we could sign. But this is really checking whether we could finalize, which may include signing. For instance, this wouldn't work if the input were multisig.

But that might be ok for this PR.

To reduce code duplication, maybe this should go inside SignPSBTInput?

Copy link
Contributor Author

@gwillen gwillen Jun 19, 2020

Choose a reason for hiding this comment

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

I'm very interested in a conversation about refactoring some of this stuff. Ok to save for another PR?

Copy link
Contributor Author

@gwillen gwillen Jun 19, 2020

Choose a reason for hiding this comment

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

(I am interested both in (1) reducing code duplication and (2) working out more precisely whether we can sign something, which I found to be very difficult to actually compute, and I definitely recognize this as a conservative approximation.)

Copy link
Member

@achow101 achow101 Jun 19, 2020

Choose a reason for hiding this comment

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

Ok to save for another PR?

Yep

@jb55
Copy link
Contributor

jb55 commented Jun 20, 2020

ACK 931dd47

@meshcollider
Copy link
Contributor

meshcollider commented Jun 21, 2020

Concept ACK, glanced at the code, looks RTM

@meshcollider meshcollider merged commit c273308 into bitcoin:master Jun 21, 2020
3 checks passed
Copy link
Member

@jonatack jonatack left a comment

Light code review and partially tested ACK 931dd47

Good to see this move forward and looking forward to continued progress as described in #18027 (comment). A couple of nits for the next PR follow, no need to respond to them.

bool signed_one = PSBTInputSigned(input);
if (n_signed && (signed_one || !sign)) {
// If sign is false, we assume that we _could_ sign if we get here. This
// will never have false negatives; it is hard to tell under what i
Copy link
Member

@jonatack jonatack Jun 22, 2020

Choose a reason for hiding this comment

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

nit: s/what i/what/ here and at line 2136 below

@@ -11,6 +11,7 @@
#include <qt/askpassphrasedialog.h>
#include <qt/clientmodel.h>
#include <qt/guiutil.h>
#include <qt/psbtoperationsdialog.h>
Copy link
Member

@jonatack jonatack Jun 22, 2020

Choose a reason for hiding this comment

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

nit: sort

MarcoFalke added a commit that referenced this pull request Jun 24, 2020
….cpp

4f9d9ef qt: Remove needless headers (Hennadii Stepanov)

Pull request description:

  No symbols from the removed headers are used in the `qt/walletview.cpp`.

  This is a small followup of #18027.

Top commit has no ACKs.

Tree-SHA512: 986ed5c8f3bac4c0053736ce84d738f8593d3dbf713109af3cb9b7051cd838f23152a39bb3c1e9694a993c4e7accf14e94e5beff5e7881155638cd44fbf7f46f
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Aug 15, 2020
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 27, 2021
….cpp

4f9d9ef qt: Remove needless headers (Hennadii Stepanov)

Pull request description:

  No symbols from the removed headers are used in the `qt/walletview.cpp`.

  This is a small followup of bitcoin#18027.

Top commit has no ACKs.

Tree-SHA512: 986ed5c8f3bac4c0053736ce84d738f8593d3dbf713109af3cb9b7051cd838f23152a39bb3c1e9694a993c4e7accf14e94e5beff5e7881155638cd44fbf7f46f
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 28, 2021
….cpp

4f9d9ef qt: Remove needless headers (Hennadii Stepanov)

Pull request description:

  No symbols from the removed headers are used in the `qt/walletview.cpp`.

  This is a small followup of bitcoin#18027.

Top commit has no ACKs.

Tree-SHA512: 986ed5c8f3bac4c0053736ce84d738f8593d3dbf713109af3cb9b7051cd838f23152a39bb3c1e9694a993c4e7accf14e94e5beff5e7881155638cd44fbf7f46f
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Jun 29, 2021
….cpp

4f9d9ef qt: Remove needless headers (Hennadii Stepanov)

Pull request description:

  No symbols from the removed headers are used in the `qt/walletview.cpp`.

  This is a small followup of bitcoin#18027.

Top commit has no ACKs.

Tree-SHA512: 986ed5c8f3bac4c0053736ce84d738f8593d3dbf713109af3cb9b7051cd838f23152a39bb3c1e9694a993c4e7accf14e94e5beff5e7881155638cd44fbf7f46f
PastaPastaPasta pushed a commit to PastaPastaPasta/dash that referenced this pull request Sep 17, 2021
….cpp

4f9d9ef qt: Remove needless headers (Hennadii Stepanov)

Pull request description:

  No symbols from the removed headers are used in the `qt/walletview.cpp`.

  This is a small followup of bitcoin#18027.

Top commit has no ACKs.

Tree-SHA512: 986ed5c8f3bac4c0053736ce84d738f8593d3dbf713109af3cb9b7051cd838f23152a39bb3c1e9694a993c4e7accf14e94e5beff5e7881155638cd44fbf7f46f
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
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.

None yet