mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-04 18:22:57 +02:00
Merge bitcoin/bitcoin#28246: wallet: Use CTxDestination in CRecipient instead of just scriptPubKey
ad0c469d98wallet: Use CTxDestination in CRecipient rather than scriptPubKey (Andrew Chow)07d3bdf4ebAdd PubKeyDestination for P2PK scripts (Andrew Chow)1a98a51c66Allow CNoDestination to represent a raw script (Andrew Chow)8dd067088dMake WitnessUnknown members private (Andrew Chow) Pull request description: For silent payments, we want to provide a `SilentPaymentsDestination` to be used as the recipient, which requires `CRecipient` to use something other than just the `scriptPubKey` as we cannot know the output script for a silent payment prior to transaction creation. `CTxDestination` seems like the obvious place to add a `SilentPaymentsDestination` as it is our internal representation of an address. In order to still allow paying to arbitrary scriptPubKeys (e.g. for data carrier outputs, or the user hand crafted a raw transaction that they have given to `fundrawtransaction`), `CNoDestination` is changed to contain raw scripts. Additionally, P2PK scripts are now interpreted as a new `PubKeyDestination` rather than `PKHash`. This results in some things that would have given an address for P2PK scripts to no longer do so. This is arguably more correct. `ExtractDestination`'s behavior is slightly changed for the above. It now returns `true` for those destinations that have addresses, so P2PK scripts now result in `false`. Even though it returns false for `CNoDestination`, the script will now be included in that `CNoDestination`. Builds on #28244 ACKs for top commit: josibake: ACKad0c469d98Tree-SHA512: ef3f8f3c7284779d9806c77c85b21caf910a79a1f7e7f1b51abcc0d7e074f14e00abf30f625a13075e41d94dad6202c10ddff462c0ee74c2ca4aab585b145a52
This commit is contained in:
@@ -186,7 +186,7 @@ FUZZ_TARGET(key, .init = initialize_key)
|
||||
const CTxDestination tx_destination = GetDestinationForKey(pubkey, output_type);
|
||||
assert(output_type == OutputType::LEGACY);
|
||||
assert(IsValidDestination(tx_destination));
|
||||
assert(CTxDestination{PKHash{pubkey}} == tx_destination);
|
||||
assert(PKHash{pubkey} == *std::get_if<PKHash>(&tx_destination));
|
||||
|
||||
const CScript script_for_destination = GetScriptForDestination(tx_destination);
|
||||
assert(script_for_destination.size() == 25);
|
||||
|
||||
@@ -149,13 +149,16 @@ FUZZ_TARGET(script, .init = initialize_script)
|
||||
const CTxDestination tx_destination_2{ConsumeTxDestination(fuzzed_data_provider)};
|
||||
const std::string encoded_dest{EncodeDestination(tx_destination_1)};
|
||||
const UniValue json_dest{DescribeAddress(tx_destination_1)};
|
||||
Assert(tx_destination_1 == DecodeDestination(encoded_dest));
|
||||
(void)GetKeyForDestination(/*store=*/{}, tx_destination_1);
|
||||
const CScript dest{GetScriptForDestination(tx_destination_1)};
|
||||
const bool valid{IsValidDestination(tx_destination_1)};
|
||||
Assert(dest.empty() != valid);
|
||||
|
||||
Assert(valid == IsValidDestinationString(encoded_dest));
|
||||
if (!std::get_if<PubKeyDestination>(&tx_destination_1)) {
|
||||
// Only try to round trip non-pubkey destinations since PubKeyDestination has no encoding
|
||||
Assert(dest.empty() != valid);
|
||||
Assert(tx_destination_1 == DecodeDestination(encoded_dest));
|
||||
Assert(valid == IsValidDestinationString(encoded_dest));
|
||||
}
|
||||
|
||||
(void)(tx_destination_1 < tx_destination_2);
|
||||
if (tx_destination_1 == tx_destination_2) {
|
||||
|
||||
@@ -172,6 +172,15 @@ CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) no
|
||||
[&] {
|
||||
tx_destination = CNoDestination{};
|
||||
},
|
||||
[&] {
|
||||
bool compressed = fuzzed_data_provider.ConsumeBool();
|
||||
CPubKey pk{ConstructPubKeyBytes(
|
||||
fuzzed_data_provider,
|
||||
ConsumeFixedLengthByteVector(fuzzed_data_provider, (compressed ? CPubKey::COMPRESSED_SIZE : CPubKey::SIZE)),
|
||||
compressed
|
||||
)};
|
||||
tx_destination = PubKeyDestination{pk};
|
||||
},
|
||||
[&] {
|
||||
tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)};
|
||||
},
|
||||
@@ -188,15 +197,11 @@ CTxDestination ConsumeTxDestination(FuzzedDataProvider& fuzzed_data_provider) no
|
||||
tx_destination = WitnessV1Taproot{XOnlyPubKey{ConsumeUInt256(fuzzed_data_provider)}};
|
||||
},
|
||||
[&] {
|
||||
WitnessUnknown witness_unknown{};
|
||||
witness_unknown.version = fuzzed_data_provider.ConsumeIntegralInRange(2, 16);
|
||||
std::vector<uint8_t> witness_unknown_program_1{fuzzed_data_provider.ConsumeBytes<uint8_t>(40)};
|
||||
if (witness_unknown_program_1.size() < 2) {
|
||||
witness_unknown_program_1 = {0, 0};
|
||||
std::vector<unsigned char> program{ConsumeRandomLengthByteVector(fuzzed_data_provider, /*max_length=*/40)};
|
||||
if (program.size() < 2) {
|
||||
program = {0, 0};
|
||||
}
|
||||
witness_unknown.length = witness_unknown_program_1.size();
|
||||
std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program);
|
||||
tx_destination = witness_unknown;
|
||||
tx_destination = WitnessUnknown{fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(2, 16), program};
|
||||
})};
|
||||
Assert(call_size == std::variant_size_v<CTxDestination>);
|
||||
return tx_destination;
|
||||
|
||||
@@ -203,8 +203,8 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
|
||||
// TxoutType::PUBKEY
|
||||
s.clear();
|
||||
s << ToByteVector(pubkey) << OP_CHECKSIG;
|
||||
BOOST_CHECK(ExtractDestination(s, address));
|
||||
BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));
|
||||
BOOST_CHECK(!ExtractDestination(s, address));
|
||||
BOOST_CHECK(std::get<PubKeyDestination>(address) == PubKeyDestination(pubkey));
|
||||
|
||||
// TxoutType::PUBKEYHASH
|
||||
s.clear();
|
||||
@@ -249,10 +249,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
|
||||
s.clear();
|
||||
s << OP_1 << ToByteVector(pubkey);
|
||||
BOOST_CHECK(ExtractDestination(s, address));
|
||||
WitnessUnknown unk;
|
||||
unk.length = 33;
|
||||
unk.version = 1;
|
||||
std::copy(pubkey.begin(), pubkey.end(), unk.program);
|
||||
WitnessUnknown unk{1, ToByteVector(pubkey)};
|
||||
BOOST_CHECK(std::get<WitnessUnknown>(address) == unk);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user