aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Woosley <ben.woosley@gmail.com>2018-06-08 11:16:07 -0700
committerBen Woosley <ben.woosley@gmail.com>2018-08-07 12:47:39 -0400
commit5eb20f81d9568284dca735e4f770f41a48aa5660 (patch)
treeb0cddba3e535af76c852d57816d84f5335b15a6d
parent56f69360dc98bd68704f19646a84d045788d199e (diff)
downloadbitcoin-5eb20f81d9568284dca735e4f770f41a48aa5660.tar.xz
Consistently use ParseHashV to validate hash inputs in rpc
ParseHashV validates the length and encoding of the string and throws an informative RPC error on failure, which is as good or better than these alternative calls. Note I switched ParseHashV to check string length first, because IsHex tests that the length is even, and an error like: "must be of length 64 (not 63, for X)" is much more informative than "must be hexadecimal string (not X)"
-rw-r--r--src/rpc/blockchain.cpp25
-rw-r--r--src/rpc/mining.cpp4
-rw-r--r--src/rpc/rawtransaction.cpp6
-rw-r--r--src/rpc/server.cpp12
-rw-r--r--src/wallet/rpcdump.cpp3
-rw-r--r--src/wallet/rpcwallet.cpp20
-rwxr-xr-xtest/functional/mining_prioritisetransaction.py3
-rwxr-xr-xtest/functional/p2p_compactblocks.py2
-rwxr-xr-xtest/functional/p2p_sendheaders.py2
-rwxr-xr-xtest/functional/rpc_blockchain.py8
-rwxr-xr-xtest/functional/rpc_rawtransaction.py12
-rwxr-xr-xtest/functional/rpc_txoutproof.py8
-rwxr-xr-xtest/functional/wallet_basic.py8
-rwxr-xr-xtest/functional/wallet_listsinceblock.py4
14 files changed, 58 insertions, 59 deletions
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index f70d506e13..b809fd0f5d 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -252,7 +252,7 @@ static UniValue waitforblock(const JSONRPCRequest& request)
);
int timeout = 0;
- uint256 hash = uint256S(request.params[0].get_str());
+ uint256 hash(ParseHashV(request.params[0], "blockhash"));
if (!request.params[1].isNull())
timeout = request.params[1].get_int();
@@ -706,8 +706,7 @@ static UniValue getblockheader(const JSONRPCRequest& request)
LOCK(cs_main);
- std::string strHash = request.params[0].get_str();
- uint256 hash(uint256S(strHash));
+ uint256 hash(ParseHashV(request.params[0], "hash"));
bool fVerbose = true;
if (!request.params[1].isNull())
@@ -800,8 +799,7 @@ static UniValue getblock(const JSONRPCRequest& request)
LOCK(cs_main);
- std::string strHash = request.params[0].get_str();
- uint256 hash(uint256S(strHash));
+ uint256 hash(ParseHashV(request.params[0], "blockhash"));
int verbosity = 1;
if (!request.params[1].isNull()) {
@@ -1033,8 +1031,7 @@ UniValue gettxout(const JSONRPCRequest& request)
UniValue ret(UniValue::VOBJ);
- std::string strHash = request.params[0].get_str();
- uint256 hash(uint256S(strHash));
+ uint256 hash(ParseHashV(request.params[0], "txid"));
int n = request.params[1].get_int();
COutPoint out(hash, n);
bool fMempool = true;
@@ -1442,8 +1439,7 @@ static UniValue preciousblock(const JSONRPCRequest& request)
+ HelpExampleRpc("preciousblock", "\"blockhash\"")
);
- std::string strHash = request.params[0].get_str();
- uint256 hash(uint256S(strHash));
+ uint256 hash(ParseHashV(request.params[0], "blockhash"));
CBlockIndex* pblockindex;
{
@@ -1478,8 +1474,7 @@ static UniValue invalidateblock(const JSONRPCRequest& request)
+ HelpExampleRpc("invalidateblock", "\"blockhash\"")
);
- std::string strHash = request.params[0].get_str();
- uint256 hash(uint256S(strHash));
+ uint256 hash(ParseHashV(request.params[0], "blockhash"));
CValidationState state;
{
@@ -1518,8 +1513,7 @@ static UniValue reconsiderblock(const JSONRPCRequest& request)
+ HelpExampleRpc("reconsiderblock", "\"blockhash\"")
);
- std::string strHash = request.params[0].get_str();
- uint256 hash(uint256S(strHash));
+ uint256 hash(ParseHashV(request.params[0], "blockhash"));
{
LOCK(cs_main);
@@ -1572,7 +1566,7 @@ static UniValue getchaintxstats(const JSONRPCRequest& request)
LOCK(cs_main);
pindex = chainActive.Tip();
} else {
- uint256 hash = uint256S(request.params[1].get_str());
+ uint256 hash(ParseHashV(request.params[1], "blockhash"));
LOCK(cs_main);
pindex = LookupBlockIndex(hash);
if (!pindex) {
@@ -1711,8 +1705,7 @@ static UniValue getblockstats(const JSONRPCRequest& request)
pindex = chainActive[height];
} else {
- const std::string strHash = request.params[0].get_str();
- const uint256 hash(uint256S(strHash));
+ const uint256 hash(ParseHashV(request.params[0], "hash_or_height"));
pindex = LookupBlockIndex(hash);
if (!pindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp
index 85b864e6b9..c95145b204 100644
--- a/src/rpc/mining.cpp
+++ b/src/rpc/mining.cpp
@@ -247,7 +247,7 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request)
LOCK(cs_main);
- uint256 hash = ParseHashStr(request.params[0].get_str(), "txid");
+ uint256 hash(ParseHashV(request.params[0], "txid"));
CAmount nAmount = request.params[2].get_int64();
if (!(request.params[1].isNull() || request.params[1].get_real() == 0)) {
@@ -456,7 +456,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
// Format: <hashBestChain><nTransactionsUpdatedLast>
std::string lpstr = lpval.get_str();
- hashWatchedChain.SetHex(lpstr.substr(0, 64));
+ hashWatchedChain = ParseHashV(lpstr.substr(0, 64), "longpollid");
nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64));
}
else
diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp
index 3b3f43edea..9f94307949 100644
--- a/src/rpc/rawtransaction.cpp
+++ b/src/rpc/rawtransaction.cpp
@@ -229,9 +229,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
UniValue txids = request.params[0].get_array();
for (unsigned int idx = 0; idx < txids.size(); idx++) {
const UniValue& txid = txids[idx];
- if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
- throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid txid ")+txid.get_str());
- uint256 hash(uint256S(txid.get_str()));
+ uint256 hash(ParseHashV(txid, "txid"));
if (setTxids.count(hash))
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated txid: ")+txid.get_str());
setTxids.insert(hash);
@@ -242,7 +240,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
uint256 hashBlock;
if (!request.params[1].isNull()) {
LOCK(cs_main);
- hashBlock = uint256S(request.params[1].get_str());
+ hashBlock = ParseHashV(request.params[1], "blockhash");
pblockindex = LookupBlockIndex(hashBlock);
if (!pblockindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
index 10040b1255..85383eb3bc 100644
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -117,16 +117,12 @@ CAmount AmountFromValue(const UniValue& value)
uint256 ParseHashV(const UniValue& v, std::string strName)
{
- std::string strHex;
- if (v.isStr())
- strHex = v.get_str();
+ std::string strHex(v.get_str());
+ if (64 != strHex.length())
+ throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d, for '%s')", strName, 64, strHex.length(), strHex));
if (!IsHex(strHex)) // Note: IsHex("") is false
throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')");
- if (64 != strHex.length())
- throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s must be of length %d (not %d)", strName, 64, strHex.length()));
- uint256 result;
- result.SetHex(strHex);
- return result;
+ return uint256S(strHex);
}
uint256 ParseHashO(const UniValue& o, std::string strKey)
{
diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp
index d09af1dbd1..d08b80cc20 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -416,8 +416,7 @@ UniValue removeprunedfunds(const JSONRPCRequest& request)
LOCK2(cs_main, pwallet->cs_wallet);
- uint256 hash;
- hash.SetHex(request.params[0].get_str());
+ uint256 hash(ParseHashV(request.params[0], "txid"));
std::vector<uint256> vHash;
vHash.push_back(hash);
std::vector<uint256> vHashOut;
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 456f08bc14..fec8f69019 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2231,9 +2231,8 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
isminefilter filter = ISMINE_SPENDABLE;
if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
- uint256 blockId;
+ uint256 blockId(ParseHashV(request.params[0], "blockhash"));
- blockId.SetHex(request.params[0].get_str());
paltindex = pindex = LookupBlockIndex(blockId);
if (!pindex) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
@@ -2362,8 +2361,7 @@ static UniValue gettransaction(const JSONRPCRequest& request)
LOCK2(cs_main, pwallet->cs_wallet);
- uint256 hash;
- hash.SetHex(request.params[0].get_str());
+ uint256 hash(ParseHashV(request.params[0], "txid"));
isminefilter filter = ISMINE_SPENDABLE;
if(!request.params[1].isNull())
@@ -2430,8 +2428,7 @@ static UniValue abandontransaction(const JSONRPCRequest& request)
LOCK2(cs_main, pwallet->cs_wallet);
- uint256 hash;
- hash.SetHex(request.params[0].get_str());
+ uint256 hash(ParseHashV(request.params[0], "txid"));
if (!pwallet->mapWallet.count(hash)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
@@ -2836,17 +2833,13 @@ static UniValue lockunspent(const JSONRPCRequest& request)
{"vout", UniValueType(UniValue::VNUM)},
});
- const std::string& txid = find_value(o, "txid").get_str();
- if (!IsHex(txid)) {
- throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
- }
-
+ const uint256 txid(ParseHashO(o, "txid"));
const int nOutput = find_value(o, "vout").get_int();
if (nOutput < 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
}
- const COutPoint outpt(uint256S(txid), nOutput);
+ const COutPoint outpt(txid, nOutput);
const auto it = pwallet->mapWallet.find(outpt.hash);
if (it == pwallet->mapWallet.end()) {
@@ -3701,8 +3694,7 @@ static UniValue bumpfee(const JSONRPCRequest& request)
}
RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
- uint256 hash;
- hash.SetHex(request.params[0].get_str());
+ uint256 hash(ParseHashV(request.params[0], "txid"));
// optional parameters
CAmount totalFee = 0;
diff --git a/test/functional/mining_prioritisetransaction.py b/test/functional/mining_prioritisetransaction.py
index 85f1af6682..e16e1e242f 100755
--- a/test/functional/mining_prioritisetransaction.py
+++ b/test/functional/mining_prioritisetransaction.py
@@ -24,7 +24,8 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
assert_raises_rpc_error(-1, "prioritisetransaction", self.nodes[0].prioritisetransaction, '', 0, 0, 0)
# Test `prioritisetransaction` invalid `txid`
- assert_raises_rpc_error(-1, "txid must be hexadecimal string", self.nodes[0].prioritisetransaction, txid='foo', fee_delta=0)
+ assert_raises_rpc_error(-8, "txid must be of length 64 (not 3, for 'foo')", self.nodes[0].prioritisetransaction, txid='foo', fee_delta=0)
+ assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'Zd1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000')", self.nodes[0].prioritisetransaction, txid='Zd1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000', fee_delta=0)
# Test `prioritisetransaction` invalid `dummy`
txid = '1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000'
diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py
index cb4c9867a3..36cd8f5b09 100755
--- a/test/functional/p2p_compactblocks.py
+++ b/test/functional/p2p_compactblocks.py
@@ -287,7 +287,7 @@ class CompactBlocksTest(BitcoinTestFramework):
block_hash = int(node.generate(1)[0], 16)
# Store the raw block in our internal format.
- block = FromHex(CBlock(), node.getblock("%02x" % block_hash, False))
+ block = FromHex(CBlock(), node.getblock("%064x" % block_hash, False))
for tx in block.vtx:
tx.calc_sha256()
block.rehash()
diff --git a/test/functional/p2p_sendheaders.py b/test/functional/p2p_sendheaders.py
index 095cc4b734..ff377721cb 100755
--- a/test/functional/p2p_sendheaders.py
+++ b/test/functional/p2p_sendheaders.py
@@ -402,7 +402,7 @@ class SendHeadersTest(BitcoinTestFramework):
block_time += 9
- fork_point = self.nodes[0].getblock("%02x" % new_block_hashes[0])["previousblockhash"]
+ fork_point = self.nodes[0].getblock("%064x" % new_block_hashes[0])["previousblockhash"]
fork_point = int(fork_point, 16)
# Use getblocks/getdata
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index 17e24453e5..a908596ab3 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -125,7 +125,9 @@ class BlockchainTest(BitcoinTestFramework):
# Test `getchaintxstats` invalid `blockhash`
assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].getchaintxstats, blockhash=0)
- assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getchaintxstats, blockhash='0')
+ assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 1, for '0')", self.nodes[0].getchaintxstats, blockhash='0')
+ assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].getchaintxstats, blockhash='ZZZ0000000000000000000000000000000000000000000000000000000000000')
+ assert_raises_rpc_error(-5, "Block not found", self.nodes[0].getchaintxstats, blockhash='0000000000000000000000000000000000000000000000000000000000000000')
blockhash = self.nodes[0].getblockhash(200)
self.nodes[0].invalidateblock(blockhash)
assert_raises_rpc_error(-8, "Block is not in main chain", self.nodes[0].getchaintxstats, blockhash=blockhash)
@@ -206,7 +208,9 @@ class BlockchainTest(BitcoinTestFramework):
def _test_getblockheader(self):
node = self.nodes[0]
- assert_raises_rpc_error(-5, "Block not found", node.getblockheader, "nonsense")
+ assert_raises_rpc_error(-8, "hash must be of length 64 (not 8, for 'nonsense')", node.getblockheader, "nonsense")
+ assert_raises_rpc_error(-8, "hash must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')", node.getblockheader, "ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")
+ assert_raises_rpc_error(-5, "Block not found", node.getblockheader, "0cf7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844")
besthash = node.getbestblockhash()
secondbesthash = node.getblockhash(199)
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index 48b4a4a9db..a1bfb00e16 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -76,8 +76,9 @@ class RawTransactionsTest(BitcoinTestFramework):
txid = '1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000'
assert_raises_rpc_error(-3, "Expected type array", self.nodes[0].createrawtransaction, 'foo', {})
assert_raises_rpc_error(-1, "JSON value is not an object as expected", self.nodes[0].createrawtransaction, ['foo'], {})
- assert_raises_rpc_error(-8, "txid must be hexadecimal string", self.nodes[0].createrawtransaction, [{}], {})
- assert_raises_rpc_error(-8, "txid must be hexadecimal string", self.nodes[0].createrawtransaction, [{'txid': 'foo'}], {})
+ assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].createrawtransaction, [{}], {})
+ assert_raises_rpc_error(-8, "txid must be of length 64 (not 3, for 'foo')", self.nodes[0].createrawtransaction, [{'txid': 'foo'}], {})
+ assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844')", self.nodes[0].createrawtransaction, [{'txid': 'ZZZ7bb8b1697ea987f3b223ba7819250cae33efacb068d23dc24859824a77844'}], {})
assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", self.nodes[0].createrawtransaction, [{'txid': txid}], {})
assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", self.nodes[0].createrawtransaction, [{'txid': txid, 'vout': 'foo'}], {})
assert_raises_rpc_error(-8, "Invalid parameter, vout must be positive", self.nodes[0].createrawtransaction, [{'txid': txid, 'vout': -1}], {})
@@ -165,9 +166,10 @@ class RawTransactionsTest(BitcoinTestFramework):
# We should not get the tx if we provide an unrelated block
assert_raises_rpc_error(-5, "No such transaction found", self.nodes[0].getrawtransaction, tx, True, block2)
# An invalid block hash should raise the correct errors
- assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal", self.nodes[0].getrawtransaction, tx, True, True)
- assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal", self.nodes[0].getrawtransaction, tx, True, "foobar")
- assert_raises_rpc_error(-8, "parameter 3 must be of length 64", self.nodes[0].getrawtransaction, tx, True, "abcd1234")
+ assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].getrawtransaction, tx, True, True)
+ assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 6, for 'foobar')", self.nodes[0].getrawtransaction, tx, True, "foobar")
+ assert_raises_rpc_error(-8, "parameter 3 must be of length 64 (not 8, for 'abcd1234')", self.nodes[0].getrawtransaction, tx, True, "abcd1234")
+ assert_raises_rpc_error(-8, "parameter 3 must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].getrawtransaction, tx, True, "ZZZ0000000000000000000000000000000000000000000000000000000000000")
assert_raises_rpc_error(-5, "Block hash not found", self.nodes[0].getrawtransaction, tx, True, "0000000000000000000000000000000000000000000000000000000000000000")
# Undo the blocks and check in_active_chain
self.nodes[0].invalidateblock(block1)
diff --git a/test/functional/rpc_txoutproof.py b/test/functional/rpc_txoutproof.py
index c52a7397dc..26abed414a 100755
--- a/test/functional/rpc_txoutproof.py
+++ b/test/functional/rpc_txoutproof.py
@@ -62,12 +62,18 @@ class MerkleBlockTest(BitcoinTestFramework):
txid_spent = txin_spent["txid"]
txid_unspent = txid1 if txin_spent["txid"] != txid1 else txid2
+ # Invalid txids
+ assert_raises_rpc_error(-8, "txid must be of length 64 (not 32, for '00000000000000000000000000000000')", self.nodes[2].gettxoutproof, ["00000000000000000000000000000000"], blockhash)
+ assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[2].gettxoutproof, ["ZZZ0000000000000000000000000000000000000000000000000000000000000"], blockhash)
+ # Invalid blockhashes
+ assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 32, for '00000000000000000000000000000000')", self.nodes[2].gettxoutproof, [txid_spent], "00000000000000000000000000000000")
+ assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')", self.nodes[2].gettxoutproof, [txid_spent], "ZZZ0000000000000000000000000000000000000000000000000000000000000")
# We can't find the block from a fully-spent tx
assert_raises_rpc_error(-5, "Transaction not yet in block", self.nodes[2].gettxoutproof, [txid_spent])
# We can get the proof if we specify the block
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_spent], blockhash)), [txid_spent])
# We can't get the proof if we specify a non-existent block
- assert_raises_rpc_error(-5, "Block not found", self.nodes[2].gettxoutproof, [txid_spent], "00000000000000000000000000000000")
+ assert_raises_rpc_error(-5, "Block not found", self.nodes[2].gettxoutproof, [txid_spent], "0000000000000000000000000000000000000000000000000000000000000000")
# We can get the proof if the transaction is unspent
assert_equal(self.nodes[2].verifytxoutproof(self.nodes[2].gettxoutproof([txid_unspent])), [txid_unspent])
# We can get the proof if we provide a list of transactions and one of them is unspent. The ordering of the list should not matter.
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index 9c58b84819..add7b7629d 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -122,9 +122,15 @@ class WalletTest(BitcoinTestFramework):
assert_equal([unspent_0], self.nodes[2].listlockunspent())
self.nodes[2].lockunspent(True, [unspent_0])
assert_equal(len(self.nodes[2].listlockunspent()), 0)
- assert_raises_rpc_error(-8, "Invalid parameter, unknown transaction",
+ assert_raises_rpc_error(-8, "txid must be of length 64 (not 34, for '0000000000000000000000000000000000')",
self.nodes[2].lockunspent, False,
[{"txid": "0000000000000000000000000000000000", "vout": 0}])
+ assert_raises_rpc_error(-8, "txid must be hexadecimal string (not 'ZZZ0000000000000000000000000000000000000000000000000000000000000')",
+ self.nodes[2].lockunspent, False,
+ [{"txid": "ZZZ0000000000000000000000000000000000000000000000000000000000000", "vout": 0}])
+ assert_raises_rpc_error(-8, "Invalid parameter, unknown transaction",
+ self.nodes[2].lockunspent, False,
+ [{"txid": "0000000000000000000000000000000000000000000000000000000000000000", "vout": 0}])
assert_raises_rpc_error(-8, "Invalid parameter, vout index out of bounds",
self.nodes[2].lockunspent, False,
[{"txid": unspent_0["txid"], "vout": 999}])
diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py
index 63c179411c..a49be78f2b 100755
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -50,8 +50,10 @@ class ListSinceBlockTest (BitcoinTestFramework):
"42759cde25462784395a337460bde75f58e73d3f08bd31fdc3507cbac856a2c4")
assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
"0000000000000000000000000000000000000000000000000000000000000000")
- assert_raises_rpc_error(-5, "Block not found", self.nodes[0].listsinceblock,
+ assert_raises_rpc_error(-8, "blockhash must be of length 64 (not 11, for 'invalid-hex')", self.nodes[0].listsinceblock,
"invalid-hex")
+ assert_raises_rpc_error(-8, "blockhash must be hexadecimal string (not 'Z000000000000000000000000000000000000000000000000000000000000000')", self.nodes[0].listsinceblock,
+ "Z000000000000000000000000000000000000000000000000000000000000000")
def test_reorg(self):
'''