8000 wallet, tests: Expand and test when the blank wallet flag should be un/set by achow101 · Pull Request #25634 · bitcoin/bitcoin · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

wallet, tests: Expand and test when the blank wallet flag should be un/set #25634

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

Merged
merged 3 commits into from
Jun 14, 2023

Conversation

achow101
Copy link
Member
@achow101 achow101 commented Jul 18, 2022

The blank wallet flag is used to indicate that the wallet intentionally does not have any keys, scripts, or descriptors, and it prevents the automatic generation of those things for such a wallet. Once the wallet contains any of those data, it is unnecessary, and possibly incorrect, to have blank set. This PR fixes a few places where this was not properly happening. It also adds a test for this unset behavior.

@DrahtBot
Copy link
Contributor
DrahtBot commented Jul 18, 2022

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

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK S3RK, ryanofsky
Concept ACK ishaanam
Stale ACK furszy, aureleoules, Xekyo, pablomartin4btc

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #27827 ([Silent Payments]: Base functionality by josibake)
  • #20892 (tests: Run both descriptor and legacy tests within a single test invocation by achow101)

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.

@aureleoules
Copy link
Contributor

Concept ACK

Copy link
Member
@pablomartin4btc pablomartin4btc 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, I'll perform some testing soon.

Copy link
Member
@furszy furszy left a comment

Choose a reason for hiding this comment

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

Code review ACK 4c936c8

Copy link
Contributor
@aureleoules aureleoules left a comment

Choose a reason for hiding this comment

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

ACK 4c936c8

Copy link
Contributor
@ishaanam ishaanam 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
This looks good for the most part, I just have a question about the test.

Comment on lines 92 to 107
8000 assert_equal(expected, wallet.listdescriptors())
assert expected["descriptors"][0] in wallet.listdescriptors()["descriptors"]

self.log.info('Test list private descriptors with encrypted wallet')
assert_raises_rpc_error(-13, 'Please enter the wallet passphrase with walletpassphrase first.', wallet.listdescriptors, True)
wallet.walletpassphrase(passphrase="pass", timeout=1000000)
assert_equal(expected_private, wallet.listdescriptors(True))
assert expected_private["descriptors"][0] in wallet.listdescriptors(True)["descriptors"]
Copy link
Contributor

Choose a reason for hiding this comment

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

In 44e30c5 "wallet: Ensure that the blank wallet flag is unset after imports"

It is not clear to me how the other changes in this PR result in this behavior change. Especially since it appears to only be happening once a wallet is encrypted. After the changes in this PR, running listdescriptors before a wallet is encrypted produces drastically different results than when it is run afterwards.
listdescriptors before the wallet is encrypted:

{'wallet_name': 'w2', 'descriptors': [{'desc': "wpkh([80002067/84'/1'/0']tpubDCMVLhErorrAGfApiJSJzEKwqeaf2z3NrkVMxgYQjZLzMjXMBeRw2muGNYbvaekAE8rUFLftyEar4LdrG2wXyyTJQZ26zptmeTEjPTaATts/0/*)#yz2uu6mw", 'timestamp': 1296688602, 'active': False, 'range': [0, 0], 'next': 0}]}

listdescriptors after the wallet is encrypted:

{'wallet_name': 'w2', 'descriptors': [{'desc': "wpkh([80002067/84'/1'/0']tpubDCMVLhErorrAGfApiJSJzEKwqeaf2z3NrkVMxgYQjZLzMjXMBeRw2muGNYbvaekAE8rUFLftyEar4LdrG2wXyyTJQZ26zptmeTEjPTaATts/0/*)#yz2uu6mw", 'timestamp': 1296688602, 'active': False, 'range': [0, 0], 'next': 0}, {'desc': "pkh([5dc1e209/44'/1'/0']tpubDDfjWivrLDGEU679nu8YgTDPUALX9bUppvdXXk19TDAaecSNxMH8vPZBeRRjaDqKUYgEd3UzZWS4rt5qsAWQW2qktupQZR1MnSnAZ7L85Cn/0/*)#rx0cg4z2", 'timestamp': 1668205361, 'active': True, 'internal': False, 'range': [0, 0], 'next': 0}, {'desc': "wpkh([5dc1e209/84'/1'/0']tpubDD42XKtjCmM9u18pwcFj5VNPoh4QZn6fDuHq5ypo5ZvZrsMguRRd5YvDjKX6BLKz393V9QpeouE95eHeaugv3FM6LVqTo9f2phTPQvw65xy/0/*)#q3r4f8hn", 'timestamp': 1668205361, 'active': True, 'internal': False, 'range': [0, 0], 'next': 0}, {'desc': "pkh([5dc1e209/44'/1'/0']tpubDDfjWivrLDGEU679nu8YgTDPUALX9bUppvdXXk19TDAaecSNxMH8vPZBeRRjaDqKUYgEd3UzZWS4rt5qsAWQW2qktupQZR1MnSnAZ7L85Cn/1/*)#jj2e4qjj", 'timestamp': 1668205361, 'active': True, 'internal': True, 'range': [0, 0], 'next': 0}, {'desc': "sh(wpkh([5dc1e209/49'/1'/0']tpubDCVSqsf6kfUFDo28Vq3Lsrt9FXVqtohxWFxufkxubWT4Kh9z5RfmcxZmgKPBsWvboazFWNqnA9YHmQNrtfCvxTU8mch4yzxcMshqCWXtt9u/0/*))#8s9y4eu7", 'timestamp': 1668205361, 'active': True, 'internal': False, 'range': [0, 0], 'next': 0}, {'desc': "tr([5dc1e209/86'/1'/0']tpubDDMfjHg7VtGGjDiXv3ohgm7NTpm6ue5XnXdJBx9NZ8PgrSdLAQ1DjnYnxNiQKJcB6ZaoQo7WjZo7iTXVzdBgW38KM5BRsJJzXtDUSSjehRU/0/*)#60q6ankn", 'timestamp': 1668205361, 'active': True, 'internal': False, 'range': [0, 0], 'next': 0}, {'desc': "tr([5dc1e209/86'/1'/0']tpubDDMfjHg7VtGGjDiXv3ohgm7NTpm6ue5XnXdJBx9NZ8PgrSdLAQ1DjnYnxNiQKJcB6ZaoQo7WjZo7iTXVzdBgW38KM5BRsJJzXtDUSSjehRU/1/*)#tm9mqxxt", 'timestamp': 1668205361, 'active': True, 'internal': True, 'range': [0, 0], 'next': 0}, {'desc': "sh(wpkh([5dc1e209/49'/1'/0']tpubDCVSqsf6kfUFDo28Vq3Lsrt9FXVqtohxWFxufkxubWT4Kh9z5RfmcxZmgKPBsWvboazFWNqnA9YHmQNrtfCvxTU8mch4yzxcMshqCWXtt9u/1/*))#j3tjdxfp", 'timestamp': 1668205361, 'active': True, 'internal': True, 'range': [0, 0], 'next': 0}, {'desc': "wpkh([5dc1e209/84'/1'/0']tpubDD42XKtjCmM9u18pwcFj5VNPoh4QZn6fDuHq5ypo5ZvZrsMguRRd5YvDjKX6BLKz393V9QpeouE95eHeaugv3FM6LVqTo9f2phTPQvw65xy/1/*)#39x55j8t", 'timestamp': 1668205361, 'active': True, 'internal': True, 'range': [0, 0], 'next': 0}]}

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. This seems like a bug. I was able to trace it back to encryption function

src/wallet/wallet.cpp:829

        // If we are using descriptors, make new descriptors with a new seed
        if (IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS) && !IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET)) {
            SetupDescriptorScriptPubKeyMans();

@achow101 why do we want to regenerate descriptors on encryption?

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, yes, I'm not sure whether this is a bug as it the behavior is (mostly) expected.

We always want to rotate keys after encryption because the old keys were written to disk unencrypted and thus may have been compromised. There may also be backups of the unencrypted keys. So if the user has opted into encryption, we want to make sure any keys they use from then on were born encrypted and known to not have been stored anywhere unencrypted. We do the same for the legacy wallet as well.

The question here is whether this behavior is expected for formerly blank wallets.

Copy link
Contributor

Choose a reason for hiding this comment

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

I personally wouldn't expect to see new descriptors after encrypting wallet with an imported descriptor. But I also understand why rotating descriptors is generally good.

I don't think distinction of "formerly blank wallets" is good enough. The same problem can happen with non-blank wallet. Should we rotate user imported descriptors in non-blank wallets? The current code would rotate it as well.

It seems like we need to track which descriptors are automatically generated and which are manually imported. Of course, the problem is that we can't backfill the information.

Copy link
Member Author

Choose a reason for hiding this comment

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

Should we rotate user imported descriptors in non-blank wallets? The current code would rotate it as well.

Yes. This is considered an important aspect of encryption as it ensures that addresses used afterwards did not have their private keys written unencrypted. It is also a well documented behavior in both the RPC and GUI.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is considered an important aspect of encryption as it ensures that addresses used afterwards did not have their private keys written unencrypted.

This makes sense, but in this case shouldn't new private keys only be generated for the descriptors that already exist in the wallet (imported or automatically generated) instead of adding additional descriptors to the wallet that the user did not ask for? Even if rotating keys upon encryption is well documented, adding additional descriptors does not appear to be.

Copy link
Member Author

Choose a reason for hiding this comment

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

This makes sense, but in this case shouldn't new private keys only be generated for the descriptors that already exist in the wallet (imported or automatically generated) instead of adding additional descriptors to the wallet that the user did not ask for? Even if rotating keys upon encryption is well documented, adding additional descriptors does not appear to be.

This can get rather complicated since users can import descriptors that don't match the same pattern as our automatically generated ones, and producing ones that look similar except for the keys might be more confusing than ones that are altogether different? At least for non-single key things, it would be very obvious that the descriptor has changed.

This is also perhaps an argument for always encrypting wallets with a default passphrase which would completely sidestep that issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

Seeing as most of the solutions to this issue/confusion are likely out of the scope of this PR, I think that these changes should be fine with the addition of documentation about this behavior change related to importing descriptors before encrypting a wallet, since previously no new descriptors would be added.

Copy link
Contributor

Choose a reason for hiding this comment

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

Change to unset the blank flag when writing a descriptor is now reverted, so I think this makes BLANK flag documentation misleading, and could be fixed with:

--- a/src/wallet/walletutil.h
+++ b/src/wallet/walletutil.h
@@ -53,10 +53,18 @@ enum WalletFlags : uint64_t {
     //! Flag set when a wallet contains no HD seed and no private keys, scripts,
     //! addresses, and other watch only things, and is therefore "blank."
     //!
-    //! The only function this flag serves is to distinguish a blank wallet from
+    //! The main function this flag serves is to distinguish a blank wallet from
     //! a newly created wallet when the wallet database is loaded, to avoid
     //! initialization that should only happen on first run.
     //!
+    //! A secondary function of this flag, which applies to descriptor wallets
+    //! only, is to serve as an ongoing indication that descriptors in the
+    //! wallet should be created manually, and that the wallet should not
+    //! generate automatically generate new descriptors if it is later
+    //! encrypted. To support this behavior, descriptor wallets unlike legacy
+    //! wallets do not automatically unset the BLANK flag when things are
+    //! imported.
+    //!
     //! This flag is also a mandatory flag to prevent previous versions of
     //! bitcoin from opening the wallet, thinking it was newly created, and
     //! then improperly reinitializing it.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've added a commit with this comment.

@S3RK
Copy link
Contributor
S3RK commented Nov 15, 2022

Thinking about this I've got a question:
Do we even need to store a flag for a blank wallet? Can't we just check whether it has any descriptors in it or not at runtime?

@achow101
Copy link
Member Author

Do we even need to store a flag for a blank wallet? Can't we just check whether it has any descriptors in it or not at runtime?

No, that's how we determine whether the wallet was just created. Without the blank flag, we don't have a way of distinguishing between "blank" and "newly created".

@furszy
Copy link
Member
furszy commented Nov 15, 2022

Do we even need to store a flag for a blank wallet? Can't we just check whether it has any descriptors in it or not at runtime?

No, that's how we determine whether the wallet was just created. Without the blank flag, we don't have a way of distinguishing between "blank" and "newly created".

Hmm, wouldn't be sufficient to differentiate blank from newly created wallets by providing a flag to the CreateWallet function based on the context?

Sounds pretty odd this blank flag storage requirement. We could just add a runtime parameter that says "if we are loading any wallet from disk, don't create any new seed nor new SPKMs, just load the file into a wallet". Then, only if the context is the createwallet RPC command (or the same flow in the GUI), set the flag to true and create the new seed and related descriptors.

@achow101
Copy link
Member Author

Hmm, wouldn't be sufficient to differentiate blank from newly created wallets by providing a flag to the CreateWallet function based on the context?

Going forward, probably. But we still need the flag for downgrade protection. Older software determines whether a wallet is new by observing that there's nothing in it. So if a blank wallet (without the flag) were loaded into the older software, it would think the wallet was just created and generate a new seed for it. Since the flag is one of the mandatory flags, older software that see that flag (or the version number that added support for the flag) will not load or modify the wallet. We unset the flag once the wallet contains things because it is no longer needed for downgrade protection. Once the wallet has keys or descriptors, older software will not automatically generate anything for that wallet.

The other reason it's implemented this way is because at the time it was introduced, we would create a wallet specified with -wallet if it did not exist. Since the same function is used for both loading and creation and there is no (easy) way to tell whether the wallet that was loaded was just created or already existed, we needed the flag in order to know not to do anything to the wallet.


Perhaps there needs to be some distinction between "this wallet needs to start out without any automatically generated things" and "this wallet must only have things the user adds explicitly". The original reason blank was added was to support born-encrypted wallets. It was a way to make sure that a newly created wallet would not have any initial keys so that the user (or the creation process itself) can encrypt the wallet and generate keys automatically after encryption. However some users probably want to have wallets where the only things in their wallets are things that are added explicitly, e.g. only imports, or only sethdseed results. As noted in #25634 (comment), blank wallets does not support that as after encrypting, a new seed or a new set of descriptors will be generated. I would argue that supporting that in blank wallets is not quite what blank wallet means and should be a separate feature.

Copy link
Contributor
@murchandamus murchandamus left a comment

Choose a reason for hiding this comment

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

ACK 23403d0

Comment on lines +115 to +123
wallet.importwallet(wallet_dump_path)
assert_equal(wallet.getwalletinfo()["blank"], False)
Copy link
Contributor

Choose a reason for hiding this comment

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

You are explicitly expecting this behavior, but I’m kinda surprised that when we import a wallet that was explicitly created “blank” after the import it is now no longer blank. As far as I can tell, no keys were created, unless the import automatically does that. I’m curious why this is the expected behavior (although since you seem to explicitly expect that behavior, I don’t think there is an issue here).

Copy link
Member Author
@achow101 achow101 Mar 17, 2023

Choose a reason for hiding this comment

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

We determine whether a wallet is new by checking whether it has any keys or scripts contained in it. If it is "new", then the wallet will be setup to have the automatically generated things. The blank flag is used only to indicate to that code that the wallet is intentionally blank and should not be setup as a new wallet. Once something has been added to the wallet, it's no longer blank and the setup code will no longer recognize it as being "new", so the flag should be removed. It's not intended as something that should live beyond that, it doesn't just mean that the wallet was created as blank, but rather that it is currently blank and that state is intentional.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, thanks for the explanation

Copy link
Contributor

Choose a reason for hiding this comment

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

I have a different perspective. The flag was provided during wallet creation and captures the intent of the user.

The blank flag is used only to indicate to that code that the wallet is intentionally blank and should not be setup as a new wallet.

I'd like to take this one step further and argue that "The blank flag is used only to indicate to that code that the wallet is intentionally blank and the user is responsible for managing the keys in this wallet manually." If user created wallet intentionally blank so the software doesn't touch the keys, does the intention go away after the keys are imported in the wallet? I don't think so.

Once something has been added to the wallet, it's no longer blank and the setup code will no longer recognize it as being "new", so the flag should be removed.

We shouldn't casually flip between just blank and intentionally blank. Yes, it's not longer blank, but it's still intentionally blank because this was and is the intent of the user. I think the word blank is just misleading here. We're better off replacing intentionally blank with manual.

@DrahtBot DrahtBot requested review from aureleoules and furszy March 17, 2023 15:33
@ishaanam
Copy link
Contributor

@achow101 could you please add release notes detailing how encrypting the wallet will now rotate the imported descriptors in a descriptor wallet? Other than that this looks good.

@achow101 achow101 force-pushed the desc-import-unset-blank branch from 23403d0 to abc328c Compare March 17, 2023 19:19
@achow101 achow101 force-pushed the desc-import-unset-blank branch from fdd7a21 to cdba23d Compare June 13, 2023 19:53
@achow101
Copy link
Member Author

The GUI would be simpler and clearer if it made blank and watch-only wallets separate choices instead of overlapping options.

I've done that in bitcoin-core/gui#739

So I'd be happier if the PR kept all the new test coverage and bugfixes but dropped the second commit "Set blank when disable private keys in createwallet" 37dd054

Dropped it.

@S3RK
Copy link
Contributor
S3RK commented Jun 14, 2023

reACK cdba23d

Appreciate the perseverance in addressing all the comments and arriving at consensus. Thank for working on this.

@DrahtBot DrahtBot requested review from pablomartin4btc and ryanofsky and removed request for pablomartin4btc June 14, 2023 07:33
@ryanofsky
Copy link
Contributor

Appreciate the perseverance in addressing all the comments and arriving at consensus. Thank for working on this.

Agreed, thanks @achow101. I do think the end result is better, but that was a very long process... and the PR description is now slightly out of date too 😕.

I'm also wondering if the earlier discussion about adding a "manual" flag (#25634 (comment)) is still relevant. Is the blank flag already acting like manual flag for descriptor wallets now, or are there other effects setting a manual flag would have for descriptor wallets? (I assume we don't care about adding a manual flag for legacy wallets.)

@DrahtBot DrahtBot requested review from pablomartin4btc and removed request for pablomartin4btc June 14, 2023 13:22
Copy link
Contributor
@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.

Code review ACK cdba23d. Only change since last review is dropping the commit which makes createwallet RPC set BLANK flag automatically when DISABLE_PRIVATE_KEYS flag is set

@DrahtBot DrahtBot requested review from pablomartin4btc and removed request for pablomartin4btc June 14, 2023 13:26
@ryanofsky
Copy link
Contributor
ryanofsky commented Jun 14, 2023

I edited the PR description to drop the second paragraph #25634 (comment):

Additionally it unifies the behavior of the RPC with the GUI in that setting disable_private_keys will also automatically set blank. However, for backwards compatibility, users can choose to override this in the RPC by doing blank=False.

@DrahtBot DrahtBot requested review from pablomartin4btc and removed request for pablomartin4btc June 14, 2023 13:28
@ryanofsky ryanofsky merged commit 6663c80 into bitcoin:master Jun 14, 2023
@ryanofsky
Copy link
Contributor

I went ahead and merged this despite latest version only having 2 acks, because previous versions had more acks, and the only significant change dropping a commit (37dd054 "Set blank when disable private keys in createwallet"). If anybody disagrees with dropping that, we can bring it back in another PR, but I thought it'd be good to merge the changes that seemed to have full agreement.

sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Jun 15, 2023
…llet flag should be un/set

cdba23d wallet: Document blank flag use in descriptor wallets (Ryan Ofsky)
4331020 wallet: Ensure that the blank wallet flag is unset after imports (Andrew Chow)
e9379f1 rpc, wallet: Include information about blank flag (Andrew Chow)

Pull request description:

  The `blank` wallet flag is used to indicate that the wallet intentionally does not have any keys, scripts, or descriptors, and it prevents the automatic generation of those things for such a wallet. Once the wallet contains any of those data, it is unnecessary, and possibly incorrect, to have `blank` set. This PR fixes a few places where this was not properly happening. It also adds a test for this unset behavior.

ACKs for top commit:
  S3RK:
    reACK cdba23d
  ryanofsky:
    Code review ACK cdba23d. Only change since last review is dropping the commit which makes createwallet RPC set BLANK flag automatically when DISABLE_PRIVATE_KEYS flag is set

Tree-SHA512: 85bc2a9754df0531575d5c8f4ad7e8f38dcd50083dc29b3283dacf56feae842e81f34654c5e1781f2dadb0560ff80e454bbc8ca3b2d1fab1b236499ae9abd7da
@S3RK
Copy link
Contributor
S3RK commented Jun 19, 2023

I'm also wondering if the earlier discussion about adding a "manual" flag (#25634 (comment)) is still relevant. Is the blank flag already acting like manual flag for descriptor wallets now, or are there other effects setting a manual flag would have for descriptor wallets? (I assume we don't care about adding a manual flag for legacy wallets.)

Unless I'm missing something, the blank flag is already acting like manual for descriptors.

  • It's not unset on imports
  • It preservers descriptors on encryption

Now when blank flag diverged in meaning for descriptors wallet vs legacy. Do we want to add a highlight to release notes? Or change some other documentation?

@ryanofsky
Copy link
Contributor
ryanofsky commented Jun 19, 2023

Now when blank flag diverged in meaning for descriptors wallet vs legacy. Do we want to add a highlight to release notes?

As far as I know, difference was introduced when descriptor wallets were introduced, so there would not be a need for release notes. But it would be good to make sure RPCs are properly documented, so if you encrypt a wallet it is clear in what cases new keys will be generated. Also if we have any documentation contrasting legacy wallets and descriptor wallets we could have it mention this difference. I don't think it would be good for documentation to make a lot of references to the BLANK flag specifically. Better to just be document when keys will and won't be generated, and only mention about flag if it actually helps clarify behavior.

Copy link
Contributor
@hernanmarino hernanmarino left a comment

Choose a reason for hiding this comment

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

post merge ACK . Also +1 to @ryanofsky latest comment.

Copy link
Member
@pablomartin4btc pablomartin4btc left a comment

Choose a reason for hiding this comment

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

post-merge re-ACK with dropping 3rd commit (which only had 2 ACKs and there was the debate on: setting BLANK flag on RPC automatically when DISABLE_PRIVATE_KEYS flag is set), going to review at the GUI's follow-up on this by @achow101 that would fix the inconsistency there.

luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Aug 16, 2023
This allows us to test that the blank flag is being set appropriately.

Github-Pull: bitcoin#25634
Rebased-From: e9379f1
luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Aug 16, 2023
@bitcoin bitcoin locked and limited conversation to collaborators Jun 22, 2024
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.

0