mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-05 14:06:27 -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;
|
return true;
|
||||||
}
|
}
|
||||||
case TxoutType::WITNESS_UNKNOWN: {
|
case TxoutType::WITNESS_UNKNOWN: {
|
||||||
WitnessUnknown unk;
|
addressRet = WitnessUnknown{vSolutions[0][0], vSolutions[1]};
|
||||||
unk.version = vSolutions[0][0];
|
|
||||||
std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
|
|
||||||
unk.length = vSolutions[1].size();
|
|
||||||
addressRet = unk;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case TxoutType::MULTISIG:
|
case TxoutType::MULTISIG:
|
||||||
|
@ -138,7 +134,7 @@ public:
|
||||||
|
|
||||||
CScript operator()(const WitnessUnknown& id) const
|
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
|
} // namespace
|
||||||
|
|
|
@ -69,22 +69,26 @@ struct WitnessV1Taproot : public XOnlyPubKey
|
||||||
//! CTxDestination subtype to encode any future Witness version
|
//! CTxDestination subtype to encode any future Witness version
|
||||||
struct WitnessUnknown
|
struct WitnessUnknown
|
||||||
{
|
{
|
||||||
unsigned int version;
|
private:
|
||||||
unsigned int length;
|
unsigned int m_version;
|
||||||
unsigned char program[40];
|
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) {
|
friend bool operator==(const WitnessUnknown& w1, const WitnessUnknown& w2) {
|
||||||
if (w1.version != w2.version) return false;
|
if (w1.GetWitnessVersion() != w2.GetWitnessVersion()) return false;
|
||||||
if (w1.length != w2.length) return false;
|
return w1.GetWitnessProgram() == w2.GetWitnessProgram();
|
||||||
return std::equal(w1.program, w1.program + w1.length, w2.program);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
friend bool operator<(const WitnessUnknown& w1, const WitnessUnknown& w2) {
|
friend bool operator<(const WitnessUnknown& w1, const WitnessUnknown& w2) {
|
||||||
if (w1.version < w2.version) return true;
|
if (w1.GetWitnessVersion() < w2.GetWitnessVersion()) return true;
|
||||||
if (w1.version > w2.version) return false;
|
if (w1.GetWitnessVersion() > w2.GetWitnessVersion()) return false;
|
||||||
if (w1.length < w2.length) return true;
|
return w1.GetWitnessProgram() < w2.GetWitnessProgram();
|
||||||
if (w1.length > w2.length) return false;
|
|
||||||
return std::lexicographical_compare(w1.program, w1.program + w1.length, w2.program, w2.program + w2.length);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -66,12 +66,13 @@ public:
|
||||||
|
|
||||||
std::string operator()(const WitnessUnknown& id) const
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
std::vector<unsigned char> data = {(unsigned char)id.version};
|
std::vector<unsigned char> data = {(unsigned char)id.GetWitnessVersion()};
|
||||||
data.reserve(1 + (id.length * 8 + 4) / 5);
|
data.reserve(1 + (program.size() * 8 + 4) / 5);
|
||||||
ConvertBits<8, 5, true>([&](unsigned char c) { data.push_back(c); }, id.program, id.program + id.length);
|
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);
|
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();
|
return CNoDestination();
|
||||||
}
|
}
|
||||||
|
|
||||||
WitnessUnknown unk;
|
return WitnessUnknown{version, data};
|
||||||
unk.version = version;
|
|
||||||
std::copy(data.begin(), data.end(), unk.program);
|
|
||||||
unk.length = data.size();
|
|
||||||
return unk;
|
|
||||||
} else {
|
} else {
|
||||||
error_str = strprintf("Invalid padding in Bech32 data section");
|
error_str = strprintf("Invalid padding in Bech32 data section");
|
||||||
return CNoDestination();
|
return CNoDestination();
|
||||||
|
|
|
@ -303,8 +303,8 @@ public:
|
||||||
{
|
{
|
||||||
UniValue obj(UniValue::VOBJ);
|
UniValue obj(UniValue::VOBJ);
|
||||||
obj.pushKV("iswitness", true);
|
obj.pushKV("iswitness", true);
|
||||||
obj.pushKV("witness_version", (int)id.version);
|
obj.pushKV("witness_version", id.GetWitnessVersion());
|
||||||
obj.pushKV("witness_program", HexStr({id.program, id.length}));
|
obj.pushKV("witness_program", HexStr(id.GetWitnessProgram()));
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -186,7 +186,7 @@ FUZZ_TARGET(key, .init = initialize_key)
|
||||||
const CTxDestination tx_destination = GetDestinationForKey(pubkey, output_type);
|
const CTxDestination tx_destination = GetDestinationForKey(pubkey, output_type);
|
||||||
assert(output_type == OutputType::LEGACY);
|
assert(output_type == OutputType::LEGACY);
|
||||||
assert(IsValidDestination(tx_destination));
|
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);
|
const CScript script_for_destination = GetScriptForDestination(tx_destination);
|
||||||
assert(script_for_destination.size() == 25);
|
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)}};
|
tx_destination = WitnessV1Taproot{XOnlyPubKey{ConsumeUInt256(fuzzed_data_provider)}};
|
||||||
},
|
},
|
||||||
[&] {
|
[&] {
|
||||||
WitnessUnknown witness_unknown{};
|
std::vector<unsigned char> program{ConsumeRandomLengthByteVector(fuzzed_data_provider, /*max_length=*/40)};
|
||||||
witness_unknown.version = fuzzed_data_provider.ConsumeIntegralInRange(2, 16);
|
if (program.size() < 2) {
|
||||||
std::vector<uint8_t> witness_unknown_program_1{fuzzed_data_provider.ConsumeBytes<uint8_t>(40)};
|
program = {0, 0};
|
||||||
if (witness_unknown_program_1.size() < 2) {
|
|
||||||
witness_unknown_program_1 = {0, 0};
|
|
||||||
}
|
}
|
||||||
witness_unknown.length = witness_unknown_program_1.size();
|
tx_destination = WitnessUnknown{fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(2, 16), program};
|
||||||
std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program);
|
|
||||||
tx_destination = witness_unknown;
|
|
||||||
})};
|
})};
|
||||||
Assert(call_size == std::variant_size_v<CTxDestination>);
|
Assert(call_size == std::variant_size_v<CTxDestination>);
|
||||||
return tx_destination;
|
return tx_destination;
|
||||||
|
|
|
@ -249,10 +249,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
|
||||||
s.clear();
|
s.clear();
|
||||||
s << OP_1 << ToByteVector(pubkey);
|
s << OP_1 << ToByteVector(pubkey);
|
||||||
BOOST_CHECK(ExtractDestination(s, address));
|
BOOST_CHECK(ExtractDestination(s, address));
|
||||||
WitnessUnknown unk;
|
WitnessUnknown unk{1, ToByteVector(pubkey)};
|
||||||
unk.length = 33;
|
|
||||||
unk.version = 1;
|
|
||||||
std::copy(pubkey.begin(), pubkey.end(), unk.program);
|
|
||||||
BOOST_CHECK(std::get<WitnessUnknown>(address) == unk);
|
BOOST_CHECK(std::get<WitnessUnknown>(address) == unk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ MessageVerificationResult MessageVerify(
|
||||||
return MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED;
|
return MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(CTxDestination(PKHash(pubkey)) == destination)) {
|
if (!(PKHash(pubkey) == *std::get_if<PKHash>(&destination))) {
|
||||||
return MessageVerificationResult::ERR_NOT_SIGNED;
|
return MessageVerificationResult::ERR_NOT_SIGNED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue