mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-04 13:55:23 -05:00
Make WitnessUnknown members private
Make sure that nothing else can change WitnessUnknown's data members by making them private. Also change the program to use a vector rather than C-style array.
This commit is contained in:
parent
238d29aff9
commit
8dd067088d
8 changed files with 32 additions and 42 deletions
|
@ -87,11 +87,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
|||
return true;
|
||||
}
|
||||
case TxoutType::WITNESS_UNKNOWN: {
|
||||
WitnessUnknown unk;
|
||||
unk.version = vSolutions[0][0];
|
||||
std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
|
||||
unk.length = vSolutions[1].size();
|
||||
addressRet = unk;
|
||||
addressRet = WitnessUnknown{vSolutions[0][0], vSolutions[1]};
|
||||
return true;
|
||||
}
|
||||
case TxoutType::MULTISIG:
|
||||
|
@ -138,7 +134,7 @@ public:
|
|||
|
||||
CScript operator()(const WitnessUnknown& id) const
|
||||
{
|
||||
return CScript() << CScript::EncodeOP_N(id.version) << std::vector<unsigned char>(id.program, id.program + id.length);
|
||||
return CScript() << CScript::EncodeOP_N(id.GetWitnessVersion()) << id.GetWitnessProgram();
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
|
|
@ -69,22 +69,26 @@ struct WitnessV1Taproot : public XOnlyPubKey
|
|||
//! CTxDestination subtype to encode any future Witness version
|
||||
struct WitnessUnknown
|
||||
{
|
||||
unsigned int version;
|
||||
unsigned int length;
|
||||
unsigned char program[40];
|
||||
private:
|
||||
unsigned int m_version;
|
||||
std::vector<unsigned char> m_program;
|
||||
|
||||
public:
|
||||
WitnessUnknown(unsigned int version, const std::vector<unsigned char>& program) : m_version(version), m_program(program) {}
|
||||
WitnessUnknown(int version, const std::vector<unsigned char>& program) : m_version(static_cast<unsigned int>(version)), m_program(program) {}
|
||||
|
||||
unsigned int GetWitnessVersion() const { return m_version; }
|
||||
const std::vector<unsigned char>& GetWitnessProgram() const LIFETIMEBOUND { return m_program; }
|
||||
|
||||
friend bool operator==(const WitnessUnknown& w1, const WitnessUnknown& w2) {
|
||||
if (w1.version != w2.version) return false;
|
||||
if (w1.length != w2.length) return false;
|
||||
return std::equal(w1.program, w1.program + w1.length, w2.program);
|
||||
if (w1.GetWitnessVersion() != w2.GetWitnessVersion()) return false;
|
||||
return w1.GetWitnessProgram() == w2.GetWitnessProgram();
|
||||
}
|
||||
|
||||
friend bool operator<(const WitnessUnknown& w1, const WitnessUnknown& w2) {
|
||||
if (w1.version < w2.version) return true;
|
||||
if (w1.version > w2.version) return false;
|
||||
if (w1.length < w2.length) return true;
|
||||
if (w1.length > w2.length) return false;
|
||||
return std::lexicographical_compare(w1.program, w1.program + w1.length, w2.program, w2.program + w2.length);
|
||||
if (w1.GetWitnessVersion() < w2.GetWitnessVersion()) return true;
|
||||
if (w1.GetWitnessVersion() > w2.GetWitnessVersion()) return false;
|
||||
return w1.GetWitnessProgram() < w2.GetWitnessProgram();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -66,12 +66,13 @@ public:
|
|||
|
||||
std::string operator()(const WitnessUnknown& id) const
|
||||
{
|
||||
if (id.version < 1 || id.version > 16 || id.length < 2 || id.length > 40) {
|
||||
const std::vector<unsigned char>& program = id.GetWitnessProgram();
|
||||
if (id.GetWitnessVersion() < 1 || id.GetWitnessVersion() > 16 || program.size() < 2 || program.size() > 40) {
|
||||
return {};
|
||||
}
|
||||
std::vector<unsigned char> data = {(unsigned char)id.version};
|
||||
data.reserve(1 + (id.length * 8 + 4) / 5);
|
||||
ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.program, id.program + id.length);
|
||||
std::vector<unsigned char> data = {(unsigned char)id.GetWitnessVersion()};
|
||||
data.reserve(1 + (program.size() * 8 + 4) / 5);
|
||||
ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, program.begin(), program.end());
|
||||
return bech32::Encode(bech32::Encoding::BECH32M, m_params.Bech32HRP(), data);
|
||||
}
|
||||
|
||||
|
@ -188,11 +189,7 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par
|
|||
return CNoDestination();
|
||||
}
|
||||
|
||||
WitnessUnknown unk;
|
||||
unk.version = version;
|
||||
std::copy(data.begin(), data.end(), unk.program);
|
||||
unk.length = data.size();
|
||||
return unk;
|
||||
return WitnessUnknown{version, data};
|
||||
} else {
|
||||
error_str = strprintf("Invalid padding in Bech32 data section");
|
||||
return CNoDestination();
|
||||
|
|
|
@ -303,8 +303,8 @@ public:
|
|||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.pushKV("iswitness", true);
|
||||
obj.pushKV("witness_version", (int)id.version);
|
||||
obj.pushKV("witness_program", HexStr({id.program, id.length}));
|
||||
obj.pushKV("witness_version", id.GetWitnessVersion());
|
||||
obj.pushKV("witness_program", HexStr(id.GetWitnessProgram()));
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -188,15 +188,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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ MessageVerificationResult MessageVerify(
|
|||
return MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED;
|
||||
}
|
||||
|
||||
if (!(CTxDestination(PKHash(pubkey)) == destination)) {
|
||||
if (!(PKHash(pubkey) == *std::get_if<PKHash>(&destination))) {
|
||||
return MessageVerificationResult::ERR_NOT_SIGNED;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue