Skip to content

Commit 10eb3a9

Browse files
committed
kernel: Split ParseSighashString
This split is done in preparation for the next commit where the dependency on UniValue in the kernel library is removed.
1 parent 4a1aae6 commit 10eb3a9

File tree

6 files changed

+47
-22
lines changed

6 files changed

+47
-22
lines changed

doc/release-notes-28113.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
RPC Wallet
2+
----------
3+
4+
- The `signrawtransactionwithkey`, `signrawtransactionwithwallet`,
5+
`walletprocesspsbt` and `descriptorprocesspsbt` calls now return more
6+
specific RPC_INVALID_PARAMETER instead of RPC_PARSE_ERROR if their
7+
sighashtype argument is malformed or not a string.

src/core_io.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_CORE_IO_H
77

88
#include <consensus/amount.h>
9+
#include <util/result.h>
910

1011
#include <string>
1112
#include <vector>
@@ -46,7 +47,7 @@ bool DecodeHexBlockHeader(CBlockHeader&, const std::string& hex_header);
4647
*/
4748
bool ParseHashStr(const std::string& strHex, uint256& result);
4849
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
49-
int ParseSighashString(const UniValue& sighash);
50+
[[nodiscard]] util::Result<int> SighashFromStr(const std::string& sighash);
5051

5152
// core_write.cpp
5253
UniValue ValueFromAmount(const CAmount amount);

src/core_read.cpp

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <serialize.h>
1212
#include <streams.h>
1313
#include <univalue.h>
14+
#include <util/result.h>
1415
#include <util/strencodings.h>
1516
#include <version.h>
1617

@@ -252,26 +253,21 @@ std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strN
252253
return ParseHex(strHex);
253254
}
254255

255-
int ParseSighashString(const UniValue& sighash)
256+
util::Result<int> SighashFromStr(const std::string& sighash)
256257
{
257-
int hash_type = SIGHASH_DEFAULT;
258-
if (!sighash.isNull()) {
259-
static std::map<std::string, int> map_sighash_values = {
260-
{std::string("DEFAULT"), int(SIGHASH_DEFAULT)},
261-
{std::string("ALL"), int(SIGHASH_ALL)},
262-
{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
263-
{std::string("NONE"), int(SIGHASH_NONE)},
264-
{std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
265-
{std::string("SINGLE"), int(SIGHASH_SINGLE)},
266-
{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
267-
};
268-
const std::string& strHashType = sighash.get_str();
269-
const auto& it = map_sighash_values.find(strHashType);
270-
if (it != map_sighash_values.end()) {
271-
hash_type = it->second;
272-
} else {
273-
throw std::runtime_error(strHashType + " is not a valid sighash parameter.");
274-
}
258+
static std::map<std::string, int> map_sighash_values = {
259+
{std::string("DEFAULT"), int(SIGHASH_DEFAULT)},
260+
{std::string("ALL"), int(SIGHASH_ALL)},
261+
{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
262+
{std::string("NONE"), int(SIGHASH_NONE)},
263+
{std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
264+
{std::string("SINGLE"), int(SIGHASH_SINGLE)},
265+
{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
266+
};
267+
const auto& it = map_sighash_values.find(sighash);
268+
if (it != map_sighash_values.end()) {
269+
return it->second;
270+
} else {
271+
return util::Error{Untranslated(sighash + " is not a valid sighash parameter.")};
275272
}
276-
return hash_type;
277273
}

src/rpc/util.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <clientversion.h>
6+
#include <core_io.h>
67
#include <common/args.h>
78
#include <consensus/amount.h>
9+
#include <script/interpreter.h>
810
#include <key_io.h>
911
#include <outputtype.h>
1012
#include <rpc/util.h>
1113
#include <script/descriptor.h>
1214
#include <script/signingprovider.h>
1315
#include <tinyformat.h>
1416
#include <util/check.h>
17+
#include <util/result.h>
1518
#include <util/strencodings.h>
1619
#include <util/string.h>
1720
#include <util/translation.h>
@@ -310,6 +313,21 @@ UniValue DescribeAddress(const CTxDestination& dest)
310313
return std::visit(DescribeAddressVisitor(), dest);
311314
}
312315

316+
int ParseSighashString(const UniValue& sighash)
317+
{
318+
if (sighash.isNull()) {
319+
return SIGHASH_DEFAULT;
320+
}
321+
if (!sighash.isStr()) {
322+
throw JSONRPCError(RPC_INVALID_PARAMETER, "sighash needs to be null or string");
323+
}
324+
const auto result{SighashFromStr(sighash.get_str())};
325+
if (!result) {
326+
throw JSONRPCError(RPC_INVALID_PARAMETER, util::ErrorString(result).original);
327+
}
328+
return result.value();
329+
}
330+
313331
unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target)
314332
{
315333
const int target{value.getInt<int>()};

src/rpc/util.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ CTxDestination AddAndGetMultisigDestination(const int required, const std::vecto
100100

101101
UniValue DescribeAddress(const CTxDestination& dest);
102102

103+
/** Parse a sighash string representation and raise an RPC error if it is invalid. */
104+
int ParseSighashString(const UniValue& sighash);
105+
103106
//! Parse a confirm target option and raise an RPC error if it is invalid.
104107
unsigned int ParseConfirmTarget(const UniValue& value, unsigned int max_target);
105108

src/test/fuzz/parse_univalue.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ FUZZ_TARGET_INIT(parse_univalue, initialize_parse_univalue)
7575
}
7676
try {
7777
(void)ParseSighashString(univalue);
78-
} catch (const std::runtime_error&) {
78+
} catch (const UniValue&) {
7979
}
8080
try {
8181
(void)AmountFromValue(univalue);

0 commit comments

Comments
 (0)