diff --git a/src/rpc/output_script.cpp b/src/rpc/output_script.cpp index c952366479f5..71b5eeb3dc56 100644 --- a/src/rpc/output_script.cpp +++ b/src/rpc/output_script.cpp @@ -27,7 +27,9 @@ static RPCHelpMan validateaddress() { return RPCHelpMan{ "validateaddress", - "\nReturn information about the given Dash address.\n", + "\nReturn information about the given Dash address.\n" + "A DIP-18 Dash Platform address is described against the credit output script an asset\n" + "lock would carry for it.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Dash address to validate"}, }, @@ -37,7 +39,7 @@ static RPCHelpMan validateaddress() {RPCResult::Type::BOOL, "isvalid", "If the address is valid or not"}, {RPCResult::Type::BOOL, "isplatform", /*optional=*/true, "If the address is a DIP-18 Dash Platform address"}, {RPCResult::Type::STR, "address", /*optional=*/true, "The Dash address validated"}, - {RPCResult::Type::STR_HEX, "scriptPubKey", /*optional=*/true, "The hex-encoded scriptPubKey generated by the address"}, + {RPCResult::Type::STR_HEX, "scriptPubKey", /*optional=*/true, "The hex-encoded scriptPubKey generated by the address. For a DIP-18 Platform address, the credit output script an asset lock would carry for it"}, {RPCResult::Type::BOOL, "isscript", /*optional=*/true, "If the key is a script"}, {RPCResult::Type::STR, "error", /*optional=*/true, "Error message, if any"}, {RPCResult::Type::ARR, "error_locations", /*optional=*/true, "Indices of likely error locations in address, if known (e.g. Bech32 errors)", @@ -73,6 +75,14 @@ static RPCHelpMan validateaddress() ret.pushKV("isvalid", true); ret.pushKV("isplatform", true); ret.pushKV("address", EncodePlatformDestination(platform_dest)); + + const CScript credit_output_script = GetScriptForPlatformDestination(platform_dest); + ret.pushKV("scriptPubKey", HexStr(credit_output_script)); + + CTxDestination l1_dest; + if (ExtractDestination(credit_output_script, l1_dest)) { + ret.pushKVs(DescribeAddress(l1_dest)); + } } else { ret.pushKV("isvalid", false); UniValue error_indices(UniValue::VARR); diff --git a/src/wallet/rpc/addresses.cpp b/src/wallet/rpc/addresses.cpp index 0a6ce8bdf526..6920c5749a3b 100644 --- a/src/wallet/rpc/addresses.cpp +++ b/src/wallet/rpc/addresses.cpp @@ -422,7 +422,8 @@ RPCHelpMan getaddressinfo() "\nReturn information about the given Dash address.\n" "Some of the information will only be present if the address is in the active wallet.\n" "A DIP-18 Dash Platform address is described against the credit output script an asset\n" - "lock would carry for it.\n", + "lock would carry for it; fields like \"ismine\" and \"solvable\" then refer to that\n" + "script, not to ownership of a Platform identity.\n", { {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Dash address for which to get information."}, }, diff --git a/test/functional/rpc_invalid_address_message.py b/test/functional/rpc_invalid_address_message.py index d8aa662703ec..15c6ca47af1d 100755 --- a/test/functional/rpc_invalid_address_message.py +++ b/test/functional/rpc_invalid_address_message.py @@ -8,6 +8,7 @@ from test_framework.script_util import ( keyhash_to_p2pkh_script, + scripthash_to_p2sh_script, ) from test_framework.segwit_addr import ( DIP18_TYPE_P2PKH, @@ -22,6 +23,7 @@ PLATFORM_HRP = 'tdash' PLATFORM_KEYHASH = bytes.fromhex('f7da0a2b5cbd4ff6bb2c4d89b67d2f3ffeec0525') +PLATFORM_SCRIPTHASH = bytes.fromhex('43fa183cf3fb6e9e7dc62b692aeb4fc8d8045636') def platform_address(encoding, type_byte, payload): @@ -79,13 +81,15 @@ def check_invalid(self, addr, error_str, error_locations=None): else: assert_equal(res['error_locations'], []) - def check_platform(self, addr, normalized): + def check_platform(self, addr, normalized, script, is_script): res = self.nodes[0].validateaddress(addr) assert_equal(res['isvalid'], True) assert_equal(res['isplatform'], True) assert_equal(res['address'], normalized) - # A Platform address has no layer-1 output script - assert 'scriptPubKey' not in res + # Described against the credit output script an asset lock would carry + # for it, consistent with getaddressinfo + assert_equal(res['scriptPubKey'], script.hex()) + assert_equal(res['isscript'], is_script) assert 'error' not in res assert 'error_locations' not in res @@ -106,9 +110,11 @@ def test_validateaddress(self): self.check_invalid(BECH32_INVALID_SIZE, 'Invalid Platform address payload length') # Valid Bech32m: DIP-18 Platform addresses, reported as such and normalized to lower case - self.check_platform(BECH32_VALID, BECH32_VALID) - self.check_platform(BECH32_VALID_CAPITALS, BECH32_VALID) - self.check_platform(BECH32_VALID_P2SH, BECH32_VALID_P2SH) + p2pkh_script = keyhash_to_p2pkh_script(PLATFORM_KEYHASH) + p2sh_script = scripthash_to_p2sh_script(PLATFORM_SCRIPTHASH) + self.check_platform(BECH32_VALID, BECH32_VALID, p2pkh_script, False) + self.check_platform(BECH32_VALID_CAPITALS, BECH32_VALID, p2pkh_script, False) + self.check_platform(BECH32_VALID_P2SH, BECH32_VALID_P2SH, p2sh_script, True) # Invalid Base58 self.check_invalid(BASE58_INVALID_PREFIX, 'Invalid prefix for Base58-encoded address')