mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
partial bitcoin#17938: Disallow automatic conversion between disparate hash types
includes: - 0a5ea32ce605984094c5552877cb99bc81654f2c - 3fcc46812334074d2c77a6233e8a961cd0785872 - 2c54217f913967703b404747133be67cf2f4feac - 966a22d859db37b1775e2180e5be032fc4fdf483 - 4d7369125a82214ea42b808a32b71b315a5c3c72
This commit is contained in:
parent
8d5ae627b8
commit
00802bb21d
@ -1416,7 +1416,7 @@ template <typename ProTx>
|
|||||||
static bool CheckHashSig(const ProTx& proTx, const PKHash& pkhash, CValidationState& state)
|
static bool CheckHashSig(const ProTx& proTx, const PKHash& pkhash, CValidationState& state)
|
||||||
{
|
{
|
||||||
std::string strError;
|
std::string strError;
|
||||||
if (!CHashSigner::VerifyHash(::SerializeHash(proTx), CKeyID(pkhash), proTx.vchSig, strError)) {
|
if (!CHashSigner::VerifyHash(::SerializeHash(proTx), ToKeyID(pkhash), proTx.vchSig, strError)) {
|
||||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-protx-sig");
|
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-protx-sig");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1426,7 +1426,7 @@ template <typename ProTx>
|
|||||||
static bool CheckStringSig(const ProTx& proTx, const PKHash& pkhash, CValidationState& state)
|
static bool CheckStringSig(const ProTx& proTx, const PKHash& pkhash, CValidationState& state)
|
||||||
{
|
{
|
||||||
std::string strError;
|
std::string strError;
|
||||||
if (!CMessageSigner::VerifyMessage(CKeyID(pkhash), proTx.vchSig, proTx.MakeSignString(), strError)) {
|
if (!CMessageSigner::VerifyMessage(ToKeyID(pkhash), proTx.vchSig, proTx.MakeSignString(), strError)) {
|
||||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-protx-sig");
|
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-protx-sig");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -512,7 +512,7 @@ void CoinControlDialog::updateLabels(CCoinControl& m_coin_control, WalletModel *
|
|||||||
{
|
{
|
||||||
CPubKey pubkey;
|
CPubKey pubkey;
|
||||||
PKHash *pkhash = std::get_if<PKHash>(&address);
|
PKHash *pkhash = std::get_if<PKHash>(&address);
|
||||||
if (pkhash && model->wallet().getPubKey(out.txout.scriptPubKey, CKeyID(*pkhash), pubkey))
|
if (pkhash && model->wallet().getPubKey(out.txout.scriptPubKey, ToKeyID(*pkhash), pubkey))
|
||||||
{
|
{
|
||||||
nBytesInputs += (pubkey.IsCompressed() ? 148 : 180);
|
nBytesInputs += (pubkey.IsCompressed() ? 148 : 180);
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,7 @@ static CKeyID ParsePubKeyIDFromAddress(const std::string& strAddress, const std:
|
|||||||
if (!pkhash) {
|
if (!pkhash) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be a valid P2PKH address, not %s", paramName, strAddress));
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be a valid P2PKH address, not %s", paramName, strAddress));
|
||||||
}
|
}
|
||||||
return CKeyID(*pkhash);
|
return ToKeyID(*pkhash);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CBLSPublicKey ParseBLSPubKey(const std::string& hexKey, const std::string& paramName, bool specific_legacy_bls_scheme = false)
|
static CBLSPublicKey ParseBLSPubKey(const std::string& hexKey, const std::string& paramName, bool specific_legacy_bls_scheme = false)
|
||||||
@ -773,7 +773,7 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CKey key;
|
CKey key;
|
||||||
if (!spk_man->GetKey(CKeyID(*pkhash), key)) {
|
if (!spk_man->GetKey(ToKeyID(*pkhash), key)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("collateral key not in wallet: %s", EncodeDestination(txDest)));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("collateral key not in wallet: %s", EncodeDestination(txDest)));
|
||||||
}
|
}
|
||||||
SignSpecialTxPayloadByString(tx, ptx, key);
|
SignSpecialTxPayloadByString(tx, ptx, key);
|
||||||
@ -1235,7 +1235,7 @@ static bool CheckWalletOwnsScript(CWallet* pwallet, const CScript& script) {
|
|||||||
|
|
||||||
CTxDestination dest;
|
CTxDestination dest;
|
||||||
if (ExtractDestination(script, dest)) {
|
if (ExtractDestination(script, dest)) {
|
||||||
if ((std::get_if<PKHash>(&dest) && spk_man->HaveKey(CKeyID(*std::get_if<PKHash>(&dest)))) || (std::get_if<ScriptHash>(&dest) && spk_man->HaveCScript(ScriptHash(*std::get_if<ScriptHash>(&dest))))) {
|
if ((std::get_if<PKHash>(&dest) && spk_man->HaveKey(ToKeyID(*std::get_if<PKHash>(&dest)))) || (std::get_if<ScriptHash>(&dest) && spk_man->HaveCScript(CScriptID{ScriptHash(*std::get_if<ScriptHash>(&dest))}))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@ CPubKey AddrToPubKey(const FillableSigningProvider& keystore, const std::string&
|
|||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("%s does not refer to a key", addr_in));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("%s does not refer to a key", addr_in));
|
||||||
}
|
}
|
||||||
CPubKey vchPubKey;
|
CPubKey vchPubKey;
|
||||||
if (!keystore.GetPubKey(CKeyID(*pkhash), vchPubKey)) {
|
if (!keystore.GetPubKey(ToKeyID(*pkhash), vchPubKey)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("no full public key for address %s", addr_in));
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("no full public key for address %s", addr_in));
|
||||||
}
|
}
|
||||||
if (!vchPubKey.IsFullyValid()) {
|
if (!vchPubKey.IsFullyValid()) {
|
||||||
|
@ -123,7 +123,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
|
|||||||
}
|
}
|
||||||
case TxoutType::SCRIPTHASH:
|
case TxoutType::SCRIPTHASH:
|
||||||
h160 = uint160(vSolutions[0]);
|
h160 = uint160(vSolutions[0]);
|
||||||
if (GetCScript(provider, sigdata, h160, scriptRet)) {
|
if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
|
||||||
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
|
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,19 @@ typedef std::vector<unsigned char> valtype;
|
|||||||
bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
|
bool fAcceptDatacarrier = DEFAULT_ACCEPT_DATACARRIER;
|
||||||
unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
|
unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
|
||||||
|
|
||||||
CScriptID::CScriptID(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
|
CScriptID::CScriptID(const CScript& in) : BaseHash(Hash160(in.begin(), in.end())) {}
|
||||||
|
CScriptID::CScriptID(const ScriptHash& in) : BaseHash(static_cast<uint160>(in)) {}
|
||||||
|
|
||||||
ScriptHash::ScriptHash(const CScript& in) : uint160(Hash160(in.begin(), in.end())) {}
|
ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in.begin(), in.end())) {}
|
||||||
|
ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast<uint160>(in)) {}
|
||||||
|
|
||||||
PKHash::PKHash(const CPubKey& pubkey) : uint160(pubkey.GetID()) {}
|
PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
|
||||||
|
PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
|
||||||
|
|
||||||
|
CKeyID ToKeyID(const PKHash& key_hash)
|
||||||
|
{
|
||||||
|
return CKeyID{static_cast<uint160>(key_hash)};
|
||||||
|
}
|
||||||
|
|
||||||
const char* GetTxnOutputType(TxoutType t)
|
const char* GetTxnOutputType(TxoutType t)
|
||||||
{
|
{
|
||||||
|
@ -15,14 +15,77 @@ static const bool DEFAULT_ACCEPT_DATACARRIER = true;
|
|||||||
|
|
||||||
class CKeyID;
|
class CKeyID;
|
||||||
class CScript;
|
class CScript;
|
||||||
|
struct ScriptHash;
|
||||||
|
|
||||||
|
template<typename HashType>
|
||||||
|
class BaseHash
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
HashType m_hash;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BaseHash() : m_hash() {}
|
||||||
|
BaseHash(const HashType& in) : m_hash(in) {}
|
||||||
|
|
||||||
|
unsigned char* begin()
|
||||||
|
{
|
||||||
|
return m_hash.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char* begin() const
|
||||||
|
{
|
||||||
|
return m_hash.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* end()
|
||||||
|
{
|
||||||
|
return m_hash.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char* end() const
|
||||||
|
{
|
||||||
|
return m_hash.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator std::vector<unsigned char>() const
|
||||||
|
{
|
||||||
|
return std::vector<unsigned char>{m_hash.begin(), m_hash.end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToString() const
|
||||||
|
{
|
||||||
|
return m_hash.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const BaseHash<HashType>& other) const noexcept
|
||||||
|
{
|
||||||
|
return m_hash == other.m_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const BaseHash<HashType>& other) const noexcept
|
||||||
|
{
|
||||||
|
return !(m_hash == other.m_hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const BaseHash<HashType>& other) const noexcept
|
||||||
|
{
|
||||||
|
return m_hash < other.m_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const
|
||||||
|
{
|
||||||
|
return m_hash.size();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
|
/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
|
||||||
class CScriptID : public uint160
|
class CScriptID : public BaseHash<uint160>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CScriptID() : uint160() {}
|
CScriptID() : BaseHash() {}
|
||||||
explicit CScriptID(const CScript& in);
|
explicit CScriptID(const CScript& in);
|
||||||
CScriptID(const uint160& in) : uint160(in) {}
|
explicit CScriptID(const uint160& in) : BaseHash(in) {}
|
||||||
|
explicit CScriptID(const ScriptHash& in);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,20 +130,21 @@ public:
|
|||||||
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
|
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PKHash : public uint160
|
struct PKHash : public BaseHash<uint160>
|
||||||
{
|
{
|
||||||
PKHash() : uint160() {}
|
PKHash() : BaseHash() {}
|
||||||
explicit PKHash(const uint160& hash) : uint160(hash) {}
|
explicit PKHash(const uint160& hash) : BaseHash(hash) {}
|
||||||
explicit PKHash(const CPubKey& pubkey);
|
explicit PKHash(const CPubKey& pubkey);
|
||||||
using uint160::uint160;
|
explicit PKHash(const CKeyID& pubkey_id);
|
||||||
};
|
};
|
||||||
|
CKeyID ToKeyID(const PKHash& key_hash);
|
||||||
|
|
||||||
struct ScriptHash : public uint160
|
struct ScriptHash : public BaseHash<uint160>
|
||||||
{
|
{
|
||||||
ScriptHash() : uint160() {}
|
ScriptHash() : BaseHash() {}
|
||||||
explicit ScriptHash(const uint160& hash) : uint160(hash) {}
|
explicit ScriptHash(const uint160& hash) : BaseHash(hash) {}
|
||||||
explicit ScriptHash(const CScript& script);
|
explicit ScriptHash(const CScript& script);
|
||||||
using uint160::uint160;
|
explicit ScriptHash(const CScriptID& script);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -286,7 +286,7 @@ bool CSporkManager::SetSporkAddress(const std::string& strAddress)
|
|||||||
LogPrintf("CSporkManager::SetSporkAddress -- Failed to parse spork address\n");
|
LogPrintf("CSporkManager::SetSporkAddress -- Failed to parse spork address\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
setSporkPubKeyIDs.insert(CKeyID(*pkhash));
|
setSporkPubKeyIDs.insert(ToKeyID(*pkhash));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ UniValue importprivkey(const JSONRPCRequest& request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Use timestamp of 1 to scan the whole chain
|
// Use timestamp of 1 to scan the whole chain
|
||||||
if (!pwallet->ImportPrivKeys({{CKeyID(vchAddress), key}}, 1)) {
|
if (!pwallet->ImportPrivKeys({{ToKeyID(vchAddress), key}}, 1)) {
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -829,7 +829,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request)
|
|||||||
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
|
||||||
}
|
}
|
||||||
CKey vchSecret;
|
CKey vchSecret;
|
||||||
if (!spk_man.GetKey(CKeyID(*pkhash), vchSecret)) {
|
if (!spk_man.GetKey(ToKeyID(*pkhash), vchSecret)) {
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
|
||||||
}
|
}
|
||||||
return EncodeSecret(vchSecret);
|
return EncodeSecret(vchSecret);
|
||||||
|
@ -3564,7 +3564,7 @@ public:
|
|||||||
UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
|
UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
|
||||||
|
|
||||||
UniValue operator()(const PKHash& pkhash) const {
|
UniValue operator()(const PKHash& pkhash) const {
|
||||||
CKeyID keyID(pkhash);
|
CKeyID keyID{ToKeyID(pkhash)};
|
||||||
UniValue obj(UniValue::VOBJ);
|
UniValue obj(UniValue::VOBJ);
|
||||||
CPubKey vchPubKey;
|
CPubKey vchPubKey;
|
||||||
if (provider && provider->GetPubKey(keyID, vchPubKey)) {
|
if (provider && provider->GetPubKey(keyID, vchPubKey)) {
|
||||||
@ -3727,7 +3727,7 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
|
|||||||
CHDChain hdChainCurrent;
|
CHDChain hdChainCurrent;
|
||||||
LegacyScriptPubKeyMan* legacy_spk_man = pwallet->GetLegacyScriptPubKeyMan();
|
LegacyScriptPubKeyMan* legacy_spk_man = pwallet->GetLegacyScriptPubKeyMan();
|
||||||
if (legacy_spk_man != nullptr) {
|
if (legacy_spk_man != nullptr) {
|
||||||
if (pkhash && legacy_spk_man->HaveHDKey(CKeyID(*pkhash), hdChainCurrent)) {
|
if (pkhash && legacy_spk_man->HaveHDKey(ToKeyID(*pkhash), hdChainCurrent)) {
|
||||||
ret.pushKV("hdchainid", hdChainCurrent.GetID().GetHex());
|
ret.pushKV("hdchainid", hdChainCurrent.GetID().GetHex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ bool LegacyScriptPubKeyMan::SignTransaction(CMutableTransaction& tx, const std::
|
|||||||
|
|
||||||
SigningResult LegacyScriptPubKeyMan::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const
|
SigningResult LegacyScriptPubKeyMan::SignMessage(const std::string& message, const PKHash& pkhash, std::string& str_sig) const
|
||||||
{
|
{
|
||||||
CKeyID key_id(pkhash);
|
CKeyID key_id(ToKeyID(pkhash));
|
||||||
CKey key;
|
CKey key;
|
||||||
if (!GetKey(key_id, key)) {
|
if (!GetKey(key_id, key)) {
|
||||||
return SigningResult::PRIVATE_KEY_NOT_AVAILABLE;
|
return SigningResult::PRIVATE_KEY_NOT_AVAILABLE;
|
||||||
@ -744,8 +744,8 @@ const CKeyMetadata* LegacyScriptPubKeyMan::GetMetadata(const CTxDestination& des
|
|||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
|
|
||||||
const PKHash *pkhash = std::get_if<PKHash>(&dest);
|
const PKHash *pkhash = std::get_if<PKHash>(&dest);
|
||||||
if (pkhash != nullptr && !pkhash->IsNull()) {
|
if (pkhash != nullptr && !ToKeyID(*pkhash).IsNull()) {
|
||||||
auto it = mapKeyMetadata.find(CKeyID(*pkhash));
|
auto it = mapKeyMetadata.find(ToKeyID(*pkhash));
|
||||||
if (it != mapKeyMetadata.end()) {
|
if (it != mapKeyMetadata.end()) {
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user