-
Notifications
You must be signed in to change notification settings - Fork 35.6k
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: Use CTxDestination in CRecipient instead of just scriptPubKey #28246
Merged
Merged
Changes from 1 commit
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
8dd0670
Make WitnessUnknown members private
achow101 1a98a51
Allow CNoDestination to represent a raw script
achow101 07d3bdf
Add PubKeyDestination for P2PK scripts
achow101 ad0c469
wallet: Use CTxDestination in CRecipient rather than scriptPubKey
achow101 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,19 @@ class CNoDestination { | |
friend bool operator<(const CNoDestination& a, const CNoDestination& b) { return a.GetScript() < b.GetScript(); } | ||
}; | ||
|
||
struct PubKeyDestination { | ||
private: | ||
CPubKey m_pubkey; | ||
|
||
public: | ||
PubKeyDestination(const CPubKey& pubkey) : m_pubkey(pubkey) {} | ||
achow101 marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it is fine to let this be implicit. There should be no risk. |
||
|
||
const CPubKey& GetPubKey() const LIFETIMEBOUND { return m_pubkey; } | ||
|
||
friend bool operator==(const PubKeyDestination& a, const PubKeyDestination& b) { return a.GetPubKey() == b.GetPubKey(); } | ||
friend bool operator<(const PubKeyDestination& a, const PubKeyDestination& b) { return a.GetPubKey() < b.GetPubKey(); } | ||
}; | ||
|
||
struct PKHash : public BaseHash<uint160> | ||
{ | ||
PKHash() : BaseHash() {} | ||
|
@@ -103,6 +116,7 @@ struct WitnessUnknown | |
/** | ||
* A txout script categorized into standard templates. | ||
* * CNoDestination: Optionally a script, no corresponding address. | ||
* * PubKeyDestination: TxoutType::PUBKEY (P2PK), no corresponding address | ||
* * PKHash: TxoutType::PUBKEYHASH destination (P2PKH address) | ||
* * ScriptHash: TxoutType::SCRIPTHASH destination (P2SH address) | ||
* * WitnessV0ScriptHash: TxoutType::WITNESS_V0_SCRIPTHASH destination (P2WSH address) | ||
|
@@ -111,9 +125,9 @@ struct WitnessUnknown | |
* * WitnessUnknown: TxoutType::WITNESS_UNKNOWN destination (P2W??? address) | ||
* A CTxDestination is the internal data type encoded in a bitcoin address | ||
*/ | ||
using CTxDestination = std::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown>; | ||
using CTxDestination = std::variant<CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown>; | ||
|
||
/** Check whether a CTxDestination is a CNoDestination. */ | ||
/** Check whether a CTxDestination corresponds to one with an address. */ | ||
achow101 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
bool IsValidDestination(const CTxDestination& dest); | ||
|
||
/** | ||
|
@@ -123,8 +137,8 @@ bool IsValidDestination(const CTxDestination& dest); | |
* is assigned to addressRet. | ||
* For all other scripts. addressRet is assigned as a CNoDestination containing the scriptPubKey. | ||
achow101 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* | ||
* Returns true for standard destinations - P2PK, P2PKH, P2SH, P2WPKH, P2WSH, and P2TR scripts. | ||
* Returns false for non-standard destinations - P2PK with invalid pubkeys, P2W???, bare multisig, null data, and nonstandard scripts. | ||
* Returns true for standard destinations with addresses - P2PKH, P2SH, P2WPKH, P2WSH, P2TR and P2W??? scripts. | ||
* Returns false for non-standard destinations and those without addresses - P2PK, bare multisig, null data, and nonstandard scripts. | ||
*/ | ||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This change looks incorrect. The PUBKEY code path now always returns "false". Is this intentional?
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.
Yes. See the first comment in this PR:
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.
But why is P2PK treated differently now?
Previously when the function returned "false", it meant the result is CNoDestination, but now that's ambiguous and could also be PubKeyDestination, and thus requires further checks.
This kind of makes the return value not very useful, IMHO.
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.
Hmm, looks like OutputTypeFromDestination needs to be updated to support PubKeyDestination?
I'm hitting an issue in my PR, with some wallet tests that use addresses from mined blocks (GetScriptForRawPubKey(coinbaseKey.GetPubKey())), and OutputTypeFromDestination is returning nullopt now.
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.
As noted in the change to the documentation for this function,
ExtractDestination
only returns true for things that have addresses. P2PK does not have an address. This is useful in other parts of the codebase and in future work such as silent payments. If you want to check if it is aCNoDestination
, then you can do that directly. However, it should generally be okay to not need to check for that. For the most part, checking forCNoDestination
is not all that useful and there's probably a better way to achieve what you want to do.No, it does not.
OutputType
is also a synonym for address type in the context of giving an address to the user. P2PK does not have an address type and users cannot get an address for them. If you are using things that relied on the incorrect behavior of getting aPKHash
for a P2PK script, then I suggest that you don't do that. P2PK is notPKHash
and you shouldn't expect it to be giving you those scripts.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.
Hmm, I don't think I understand why it's considered to have no address ...
In the wallet test, I'm using GetScriptForRawPubKey(coinbaseKey.GetPubKey()) to mine a block (via the MineBlock function), and then create a wallet with that coinbase key and issue transactions with coins returned from AvailableCoins.
With the new code path, it seems the script coming from AvailableCoins gets classified as PubKeyDestination, which fails to get an OutputTypeFromDestination, however before this change, this code worked and generated successful transactions.
Is there another way to mine blocks and get non-P2PK script from the coinbase key?
For context, the code that used to work but is now failing is in the function CreateDeniabilizationTransaction, in spend.cpp in my PR (https://github.com/bitcoin/bitcoin/pull/27792/files#)
And further down in the same function (with the workaround I just added to pass CI):
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.
They literally do not have addresses. There is no address type which maps to a P2PK script. That this and other software sometimes display an address for P2PK scripts is simply wrong. They are displaying P2PK addresses. If you send to those addresses, a P2PK script is not created.
AvailableCoins
does not operate on destinations, it operates on scripts. This is way more precise since there are more standard script types than there are standard addresses (e.g. P2PK, bare multisig). If you have modified it to operate on destinations, don't do that.Please take this discussion to your PR as it would be more helpful to see what you've done rather than to continue discussing code proposed in another PR in this thread. Just leave a review comment on the relevant line in your PR and mention me.
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.
Thanks! It's clear I didn't have a good understanding of the relationship between scripts and addresses. I'll move the discussion to my PR.