mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-03 01:33:20 +02:00
Merge bitcoin/bitcoin#16807: Let validateaddress locate error in Bech32 address
88cc481092Modify copyright header on Bech32 code (Samuel Dobson)5599813b80Add lots of comments to Bech32 (Samuel Dobson)2eb5792ec7Add release notes for validateaddress Bech32 error detection (MeshCollider)42d6a029e5Refactor and add more tests for validateaddress (Samuel Dobson)c4979f77c1Add boost tests for bech32 error detection (MeshCollider)02a7bdee42Add error_locations to validateaddress RPC (Samuel Dobson)b62b67e06cAdd Bech32 error location function (Samuel Dobson)0b06e720c0More detailed error checking for base58 addresses (Samuel Dobson) Pull request description: Addresses (partially) #16779 - no GUI change in this PR Adds a LocateError function the bech32 library, which is then called by `validateaddress` RPC, (and then eventually from a GUI tool too, future work). I think modifying validateaddress is nicer than adding a separate RPC for this. Includes tests. Based on https://github.com/sipa/bech32/blob/master/ecc/javascript/bech32_ecc.js Credit to sipa for that code ACKs for top commit: laanwj: Code review and manually tested ACK88cc481092ryanofsky: Code review ACK88cc481092with caveat that I only checked the new `LocateErrors` code to try to verify it didn't have unsafe or unexpected operations or loop forever or crash. Did not try to verify behavior corresponds to the spec. In the worst case bugs here should just affect error messages not actual decoding of addresses so this seemed ok. w0xlt: tACK88cc481Tree-SHA512: 9c7fe9745bc7527f80a30bd4c1e3034e16b96a02cc7f6c268f91bfad08a6965a8064fe44230aa3f87e4fa3c938f662ff4446bc682c83cb48c1a3f95cf4186688
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
// Copyright (c) 2017 Pieter Wuille
|
||||
// Copyright (c) 2021 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
@@ -68,10 +69,36 @@ BOOST_AUTO_TEST_CASE(bech32_testvectors_invalid)
|
||||
"1qzzfhee",
|
||||
"a12UEL5L",
|
||||
"A12uEL5L",
|
||||
"abcdef1qpzrz9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
|
||||
};
|
||||
static const std::pair<std::string, int> ERRORS[] = {
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Bech32 string too long", 90},
|
||||
{"Missing separator", -1},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid Base 32 character", 2},
|
||||
{"Invalid separator position", 2},
|
||||
{"Invalid character or mixed case", 8},
|
||||
{"Invalid checksum", -1}, // The checksum is calculated using the uppercase form so the entire string is invalid, not just a few characters
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid character or mixed case", 3},
|
||||
{"Invalid character or mixed case", 3},
|
||||
{"Invalid checksum", 11}
|
||||
};
|
||||
int i = 0;
|
||||
for (const std::string& str : CASES) {
|
||||
const auto& err = ERRORS[i];
|
||||
const auto dec = bech32::Decode(str);
|
||||
BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
|
||||
std::vector<int> error_locations;
|
||||
std::string error = bech32::LocateErrors(str, error_locations);
|
||||
BOOST_CHECK_EQUAL(err.first, error);
|
||||
if (err.second == -1) BOOST_CHECK(error_locations.empty());
|
||||
else BOOST_CHECK_EQUAL(err.second, error_locations[0]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +118,37 @@ BOOST_AUTO_TEST_CASE(bech32m_testvectors_invalid)
|
||||
"au1s5cgom",
|
||||
"M1VUXWEZ",
|
||||
"16plkw9",
|
||||
"1p2gdwpf"
|
||||
"1p2gdwpf",
|
||||
"abcdef1l7aum6echk45nj2s0wdvt2fg8x9yrzpqzd3ryx",
|
||||
};
|
||||
static const std::pair<std::string, int> ERRORS[] = {
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Invalid character or mixed case", 0},
|
||||
{"Bech32 string too long", 90},
|
||||
{"Missing separator", -1},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid Base 32 character", 2},
|
||||
{"Invalid Base 32 character", 3},
|
||||
{"Invalid separator position", 2},
|
||||
{"Invalid Base 32 character", 8},
|
||||
{"Invalid Base 32 character", 7},
|
||||
{"Invalid checksum", -1},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid separator position", 0},
|
||||
{"Invalid checksum", 21},
|
||||
};
|
||||
int i = 0;
|
||||
for (const std::string& str : CASES) {
|
||||
const auto& err = ERRORS[i];
|
||||
const auto dec = bech32::Decode(str);
|
||||
BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
|
||||
std::vector<int> error_locations;
|
||||
std::string error = bech32::LocateErrors(str, error_locations);
|
||||
BOOST_CHECK_EQUAL(err.first, error);
|
||||
if (err.second == -1) BOOST_CHECK(error_locations.empty());
|
||||
else BOOST_CHECK_EQUAL(err.second, error_locations[0]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user