Check redeemScript size does not exceed 520 byte limit
redeemScripts >520bytes can't be spent due to the MAX_SCRIPT_ELEMENT_SIZE limit; previously the addmultisigaddress and createmultisig RPC calls would let you violate that limit unknowingly. Also made the wallet code itself check the redeemScript prior to adding it to the wallet, which in the (rare) instance that a user has added an invalid oversized redeemScript to their wallet causes an error on startup. The affected key isn't added to the wallet; other keys are unaffected.
This commit is contained in:
parent
4d79098ad5
commit
787ee0c913
@ -33,6 +33,9 @@ bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
|
|||||||
|
|
||||||
bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
|
bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
|
||||||
{
|
{
|
||||||
|
if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
|
||||||
|
return error("CBasicKeyStore::AddCScript() : redeemScripts > %i bytes are invalid", MAX_SCRIPT_ELEMENT_SIZE);
|
||||||
|
|
||||||
LOCK(cs_KeyStore);
|
LOCK(cs_KeyStore);
|
||||||
mapScripts[redeemScript.GetID()] = redeemScript;
|
mapScripts[redeemScript.GetID()] = redeemScript;
|
||||||
return true;
|
return true;
|
||||||
|
@ -176,7 +176,7 @@ Value validateaddress(const Array& params, bool fHelp)
|
|||||||
//
|
//
|
||||||
// Used by addmultisigaddress / createmultisig:
|
// Used by addmultisigaddress / createmultisig:
|
||||||
//
|
//
|
||||||
CScript _createmultisig(const Array& params)
|
CScript _createmultisig_redeemScript(const Array& params)
|
||||||
{
|
{
|
||||||
int nRequired = params[0].get_int();
|
int nRequired = params[0].get_int();
|
||||||
const Array& keys = params[1].get_array();
|
const Array& keys = params[1].get_array();
|
||||||
@ -228,6 +228,11 @@ CScript _createmultisig(const Array& params)
|
|||||||
}
|
}
|
||||||
CScript result;
|
CScript result;
|
||||||
result.SetMultisig(nRequired, pubkeys);
|
result.SetMultisig(nRequired, pubkeys);
|
||||||
|
|
||||||
|
if (result.size() > MAX_SCRIPT_ELEMENT_SIZE)
|
||||||
|
throw runtime_error(
|
||||||
|
strprintf("redeemScript exceeds size limit: %d > %d", result.size(), MAX_SCRIPT_ELEMENT_SIZE));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,7 +268,7 @@ Value createmultisig(const Array& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Construct using pay-to-script-hash:
|
// Construct using pay-to-script-hash:
|
||||||
CScript inner = _createmultisig(params);
|
CScript inner = _createmultisig_redeemScript(params);
|
||||||
CScriptID innerID = inner.GetID();
|
CScriptID innerID = inner.GetID();
|
||||||
CBitcoinAddress address(innerID);
|
CBitcoinAddress address(innerID);
|
||||||
|
|
||||||
|
@ -871,7 +871,7 @@ Value sendmany(const Array& params, bool fHelp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Defined in rpcmisc.cpp
|
// Defined in rpcmisc.cpp
|
||||||
extern CScript _createmultisig(const Array& params);
|
extern CScript _createmultisig_redeemScript(const Array& params);
|
||||||
|
|
||||||
Value addmultisigaddress(const Array& params, bool fHelp)
|
Value addmultisigaddress(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
@ -908,7 +908,7 @@ Value addmultisigaddress(const Array& params, bool fHelp)
|
|||||||
strAccount = AccountFromValue(params[2]);
|
strAccount = AccountFromValue(params[2]);
|
||||||
|
|
||||||
// Construct using pay-to-script-hash:
|
// Construct using pay-to-script-hash:
|
||||||
CScript inner = _createmultisig(params);
|
CScript inner = _createmultisig_redeemScript(params);
|
||||||
CScriptID innerID = inner.GetID();
|
CScriptID innerID = inner.GetID();
|
||||||
pwalletMain->AddCScript(inner);
|
pwalletMain->AddCScript(inner);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user