Consolidate redundant implementations of ParseHashStr
This change: * adds a length check to ParseHashStr, appropriate given its use to populate a 256-bit number from a hex str. * allows the caller to handle the failure, which allows for the more appropriate JSONRPCError on failure in prioritisetransaction rpc
This commit is contained in:
parent
990fc0de1a
commit
9c5af58d51
6 changed files with 87 additions and 22 deletions
|
@ -240,10 +240,10 @@ static void MutateTxAddInput(CMutableTransaction& tx, const std::string& strInpu
|
||||||
throw std::runtime_error("TX input missing separator");
|
throw std::runtime_error("TX input missing separator");
|
||||||
|
|
||||||
// extract and validate TXID
|
// extract and validate TXID
|
||||||
std::string strTxid = vStrInputParts[0];
|
uint256 txid;
|
||||||
if ((strTxid.size() != 64) || !IsHex(strTxid))
|
if (!ParseHashStr(vStrInputParts[0], txid)) {
|
||||||
throw std::runtime_error("invalid TX input txid");
|
throw std::runtime_error("invalid TX input txid");
|
||||||
uint256 txid(uint256S(strTxid));
|
}
|
||||||
|
|
||||||
static const unsigned int minTxOutSz = 9;
|
static const unsigned int minTxOutSz = 9;
|
||||||
static const unsigned int maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz);
|
static const unsigned int maxVout = MAX_BLOCK_WEIGHT / (WITNESS_SCALE_FACTOR * minTxOutSz);
|
||||||
|
@ -590,7 +590,10 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
|
||||||
if (!prevOut.checkObject(types))
|
if (!prevOut.checkObject(types))
|
||||||
throw std::runtime_error("prevtxs internal object typecheck fail");
|
throw std::runtime_error("prevtxs internal object typecheck fail");
|
||||||
|
|
||||||
uint256 txid = ParseHashStr(prevOut["txid"].get_str(), "txid");
|
uint256 txid;
|
||||||
|
if (!ParseHashStr(prevOut["txid"].get_str(), txid)) {
|
||||||
|
throw std::runtime_error("txid must be hexadecimal string (not '" + prevOut["txid"].get_str() + "')");
|
||||||
|
}
|
||||||
|
|
||||||
const int nOut = prevOut["vout"].get_int();
|
const int nOut = prevOut["vout"].get_int();
|
||||||
if (nOut < 0)
|
if (nOut < 0)
|
||||||
|
|
|
@ -25,7 +25,16 @@ std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDeco
|
||||||
bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true);
|
bool DecodeHexTx(CMutableTransaction& tx, const std::string& hex_tx, bool try_no_witness = false, bool try_witness = true);
|
||||||
bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
|
bool DecodeHexBlk(CBlock&, const std::string& strHexBlk);
|
||||||
bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
|
bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
|
||||||
uint256 ParseHashStr(const std::string&, const std::string& strName);
|
|
||||||
|
/**
|
||||||
|
* Parse a hex string into 256 bits
|
||||||
|
* @param[in] strHex a hex-formatted, 64-character string
|
||||||
|
* @param[out] result the result of the parasing
|
||||||
|
* @returns true if successful, false if not
|
||||||
|
*
|
||||||
|
* @see ParseHashV for an RPC-oriented version of this
|
||||||
|
*/
|
||||||
|
bool ParseHashStr(const std::string& strHex, uint256& result);
|
||||||
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
|
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
|
||||||
bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error);
|
bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx, std::string& error);
|
||||||
int ParseSighashString(const UniValue& sighash);
|
int ParseSighashString(const UniValue& sighash);
|
||||||
|
|
|
@ -193,14 +193,13 @@ bool DecodePSBT(PartiallySignedTransaction& psbt, const std::string& base64_tx,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 ParseHashStr(const std::string& strHex, const std::string& strName)
|
bool ParseHashStr(const std::string& strHex, uint256& result)
|
||||||
{
|
{
|
||||||
if (!IsHex(strHex)) // Note: IsHex("") is false
|
if ((strHex.size() != 64) || !IsHex(strHex))
|
||||||
throw std::runtime_error(strName + " must be hexadecimal string (not '" + strHex + "')");
|
return false;
|
||||||
|
|
||||||
uint256 result;
|
|
||||||
result.SetHex(strHex);
|
result.SetHex(strHex);
|
||||||
return result;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName)
|
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName)
|
||||||
|
|
|
@ -105,15 +105,6 @@ static std::string AvailableDataFormatsString()
|
||||||
return formats;
|
return formats;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseHashStr(const std::string& strReq, uint256& v)
|
|
||||||
{
|
|
||||||
if (!IsHex(strReq) || (strReq.size() != 64))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
v.SetHex(strReq);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CheckWarmup(HTTPRequest* req)
|
static bool CheckWarmup(HTTPRequest* req)
|
||||||
{
|
{
|
||||||
std::string statusmessage;
|
std::string statusmessage;
|
||||||
|
|
|
@ -114,7 +114,8 @@ BOOST_AUTO_TEST_CASE(blockfilters_json_test)
|
||||||
|
|
||||||
unsigned int pos = 0;
|
unsigned int pos = 0;
|
||||||
/*int block_height =*/ test[pos++].get_int();
|
/*int block_height =*/ test[pos++].get_int();
|
||||||
/*uint256 block_hash =*/ ParseHashStr(test[pos++].get_str(), "block_hash");
|
uint256 block_hash;
|
||||||
|
BOOST_CHECK(ParseHashStr(test[pos++].get_str(), block_hash));
|
||||||
|
|
||||||
CBlock block;
|
CBlock block;
|
||||||
BOOST_REQUIRE(DecodeHexBlk(block, test[pos++].get_str()));
|
BOOST_REQUIRE(DecodeHexBlk(block, test[pos++].get_str()));
|
||||||
|
@ -129,9 +130,11 @@ BOOST_AUTO_TEST_CASE(blockfilters_json_test)
|
||||||
tx_undo.vprevout.emplace_back(txout, 0, false);
|
tx_undo.vprevout.emplace_back(txout, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 prev_filter_header_basic = ParseHashStr(test[pos++].get_str(), "prev_filter_header_basic");
|
uint256 prev_filter_header_basic;
|
||||||
|
BOOST_CHECK(ParseHashStr(test[pos++].get_str(), prev_filter_header_basic));
|
||||||
std::vector<unsigned char> filter_basic = ParseHex(test[pos++].get_str());
|
std::vector<unsigned char> filter_basic = ParseHex(test[pos++].get_str());
|
||||||
uint256 filter_header_basic = ParseHashStr(test[pos++].get_str(), "filter_header_basic");
|
uint256 filter_header_basic;
|
||||||
|
BOOST_CHECK(ParseHashStr(test[pos++].get_str(), filter_header_basic));
|
||||||
|
|
||||||
BlockFilter computed_filter_basic(BlockFilterType::BASIC, block, block_undo);
|
BlockFilter computed_filter_basic(BlockFilterType::BASIC, block, block_undo);
|
||||||
BOOST_CHECK(computed_filter_basic.GetFilter().GetEncoded() == filter_basic);
|
BOOST_CHECK(computed_filter_basic.GetFilter().GetEncoded() == filter_basic);
|
||||||
|
|
|
@ -102,6 +102,30 @@
|
||||||
"error_txt": "error: Invalid TX locktime requested",
|
"error_txt": "error: Invalid TX locktime requested",
|
||||||
"description": "Tests the check for invalid locktime value"
|
"description": "Tests the check for invalid locktime value"
|
||||||
},
|
},
|
||||||
|
{ "exec": "./bitcoin-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=Z897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: invalid TX input txid",
|
||||||
|
"description": "Tests the check for an invalid txid invalid hex"
|
||||||
|
},
|
||||||
|
{ "exec": "./bitcoin-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=5897de6bd6:0"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: invalid TX input txid",
|
||||||
|
"description": "Tests the check for an invalid txid valid hex but too short"
|
||||||
|
},
|
||||||
|
{ "exec": "./bitcoin-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f12:0"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: invalid TX input txid",
|
||||||
|
"description": "Tests the check for an invalid txid valid hex but too long"
|
||||||
|
},
|
||||||
{ "exec": "./bitcoin-tx",
|
{ "exec": "./bitcoin-tx",
|
||||||
"args":
|
"args":
|
||||||
["-create",
|
["-create",
|
||||||
|
@ -280,6 +304,42 @@
|
||||||
"error_txt": "error: prevtxs internal object typecheck fail",
|
"error_txt": "error: prevtxs internal object typecheck fail",
|
||||||
"description": "Tests the check for invalid vout index in prevtxs for sign"
|
"description": "Tests the check for invalid vout index in prevtxs for sign"
|
||||||
},
|
},
|
||||||
|
{ "exec": "./bitcoin-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
|
||||||
|
"set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
|
||||||
|
"set=prevtxs:[{\"txid\":\"Zd49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59412\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]",
|
||||||
|
"sign=ALL",
|
||||||
|
"outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: txid must be hexadecimal string (not 'Zd49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59412')",
|
||||||
|
"description": "Tests the check for invalid txid due to invalid hex"
|
||||||
|
},
|
||||||
|
{ "exec": "./bitcoin-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
|
||||||
|
"set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
|
||||||
|
"set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc594\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]",
|
||||||
|
"sign=ALL",
|
||||||
|
"outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: txid must be hexadecimal string (not '4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc594')",
|
||||||
|
"description": "Tests the check for invalid txid valid hex, but too short"
|
||||||
|
},
|
||||||
|
{ "exec": "./bitcoin-tx",
|
||||||
|
"args":
|
||||||
|
["-create",
|
||||||
|
"in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
|
||||||
|
"set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
|
||||||
|
"set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc5948512\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]",
|
||||||
|
"sign=ALL",
|
||||||
|
"outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
|
||||||
|
"return_code": 1,
|
||||||
|
"error_txt": "error: txid must be hexadecimal string (not '4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc5948512')",
|
||||||
|
"description": "Tests the check for invalid txid valid hex, but too long"
|
||||||
|
},
|
||||||
{ "exec": "./bitcoin-tx",
|
{ "exec": "./bitcoin-tx",
|
||||||
"args":
|
"args":
|
||||||
["-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397", "nversion=1"],
|
["-create", "outpubkey=0:02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397", "nversion=1"],
|
||||||
|
|
Loading…
Reference in a new issue