forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge bitcoin#27727: rpc: Fix invalid bech32 address handling
eeee55f rpc: Fix invalid bech32 handling (MarcoFalke) Pull request description: Currently the handling of invalid bech32(m) addresses over RPC has many issues: * No error for invalid addresses is reported, leading to internal bugs via `CHECK_NONFATAL`, see bitcoin#27723 * The error messages use "data size" (the meaning of which is unclear to the user, because the witness program data and bech32 section data are related but different) when they mean "program size" Fix all issues. Also, use the BIP 173 and BIP 350 test vectors. ACKs for top commit: achow101: ACK eeee55f brunoerg: crACK eeee55f Tree-SHA512: c8639ee49e2a54b740b72d66bc4a40352dd553a6e3220dea9f94e48e33124f21f597a2817cb405d0a4c88d21df1013c0a4877a01370a2d326aa2cff1f9c381a8
- Loading branch information
Showing
4 changed files
with
217 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
#!/usr/bin/env python3 | ||
# Copyright (c) 2023 The Bitcoin Core developers | ||
# Distributed under the MIT software license, see the accompanying | ||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
"""Test validateaddress for main chain""" | ||
|
||
from test_framework.test_framework import BitcoinTestFramework | ||
|
||
from test_framework.util import assert_equal | ||
|
||
INVALID_DATA = [ | ||
# BIP 173 | ||
( | ||
"tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", | ||
"Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # Invalid hrp | ||
[], | ||
), | ||
("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", "Invalid Bech32 checksum", [41]), | ||
( | ||
"BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", | ||
"Version 1+ witness address must use Bech32m checksum", | ||
[], | ||
), | ||
( | ||
"bc1rw5uspcuh", | ||
"Version 1+ witness address must use Bech32m checksum", # Invalid program length | ||
[], | ||
), | ||
( | ||
"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", | ||
"Version 1+ witness address must use Bech32m checksum", # Invalid program length | ||
[], | ||
), | ||
( | ||
"BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", | ||
"Invalid Bech32 v0 address program size (16 byte), per BIP141", | ||
[], | ||
), | ||
( | ||
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7", | ||
"Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Mixed case | ||
[], | ||
), | ||
( | ||
"BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3t4", | ||
"Invalid character or mixed case", # bc1, Mixed case, not in BIP 173 test vectors | ||
[40], | ||
), | ||
( | ||
"bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du", | ||
"Version 1+ witness address must use Bech32m checksum", # Wrong padding | ||
[], | ||
), | ||
( | ||
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", | ||
"Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Non-zero padding in 8-to-5 conversion | ||
[], | ||
), | ||
("bc1gmk9yu", "Empty Bech32 data section", []), | ||
# BIP 350 | ||
( | ||
"tc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq5zuyut", | ||
"Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # Invalid human-readable part | ||
[], | ||
), | ||
( | ||
"bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqh2y7hd", | ||
"Version 1+ witness address must use Bech32m checksum", # Invalid checksum (Bech32 instead of Bech32m) | ||
[], | ||
), | ||
( | ||
"tb1z0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqglt7rf", | ||
"Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Invalid checksum (Bech32 instead of Bech32m) | ||
[], | ||
), | ||
( | ||
"BC1S0XLXVLHEMJA6C4DQV22UAPCTQUPFHLXM9H8Z3K2E72Q4K9HCZ7VQ54WELL", | ||
"Version 1+ witness address must use Bech32m checksum", # Invalid checksum (Bech32 instead of Bech32m) | ||
[], | ||
), | ||
( | ||
"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kemeawh", | ||
"Version 0 witness address must use Bech32 checksum", # Invalid checksum (Bech32m instead of Bech32) | ||
[], | ||
), | ||
( | ||
"tb1q0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq24jc47", | ||
"Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Invalid checksum (Bech32m instead of Bech32) | ||
[], | ||
), | ||
( | ||
"bc1p38j9r5y49hruaue7wxjce0updqjuyyx0kh56v8s25huc6995vvpql3jow4", | ||
"Invalid Base 32 character", # Invalid character in checksum | ||
[59], | ||
), | ||
( | ||
"BC130XLXVLHEMJA6C4DQV22UAPCTQUPFHLXM9H8Z3K2E72Q4K9HCZ7VQ7ZWS8R", | ||
"Invalid Bech32 address witness version", | ||
[], | ||
), | ||
("bc1pw5dgrnzv", "Invalid Bech32 address program size (1 byte)", []), | ||
( | ||
"bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v8n0nx0muaewav253zgeav", | ||
"Invalid Bech32 address program size (41 byte)", | ||
[], | ||
), | ||
( | ||
"BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", | ||
"Invalid Bech32 v0 address program size (16 byte), per BIP141", | ||
[], | ||
), | ||
( | ||
"tb1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq47Zagq", | ||
"Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Mixed case | ||
[], | ||
), | ||
( | ||
"bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v07qwwzcrf", | ||
"Invalid padding in Bech32 data section", # zero padding of more than 4 bits | ||
[], | ||
), | ||
( | ||
"tb1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vpggkg4j", | ||
"Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Non-zero padding in 8-to-5 conversion | ||
[], | ||
), | ||
("bc1gmk9yu", "Empty Bech32 data section", []), | ||
] | ||
VALID_DATA = [ | ||
# BIP 350 | ||
( | ||
"BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4", | ||
"0014751e76e8199196d454941c45d1b3a323f1433bd6", | ||
), | ||
# ( | ||
# "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7", | ||
# "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", | ||
# ), | ||
( | ||
"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", | ||
"00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", | ||
), | ||
( | ||
"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kt5nd6y", | ||
"5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6", | ||
), | ||
("BC1SW50QGDZ25J", "6002751e"), | ||
("bc1zw508d6qejxtdg4y5r3zarvaryvaxxpcs", "5210751e76e8199196d454941c45d1b3a323"), | ||
# ( | ||
# "tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy", | ||
# "0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", | ||
# ), | ||
( | ||
"bc1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses5wp4dt", | ||
"0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", | ||
), | ||
# ( | ||
# "tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c", | ||
# "5120000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", | ||
# ), | ||
( | ||
"bc1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses7epu4h", | ||
"5120000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", | ||
), | ||
( | ||
"bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0", | ||
"512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", | ||
), | ||
] | ||
|
||
|
||
class ValidateAddressMainTest(BitcoinTestFramework): | ||
def set_test_params(self): | ||
self.setup_clean_chain = True | ||
self.chain = "" # main | ||
self.num_nodes = 1 | ||
self.extra_args = [["-prune=899"]] * self.num_nodes | ||
|
||
def check_valid(self, addr, spk): | ||
info = self.nodes[0].validateaddress(addr) | ||
assert_equal(info["isvalid"], True) | ||
assert_equal(info["scriptPubKey"], spk) | ||
assert "error" not in info | ||
assert "error_locations" not in info | ||
|
||
def check_invalid(self, addr, error_str, error_locations): | ||
res = self.nodes[0].validateaddress(addr) | ||
assert_equal(res["isvalid"], False) | ||
assert_equal(res["error"], error_str) | ||
assert_equal(res["error_locations"], error_locations) | ||
|
||
def test_validateaddress(self): | ||
for (addr, error, locs) in INVALID_DATA: | ||
self.check_invalid(addr, error, locs) | ||
for (addr, spk) in VALID_DATA: | ||
self.check_valid(addr, spk) | ||
|
||
def run_test(self): | ||
self.test_validateaddress() | ||
|
||
|
||
if __name__ == "__main__": | ||
ValidateAddressMainTest().main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters