Skip to content

Commit 362e901

Browse files
committed
Merge #18466: rpc: fix invalid parameter error codes for {sign,verify}message RPCs
a5cfb40 doc: release note for changed {sign,verify}message error codes (Sebastian Falbesoner) 9e399b9 test: check parameter validity in rpc_signmessage.py (Sebastian Falbesoner) e62f0c7 rpc: fix {sign,message}verify RPC errors for invalid address/signature (Sebastian Falbesoner) Pull request description: RPCs that accept address parameters usually return the intended error code `RPC_INVALID_ADDRESS_OR_KEY` (-5) if a passed address is invalid. The two exceptions to the rule are `signmessage` and `verifymessage`, which return `RPC_TYPE_ERROR` (-3) in this case instead. Oddly enough `verifymessage` returns `RPC_INVALID_ADDRESS_OR_KEY` when the _signature_ was malformed, where `RPC_TYPE_ERROR` would be more approriate. This PR fixes these inaccuracies and as well adds tests to `rpc_signmessage.py` that check the parameter validity and error codes for the related RPCs `signmessagewithprivkey`, `signmessage` and `verifymessage`. master branch: ``` $ ./bitcoin-cli signmessage invalid_addr message error code: -3 error message: Invalid address $ ./bitcoin-cli verifymessage invalid_addr dummy_sig message error code: -3 error message: Invalid address $ ./bitcoin-cli verifymessage 12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX invalid_sig message error code: -5 error message: Malformed base64 encoding ``` PR branch: ``` $ ./bitcoin-cli signmessage invalid_addr message error code: -5 error message: Invalid address $ ./bitcoin-cli verifymessage invalid_addr dummy_sig message error code: -5 error message: Invalid address $ ./bitcoin-cli verifymessage 12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX invalid_sig message error code: -3 error message: Malformed base64 encoding ``` ACKs for top commit: laanwj: Code review ACK a5cfb40 meshcollider: utACK a5cfb40 Tree-SHA512: bae0c4595a2603cea66090f6033785601837b45fd853052312b3a39d8520566c581994b68f693dd247c22586c638c3b7689c849085cce548cc36b9bf0e119d2d
2 parents e52ce9f + a5cfb40 commit 362e901

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

doc/release-notes-18466.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Low-level RPC changes
2+
---------------------
3+
4+
- Error codes have been updated to be more accurate for the following error cases (#18466):
5+
- `signmessage` now returns RPC_INVALID_ADDRESS_OR_KEY (-5) if the
6+
passed address is invalid. Previously returned RPC_TYPE_ERROR (-3).
7+
- `verifymessage` now returns RPC_INVALID_ADDRESS_OR_KEY (-5) if the
8+
passed address is invalid. Previously returned RPC_TYPE_ERROR (-3).
9+
- `verifymessage` now returns RPC_TYPE_ERROR (-3) if the passed signature
10+
is malformed. Previously returned RPC_INVALID_ADDRESS_OR_KEY (-5).

src/rpc/misc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,11 @@ static RPCHelpMan verifymessage()
305305

306306
switch (MessageVerify(strAddress, strSign, strMessage)) {
307307
case MessageVerificationResult::ERR_INVALID_ADDRESS:
308-
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
308+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
309309
case MessageVerificationResult::ERR_ADDRESS_NO_KEY:
310310
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
311311
case MessageVerificationResult::ERR_MALFORMED_SIGNATURE:
312-
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
312+
throw JSONRPCError(RPC_TYPE_ERROR, "Malformed base64 encoding");
313313
case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED:
314314
case MessageVerificationResult::ERR_NOT_SIGNED:
315315
return false;

src/wallet/rpcwallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ static RPCHelpMan signmessage()
630630

631631
CTxDestination dest = DecodeDestination(strAddress);
632632
if (!IsValidDestination(dest)) {
633-
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
633+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
634634
}
635635

636636
const PKHash* pkhash = std::get_if<PKHash>(&dest);

test/functional/rpc_signmessage.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
"""Test RPC commands for signing and verifying messages."""
66

77
from test_framework.test_framework import BitcoinTestFramework
8-
from test_framework.util import assert_equal
8+
from test_framework.util import (
9+
assert_equal,
10+
assert_raises_rpc_error,
11+
)
912

1013
class SignMessagesTest(BitcoinTestFramework):
1114
def set_test_params(self):
@@ -38,5 +41,22 @@ def run_test(self):
3841
assert not self.nodes[0].verifymessage(other_address, signature, message)
3942
assert not self.nodes[0].verifymessage(address, other_signature, message)
4043

44+
self.log.info('test parameter validity and error codes')
45+
# signmessage(withprivkey) have two required parameters
46+
for num_params in [0, 1, 3, 4, 5]:
47+
param_list = ["dummy"]*num_params
48+
assert_raises_rpc_error(-1, "signmessagewithprivkey", self.nodes[0].signmessagewithprivkey, *param_list)
49+
assert_raises_rpc_error(-1, "signmessage", self.nodes[0].signmessage, *param_list)
50+
# verifymessage has three required parameters
51+
for num_params in [0, 1, 2, 4, 5]:
52+
param_list = ["dummy"]*num_params
53+
assert_raises_rpc_error(-1, "verifymessage", self.nodes[0].verifymessage, *param_list)
54+
# invalid key or address provided
55+
assert_raises_rpc_error(-5, "Invalid private key", self.nodes[0].signmessagewithprivkey, "invalid_key", message)
56+
assert_raises_rpc_error(-5, "Invalid address", self.nodes[0].signmessage, "invalid_addr", message)
57+
assert_raises_rpc_error(-5, "Invalid address", self.nodes[0].verifymessage, "invalid_addr", signature, message)
58+
# malformed signature provided
59+
assert_raises_rpc_error(-3, "Malformed base64 encoding", self.nodes[0].verifymessage, self.nodes[0].getnewaddress(), "invalid_sig", message)
60+
4161
if __name__ == '__main__':
4262
SignMessagesTest().main()

0 commit comments

Comments
 (0)