Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/rpc/output_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
},
Expand All @@ -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)",
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/wallet/rpc/addresses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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."},
},
Expand Down
18 changes: 12 additions & 6 deletions test/functional/rpc_invalid_address_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -22,6 +23,7 @@

PLATFORM_HRP = 'tdash'
PLATFORM_KEYHASH = bytes.fromhex('f7da0a2b5cbd4ff6bb2c4d89b67d2f3ffeec0525')
PLATFORM_SCRIPTHASH = bytes.fromhex('43fa183cf3fb6e9e7dc62b692aeb4fc8d8045636')


def platform_address(encoding, type_byte, payload):
Expand Down Expand Up @@ -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

Expand All @@ -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')
Expand Down
Loading