|
| 1 | +#!/usr/bin/env python3 |
| 2 | +# Copyright (c) 2023 The Bitcoin Core developers |
| 3 | +# Distributed under the MIT software license, see the accompanying |
| 4 | +# file COPYING or http://www.opensource.org/licenses/mit-license.php. |
| 5 | +"""Test validateaddress for main chain""" |
| 6 | + |
| 7 | +from test_framework.test_framework import BitcoinTestFramework |
| 8 | + |
| 9 | +from test_framework.util import assert_equal |
| 10 | + |
| 11 | +INVALID_DATA = [ |
| 12 | + # BIP 173 |
| 13 | + ( |
| 14 | + "tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", |
| 15 | + "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # Invalid hrp |
| 16 | + [], |
| 17 | + ), |
| 18 | + ("bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", "Invalid Bech32 checksum", [41]), |
| 19 | + ( |
| 20 | + "BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", |
| 21 | + "Version 1+ witness address must use Bech32m checksum", |
| 22 | + [], |
| 23 | + ), |
| 24 | + ( |
| 25 | + "bc1rw5uspcuh", |
| 26 | + "Version 1+ witness address must use Bech32m checksum", # Invalid program length |
| 27 | + [], |
| 28 | + ), |
| 29 | + ( |
| 30 | + "bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", |
| 31 | + "Version 1+ witness address must use Bech32m checksum", # Invalid program length |
| 32 | + [], |
| 33 | + ), |
| 34 | + ( |
| 35 | + "BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", |
| 36 | + "Invalid Bech32 v0 address program size (16 byte), per BIP141", |
| 37 | + [], |
| 38 | + ), |
| 39 | + ( |
| 40 | + "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7", |
| 41 | + "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Mixed case |
| 42 | + [], |
| 43 | + ), |
| 44 | + ( |
| 45 | + "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3t4", |
| 46 | + "Invalid character or mixed case", # bc1, Mixed case, not in BIP 173 test vectors |
| 47 | + [40], |
| 48 | + ), |
| 49 | + ( |
| 50 | + "bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du", |
| 51 | + "Version 1+ witness address must use Bech32m checksum", # Wrong padding |
| 52 | + [], |
| 53 | + ), |
| 54 | + ( |
| 55 | + "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", |
| 56 | + "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Non-zero padding in 8-to-5 conversion |
| 57 | + [], |
| 58 | + ), |
| 59 | + ("bc1gmk9yu", "Empty Bech32 data section", []), |
| 60 | + # BIP 350 |
| 61 | + ( |
| 62 | + "tc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq5zuyut", |
| 63 | + "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # Invalid human-readable part |
| 64 | + [], |
| 65 | + ), |
| 66 | + ( |
| 67 | + "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqh2y7hd", |
| 68 | + "Version 1+ witness address must use Bech32m checksum", # Invalid checksum (Bech32 instead of Bech32m) |
| 69 | + [], |
| 70 | + ), |
| 71 | + ( |
| 72 | + "tb1z0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqglt7rf", |
| 73 | + "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Invalid checksum (Bech32 instead of Bech32m) |
| 74 | + [], |
| 75 | + ), |
| 76 | + ( |
| 77 | + "BC1S0XLXVLHEMJA6C4DQV22UAPCTQUPFHLXM9H8Z3K2E72Q4K9HCZ7VQ54WELL", |
| 78 | + "Version 1+ witness address must use Bech32m checksum", # Invalid checksum (Bech32 instead of Bech32m) |
| 79 | + [], |
| 80 | + ), |
| 81 | + ( |
| 82 | + "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kemeawh", |
| 83 | + "Version 0 witness address must use Bech32 checksum", # Invalid checksum (Bech32m instead of Bech32) |
| 84 | + [], |
| 85 | + ), |
| 86 | + ( |
| 87 | + "tb1q0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq24jc47", |
| 88 | + "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Invalid checksum (Bech32m instead of Bech32) |
| 89 | + [], |
| 90 | + ), |
| 91 | + ( |
| 92 | + "bc1p38j9r5y49hruaue7wxjce0updqjuyyx0kh56v8s25huc6995vvpql3jow4", |
| 93 | + "Invalid Base 32 character", # Invalid character in checksum |
| 94 | + [59], |
| 95 | + ), |
| 96 | + ( |
| 97 | + "BC130XLXVLHEMJA6C4DQV22UAPCTQUPFHLXM9H8Z3K2E72Q4K9HCZ7VQ7ZWS8R", |
| 98 | + "Invalid Bech32 address witness version", |
| 99 | + [], |
| 100 | + ), |
| 101 | + ("bc1pw5dgrnzv", "Invalid Bech32 address program size (1 byte)", []), |
| 102 | + ( |
| 103 | + "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v8n0nx0muaewav253zgeav", |
| 104 | + "Invalid Bech32 address program size (41 byte)", |
| 105 | + [], |
| 106 | + ), |
| 107 | + ( |
| 108 | + "BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", |
| 109 | + "Invalid Bech32 v0 address program size (16 byte), per BIP141", |
| 110 | + [], |
| 111 | + ), |
| 112 | + ( |
| 113 | + "tb1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vq47Zagq", |
| 114 | + "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Mixed case |
| 115 | + [], |
| 116 | + ), |
| 117 | + ( |
| 118 | + "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v07qwwzcrf", |
| 119 | + "Invalid padding in Bech32 data section", # zero padding of more than 4 bits |
| 120 | + [], |
| 121 | + ), |
| 122 | + ( |
| 123 | + "tb1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vpggkg4j", |
| 124 | + "Invalid or unsupported Segwit (Bech32) or Base58 encoding.", # tb1, Non-zero padding in 8-to-5 conversion |
| 125 | + [], |
| 126 | + ), |
| 127 | + ("bc1gmk9yu", "Empty Bech32 data section", []), |
| 128 | +] |
| 129 | +VALID_DATA = [ |
| 130 | + # BIP 350 |
| 131 | + ( |
| 132 | + "BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4", |
| 133 | + "0014751e76e8199196d454941c45d1b3a323f1433bd6", |
| 134 | + ), |
| 135 | + # ( |
| 136 | + # "tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7", |
| 137 | + # "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", |
| 138 | + # ), |
| 139 | + ( |
| 140 | + "bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", |
| 141 | + "00201863143c14c5166804bd19203356da136c985678cd4d27a1b8c6329604903262", |
| 142 | + ), |
| 143 | + ( |
| 144 | + "bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kt5nd6y", |
| 145 | + "5128751e76e8199196d454941c45d1b3a323f1433bd6751e76e8199196d454941c45d1b3a323f1433bd6", |
| 146 | + ), |
| 147 | + ("BC1SW50QGDZ25J", "6002751e"), |
| 148 | + ("bc1zw508d6qejxtdg4y5r3zarvaryvaxxpcs", "5210751e76e8199196d454941c45d1b3a323"), |
| 149 | + # ( |
| 150 | + # "tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy", |
| 151 | + # "0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", |
| 152 | + # ), |
| 153 | + ( |
| 154 | + "bc1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses5wp4dt", |
| 155 | + "0020000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", |
| 156 | + ), |
| 157 | + # ( |
| 158 | + # "tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0c", |
| 159 | + # "5120000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", |
| 160 | + # ), |
| 161 | + ( |
| 162 | + "bc1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvses7epu4h", |
| 163 | + "5120000000c4a5cad46221b2a187905e5266362b99d5e91c6ce24d165dab93e86433", |
| 164 | + ), |
| 165 | + ( |
| 166 | + "bc1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqzk5jj0", |
| 167 | + "512079be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", |
| 168 | + ), |
| 169 | +] |
| 170 | + |
| 171 | + |
| 172 | +class ValidateAddressMainTest(BitcoinTestFramework): |
| 173 | + def set_test_params(self): |
| 174 | + self.setup_clean_chain = True |
| 175 | + self.chain = "" # main |
| 176 | + self.num_nodes = 1 |
| 177 | + self.extra_args = [["-prune=899"]] * self.num_nodes |
| 178 | + |
| 179 | + def check_valid(self, addr, spk): |
| 180 | + info = self.nodes[0].validateaddress(addr) |
| 181 | + assert_equal(info["isvalid"], True) |
| 182 | + assert_equal(info["scriptPubKey"], spk) |
| 183 | + assert "error" not in info |
| 184 | + assert "error_locations" not in info |
| 185 | + |
| 186 | + def check_invalid(self, addr, error_str, error_locations): |
| 187 | + res = self.nodes[0].validateaddress(addr) |
| 188 | + assert_equal(res["isvalid"], False) |
| 189 | + assert_equal(res["error"], error_str) |
| 190 | + assert_equal(res["error_locations"], error_locations) |
| 191 | + |
| 192 | + def test_validateaddress(self): |
| 193 | + for (addr, error, locs) in INVALID_DATA: |
| 194 | + self.check_invalid(addr, error, locs) |
| 195 | + for (addr, spk) in VALID_DATA: |
| 196 | + self.check_valid(addr, spk) |
| 197 | + |
| 198 | + def run_test(self): |
| 199 | + self.test_validateaddress() |
| 200 | + |
| 201 | + |
| 202 | +if __name__ == "__main__": |
| 203 | + ValidateAddressMainTest().main() |
0 commit comments