-
Notifications
You must be signed in to change notification settings - Fork 35.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhanced error messages for invalid network prefix during address parsing. #27260
base: master
Are you sure you want to change the base?
Conversation
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
Please keep your changes, and "fixes" commits squashed. Looks like your changing the file perms on at least one file, is that intentional? |
Will do. No it was not intentional but was a side effect of moving 3 files over scp to a different host. This has been resolved and commits squashed. |
c98f7cc
to
911c8b6
Compare
3c0fcda
to
aff7635
Compare
Needs rebase on current master, if still relevant |
ef46a30
to
5ff2490
Compare
I believe this PR is still very relevant because it substantially improves the logic around address decoding and specifically the displaying of errors in the GUI and RPC. With that said I have rebased and this code is passing all tests other than |
Thanks, the reason I mentioned it was the silent merge conflict: |
Is there a good way to detect these silent conflicts earlier? Usually I get notified via email when there are issues that need rebased; this is the first time one has happened without a notification. Thanks |
0000000
to
0000000
Compare
Signed-off-by: russeree <git@qrsnap.io>
1234567
to
0000000
Compare
Signed-off-by: russeree <git@qrsnap.io>
Signed-off-by: russeree <git@qrsnap.io>
This commit addresses an issue in Bitcoin Core where an incorrect bech32 prefix would lead to the address being treated as entirely invalid for both base58 and bech32 encoding, without providing the user with an appropriate error message. Base58 error handling was also improved. Changes: - An incorrect bech32 address error message now presents the expected ChainParams hrp and network to the user. - A Bech32 address with an incorrect ChainParams prefix is not automatically handled as base58, increasing the accuracy and readability of user facing error messages. - An incorrect base58 address prefix now presents the user with the expected prefixes for the current ChainParams, which are deterministically computed in util/base58_address.(cpp/h) - Functional tests were refactored to reflect the additional accuracy of error messages. - Added GetChainTypeDisplayString(), which generates a user facing chain type string for "Bitcoin", "testnet", "signet", and "regtest". This is used for displaying the user's active chain when displaying errors. As per Luke Dashjr, "mainnet" is not used in user facing messages. - Added Base58PrefixesFromVersionBytes(), which when given a total length in bytes and a base58 prefix will give the user all possible single character prefixes for the encoded base58 string. - Bech32 error decoding now handles the cases where the input has neither base58 or bech32 characters and the inverse where the input has both valid base58 and bech32 characters. - Increased code readability through the use of structured bindings. - Added a multiple separators check to bech32.cpp this is to convert incorrect error messages about a singular separator position into a message that covers multiple separators and their positions. - Added a minimum length check to bech32.cpp and ErrorLocatiosn message with the locations being a vector of the chars positions up to the minimum length of 8 chars. A huge thanks to D++ for the extensive contributions Co-authored-by: D++ <82842780+dplusplus1024@users.noreply.github.com> Signed-off-by: russeree <git@qrsnap.io>
Approach ACK |
Signed-off-by: russeree <git@qrsnap.io>
if (str.find('1') != pos) { | ||
for(size_t search_idx = 0; search_idx < str.size(); ++search_idx) { | ||
if(str[search_idx] == '1') { | ||
error_locations.push_back(search_idx); | ||
} | ||
} | ||
return std::make_pair("Multiple separators", std::move(error_locations)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 0000000 "Add bech32 error short & multiple separators cases"
This is incorrect. 1
is an allowed character in the human readable part, hence a multiple separators check doesn't make sense. The real separator is simply the last 1
that appears. See https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32
src/util/base58_address.cpp
Outdated
|
||
#include <algorithm> | ||
|
||
std::vector<char> Base58PrefixesFromVersionByte(size_t length, unsigned char version_byte) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 0000000 "Add Base58 Address Prefix Decoder"
It seems a bit odd to me to do all of this work to compute these prefixes just for error messaging. ISTM it would be a lot simpler to just hard code them into chainparams anyways. It's not as if the prefixes will ever change, and new ones are unlikely to be added.
Merging this code seems like an additional maintenance burden for very little gain.
Also, if you insist on keeping this code, it should be placed into its final location when introduced instead of moved in the last commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The choice to do this was a response to the above comment. I would agree chainparams would be the place to implement a hardcoded (char[], stringview) prefix. Another advantage is that lookup is likely faster; so if a user is frequently getting errors it may save a few them a few cycles.
🐙 This pull request conflicts with the target branch and needs rebase. |
Issue:
Simply
DecodeDestination
does not handle errors where the user inputs a valid address for the wrong network. e.x. testnet while running client on mainnetThe current error
not a valid Bech32 or Base58 encoding
for a valid address on a different network is entirely incorrect. This is because of the is_bech32 variable used at the core ofDecodeDestination
logic only checks that the prefix matches. If it doesn't it just starts running everything asDecodeBase58Check
regardless if the Bech32 String was actually valid.Proposed Solution:
Base58 Addresses with invalid prefixes will now display network and expected values.
Invalid or unsupported Base58-encoded address.
Invalid or unsupported Base58 testnet address. Expected prefix m, n, or 2
Bech32 Addresses with invalid prefixes will now display network and expected values. The current from of the error is completely incorrect when the user passes valid Bech32 for the wrong network.
Invalid or unsupported Segwit (Bech32) or Base58 encoding.
Invalid chain prefix for testnet. Expected tb got bc
Reference
#26290
Implementation :
Simply put, don't delay the attempt to decode the string as Bech32 using Bech32::Decode(str). This takes a minimal amount CPU cycles to perform and is acceptable to do since this operation is not performed often.
Once you get the decoding status of the string as bech32, do the same with DecodeBase58 using a len of 100 and DecodeBase58Check. This gives you enough information to start properly decoding errors.
After you have decoded the address in various formats run though the logic and display errors for invalid addresses with the network names and expected values when the user just misses the prefix.
Update 1: #27260 (comment)
Other Notes