diff --git a/src/key_io.cpp b/src/key_io.cpp index fb6d7719b3..c6064aa25a 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -152,11 +152,14 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par uint160 hash; error_str = ""; + bool is_bech32 = !(bech32::Decode(str).encoding == bech32::Encoding::INVALID); + bool is_blech32 = !(blech32::Decode(str).encoding == blech32::Encoding::INVALID); + // Note this will be false if it is a valid Bech32 address for a different network - bool is_bech32 = (ToLower(str.substr(0, params.Bech32HRP().size())) == params.Bech32HRP()); - bool is_blech32 = (ToLower(str.substr(0, params.Blech32HRP().size())) == params.Blech32HRP()); + bool is_bech32_hrp = (ToLower(str.substr(0, params.Bech32HRP().size())) == params.Bech32HRP()); + bool is_blech32_hrp = (ToLower(str.substr(0, params.Blech32HRP().size())) == params.Blech32HRP()); - if (!is_bech32 && !is_blech32 && DecodeBase58Check(str, data, 55)) { + if (!is_bech32 && !is_blech32 && !is_bech32_hrp && !is_blech32_hrp && DecodeBase58Check(str, data, 55)) { // base58-encoded Bitcoin addresses. // Public-key-hash-addresses have version 0 (or 111 testnet). // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key. @@ -206,14 +209,14 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par error_str = "Invalid prefix for Base58-encoded address"; } return CNoDestination(); - } else if (!is_bech32 && !is_blech32) { + } else if (!is_bech32 && !is_blech32 && !is_bech32_hrp && !is_blech32_hrp) { // Try Base58 decoding without the checksum, using a much larger max length if (!DecodeBase58(str, data, 100)) { error_str = "Not a valid Bech32 or Base58 encoding"; } else { error_str = "Invalid checksum or length of Base58 address"; } - // return CNoDestination(); // ELEMENTS: FIXME + return CNoDestination(); } data.clear(); diff --git a/test/functional/rpc_invalid_address_message.py b/test/functional/rpc_invalid_address_message.py index 36ea40517b..459e3144be 100755 --- a/test/functional/rpc_invalid_address_message.py +++ b/test/functional/rpc_invalid_address_message.py @@ -13,7 +13,7 @@ BECH32_VALID = 'ert1qtmp74ayg7p24uslctssvjm06q5phz4yr7gdkdv' BECH32_VALID_CAPITALS = 'ERT1QTMP74AYG7P24USLCTSSVJM06Q5PHZ4YR7GDKDV' -BECH32_VALID_MULTISIG = 'ert1qdg3myrgvzw7ml9q0ejxhlkyxm7vl9r56yzkfgvzclrf4hkpx9yfqhpsuks' +BECH32_VALID_MULTISIG = 'ert1qmzm84udpuz6axdstxlpwafca7g7nh5w2yu8c7vqhe0rhjkcrfcfqwymvhe' BECH32_INVALID_BECH32 = 'ert1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqugsf3u' BECH32_INVALID_BECH32M = 'ert1qw508d6qejxtdg4y5r3zarvary0c5xw7kfqwaud' @@ -21,19 +21,19 @@ BECH32_INVALID_SIZE = 'ert1s0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v8n0nx0muaewav25pltc58' BECH32_INVALID_V0_SIZE = 'ert1qw508d6qejxtdg4y5r3zarvary0c5xw7kqq2287l0' BECH32_INVALID_PREFIX = 'bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx' -BECH32_TOO_LONG = 'bcrt1q049edschfnwystcqnsvyfpj23mpsg3jcedq9xv049edschfnwystcqnsvyfpj23mpsg3jcedq9xv049edschfnwystcqnsvyfpj23m' -BECH32_ONE_ERROR = 'bcrt1q049edschfnwystcqnsvyfpj23mpsg3jcedq9xv' -BECH32_ONE_ERROR_CAPITALS = 'BCRT1QPLMTZKC2XHARPPZDLNPAQL78RSHJ68U32RAH7R' -BECH32_TWO_ERRORS = 'bcrt1qax9suht3qv95sw33xavx8crpxduefdrsvgsklu' # should be bcrt1qax9suht3qv95sw33wavx8crpxduefdrsvgsklx -BECH32_NO_SEPARATOR = 'bcrtq049ldschfnwystcqnsvyfpj23mpsg3jcedq9xv' -BECH32_INVALID_CHAR = 'bcrt1q04oldschfnwystcqnsvyfpj23mpsg3jcedq9xv' -BECH32_MULTISIG_TWO_ERRORS = 'bcrt1qdg3myrgvzw7ml8q0ejxhlkyxn7vl9r56yzkfgvzclrf4hkpx9yfqhpsuks' -BECH32_WRONG_VERSION = 'bcrt1ptmp74ayg7p24uslctssvjm06q5phz4yrxucgnv' +BECH32_TOO_LONG = 'ert1q049edschfnwystcqnsvyfpj23mpsg3jcedq9xv049edschfnwystcqnsvyfpj23mpsg3jcedq9xv049edschfnwystcqnsvyfpj23m' +BECH32_ONE_ERROR = 'ert1qtmp7aayg7p24uslctssvjm06q5phz4yr7gdkdv' +BECH32_ONE_ERROR_CAPITALS = 'ERT1QTMP7AAYG7P24USLCTSSVJM06Q5PHZ4YR7GDKDV' +BECH32_TWO_ERRORS = 'ert1qtmp74syg7p24uslctsavjm06q5phz4yr7gdkdv' +BECH32_NO_SEPARATOR = 'ertq049ldschfnwystcqnsvyfpj23mpsg3jcedq9xv' +BECH32_INVALID_CHAR = 'ert1q04oldschfnwystcqnsvyfpj23mpsg3jcedq9xv' +BECH32_MULTISIG_TWO_ERRORS = 'ert1qmzm84udpua6axdstxlpwafca7g7na5w2yu8c7vqhe0rhjkcrfcfqwymvhe' +BECH32_WRONG_VERSION = 'ert1ptmp74ayg7p24uslctssvjm06q5phz4yr7gdkdv' BASE58_VALID = '2dcjQH4DQC3pMcSQkMkSQyPPEr7rZ6Ga4GR' BASE58_INVALID_PREFIX = '17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem' BASE58_INVALID_CHECKSUM = 'mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJJfn' -BASE58_INVALID_LENGTH = '2VKf7XKMrp4bVNVmuRbyCewkP8FhGLP2E54LHDPakr9Sq5mtU2' +BASE58_INVALID_LENGTH = '2dcjQH4DQC3pMcSQkMkSQyPPEr7rZ6Ga4GR7rZ6Ga4GR' INVALID_ADDRESS = 'asfah14i8fajz0123f' INVALID_ADDRESS_2 = '1q049ldschfnwystcqnsvyfpj23mpsg3jcedq9xv' @@ -71,36 +71,36 @@ def check_invalid(self, addr, error_str, error_locations=None): def test_validateaddress(self): # Invalid Bech32 self.check_invalid(BECH32_INVALID_SIZE, 'Invalid Bech32 address data size') - # self.check_invalid(BECH32_INVALID_PREFIX, 'Not a valid Bech32 or Base58 encoding') # ELEMENTS: FIXME + self.check_invalid(BECH32_INVALID_PREFIX, 'Invalid prefix for Bech32 address') self.check_invalid(BECH32_INVALID_BECH32, 'Version 1+ witness address must use Bech32m checksum') self.check_invalid(BECH32_INVALID_BECH32M, 'Version 0 witness address must use Bech32 checksum') self.check_invalid(BECH32_INVALID_VERSION, 'Invalid Bech32 address witness version') self.check_invalid(BECH32_INVALID_V0_SIZE, 'Invalid Bech32 v0 address data size') - self.check_invalid(BECH32_TOO_LONG, 'Bech32 string too long', list(range(90, 108))) + self.check_invalid(BECH32_TOO_LONG, 'Bech32 string too long', list(range(90, 107))) self.check_invalid(BECH32_ONE_ERROR, 'Invalid Bech32 checksum', [9]) - self.check_invalid(BECH32_TWO_ERRORS, 'Invalid Bech32 checksum', [22, 43]) - self.check_invalid(BECH32_ONE_ERROR_CAPITALS, 'Invalid Bech32 checksum', [38]) + self.check_invalid(BECH32_TWO_ERRORS, 'Invalid Bech32 checksum', [10, 23]) + self.check_invalid(BECH32_ONE_ERROR_CAPITALS, 'Invalid Bech32 checksum', [9]) self.check_invalid(BECH32_NO_SEPARATOR, 'Missing separator') - self.check_invalid(BECH32_INVALID_CHAR, 'Invalid Base 32 character', [8]) - self.check_invalid(BECH32_MULTISIG_TWO_ERRORS, 'Invalid Bech32 checksum', [19, 30]) - self.check_invalid(BECH32_WRONG_VERSION, 'Invalid Bech32 checksum', [5]) + self.check_invalid(BECH32_INVALID_CHAR, 'Invalid Base 32 character', [7]) + self.check_invalid(BECH32_MULTISIG_TWO_ERRORS, 'Invalid Bech32 checksum', [14, 33]) + self.check_invalid(BECH32_WRONG_VERSION, 'Invalid Bech32 checksum', [4]) # Valid Bech32 self.check_valid(BECH32_VALID) self.check_valid(BECH32_VALID_CAPITALS) - # self.check_valid(BECH32_VALID_MULTISIG) # ELEMENTS: FIXME + self.check_valid(BECH32_VALID_MULTISIG) # Invalid Base58 self.check_invalid(BASE58_INVALID_PREFIX, 'Invalid prefix for Base58-encoded address') - # self.check_invalid(BASE58_INVALID_CHECKSUM, 'Invalid checksum or length of Base58 address') # ELEMENTS: FIXME - # self.check_invalid(BASE58_INVALID_LENGTH, 'Invalid checksum or length of Base58 address') # ELEMENTS: FIXME + self.check_invalid(BASE58_INVALID_CHECKSUM, 'Invalid checksum or length of Base58 address') + self.check_invalid(BASE58_INVALID_LENGTH, 'Invalid checksum or length of Base58 address') # Valid Base58 self.check_valid(BASE58_VALID) # Invalid address format - # self.check_invalid(INVALID_ADDRESS, 'Not a valid Bech32 or Base58 encoding') # ELEMENTS: FIXME - # self.check_invalid(INVALID_ADDRESS_2, 'Not a valid Bech32 or Base58 encoding') # ELEMENTS: FIXME + self.check_invalid(INVALID_ADDRESS, 'Not a valid Bech32 or Base58 encoding') + self.check_invalid(INVALID_ADDRESS_2, 'Not a valid Bech32 or Base58 encoding') # ELEMENTS info = self.nodes[0].validateaddress(BLECH32_INVALID_SIZE)