Skip to content

Commit 40aab35

Browse files
author
MarcoFalke
committed
Merge #19253: Tests: tidy up address.py and segwit_addr.py
825fcae [tests] Replace bytes literals with hex literals (John Newbery) 64eca45 [tests] Fix pep8 style violations in address.py (John Newbery) b230f8b [tests] Correct docstring for address.py (John Newbery) ea70e6a [tests] Tidy up imports in address.py (John Newbery) 7f639df [tests] Remove unused optional verify_checksum parameter (John Newbery) 011e784 [tests] Rename segwit encode and decode functions (John Newbery) e455713 [tests] Move bech32 unit tests to test framework (John Newbery) Pull request description: Lots of small fixes: - moving unit tests to test_framework implementation files - renaming functions to be clearer - removing multiple imports - removing unreadable byte literals from the code - fixing pep8 violations - correcting out-of-date docstring ACKs for top commit: jonatack: re-ACK 825fcae per `git range-diff a0a422c 7edcdcd 825fcae` and verified `wallet_address_types.py` and `wallet_basic.py --descriptors` (the failure on one travis job) are green locally. MarcoFalke: ACK 825fcae fanquake: ACK 825fcae - looks ok to me. Tree-SHA512: aea509c27c1bcb94bef11205b6a79836c39c62249672815efc9822f411bc2e2336ceb3d72b3b861c3f4054a08e16edb28c6edd3aa5eff72eec1d60ea6ca82dc4
2 parents 3487e42 + 825fcae commit 40aab35

File tree

4 files changed

+57
-51
lines changed

4 files changed

+57
-51
lines changed

test/functional/test_framework/address.py

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
# Copyright (c) 2016-2020 The Bitcoin Core developers
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5-
"""Encode and decode BASE58, P2PKH and P2SH addresses."""
5+
"""Encode and decode Bitcoin addresses.
6+
7+
- base58 P2PKH and P2SH addresses.
8+
- bech32 segwit v0 P2WPKH and P2WSH addresses."""
69

710
import enum
811
import unittest
912

1013
from .script import hash256, hash160, sha256, CScript, OP_0
11-
from .util import hex_str_to_bytes
12-
13-
from . import segwit_addr
14-
15-
from test_framework.util import assert_equal
14+
from .segwit_addr import encode_segwit_address
15+
from .util import assert_equal, hex_str_to_bytes
1616

1717
ADDRESS_BCRT1_UNSPENDABLE = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj'
1818
ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj)#juyq9d97'
@@ -35,7 +35,7 @@ def byte_to_base58(b, version):
3535
str = chr(version).encode('latin-1').hex() + str
3636
checksum = hash256(hex_str_to_bytes(str)).hex()
3737
str += checksum[:8]
38-
value = int('0x'+str,0)
38+
value = int('0x' + str, 0)
3939
while value > 0:
4040
result = chars[value % 58] + result
4141
value //= 58
@@ -45,7 +45,10 @@ def byte_to_base58(b, version):
4545
return result
4646

4747

48-
def base58_to_byte(s, verify_checksum=True):
48+
def base58_to_byte(s):
49+
"""Converts a base58-encoded string to its data and version.
50+
51+
Throws if the base58 checksum is invalid."""
4952
if not s:
5053
return b''
5154
n = 0
@@ -65,66 +68,67 @@ def base58_to_byte(s, verify_checksum=True):
6568
else:
6669
break
6770
res = b'\x00' * pad + res
68-
if verify_checksum:
69-
assert_equal(hash256(res[:-4])[:4], res[-4:])
71+
72+
# Assert if the checksum is invalid
73+
assert_equal(hash256(res[:-4])[:4], res[-4:])
7074

7175
return res[1:-4], int(res[0])
7276

7377

74-
def keyhash_to_p2pkh(hash, main = False):
78+
def keyhash_to_p2pkh(hash, main=False):
7579
assert len(hash) == 20
7680
version = 0 if main else 111
7781
return byte_to_base58(hash, version)
7882

79-
def scripthash_to_p2sh(hash, main = False):
83+
def scripthash_to_p2sh(hash, main=False):
8084
assert len(hash) == 20
8185
version = 5 if main else 196
8286
return byte_to_base58(hash, version)
8387

84-
def key_to_p2pkh(key, main = False):
88+
def key_to_p2pkh(key, main=False):
8589
key = check_key(key)
8690
return keyhash_to_p2pkh(hash160(key), main)
8791

88-
def script_to_p2sh(script, main = False):
92+
def script_to_p2sh(script, main=False):
8993
script = check_script(script)
9094
return scripthash_to_p2sh(hash160(script), main)
9195

92-
def key_to_p2sh_p2wpkh(key, main = False):
96+
def key_to_p2sh_p2wpkh(key, main=False):
9397
key = check_key(key)
9498
p2shscript = CScript([OP_0, hash160(key)])
9599
return script_to_p2sh(p2shscript, main)
96100

97-
def program_to_witness(version, program, main = False):
101+
def program_to_witness(version, program, main=False):
98102
if (type(program) is str):
99103
program = hex_str_to_bytes(program)
100104
assert 0 <= version <= 16
101105
assert 2 <= len(program) <= 40
102106
assert version > 0 or len(program) in [20, 32]
103-
return segwit_addr.encode("bc" if main else "bcrt", version, program)
107+
return encode_segwit_address("bc" if main else "bcrt", version, program)
104108

105-
def script_to_p2wsh(script, main = False):
109+
def script_to_p2wsh(script, main=False):
106110
script = check_script(script)
107111
return program_to_witness(0, sha256(script), main)
108112

109-
def key_to_p2wpkh(key, main = False):
113+
def key_to_p2wpkh(key, main=False):
110114
key = check_key(key)
111115
return program_to_witness(0, hash160(key), main)
112116

113-
def script_to_p2sh_p2wsh(script, main = False):
117+
def script_to_p2sh_p2wsh(script, main=False):
114118
script = check_script(script)
115119
p2shscript = CScript([OP_0, sha256(script)])
116120
return script_to_p2sh(p2shscript, main)
117121

118122
def check_key(key):
119123
if (type(key) is str):
120-
key = hex_str_to_bytes(key) # Assuming this is hex string
124+
key = hex_str_to_bytes(key) # Assuming this is hex string
121125
if (type(key) is bytes and (len(key) == 33 or len(key) == 65)):
122126
return key
123127
assert False
124128

125129
def check_script(script):
126130
if (type(script) is str):
127-
script = hex_str_to_bytes(script) # Assuming this is hex string
131+
script = hex_str_to_bytes(script) # Assuming this is hex string
128132
if (type(script) is bytes or type(script) is CScript):
129133
return script
130134
assert False
@@ -135,15 +139,15 @@ def test_base58encodedecode(self):
135139
def check_base58(data, version):
136140
self.assertEqual(base58_to_byte(byte_to_base58(data, version)), (data, version))
137141

138-
check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 111)
139-
check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 111)
140-
check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
141-
check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
142-
check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
143-
check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
144-
check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 0)
145-
check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 0)
146-
check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
147-
check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
148-
check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
149-
check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
142+
check_base58(bytes.fromhex('1f8ea1702a7bd4941bca0941b852c4bbfedb2e05'), 111)
143+
check_base58(bytes.fromhex('3a0b05f4d7f66c3ba7009f453530296c845cc9cf'), 111)
144+
check_base58(bytes.fromhex('41c1eaf111802559bad61b60d62b1f897c63928a'), 111)
145+
check_base58(bytes.fromhex('0041c1eaf111802559bad61b60d62b1f897c63928a'), 111)
146+
check_base58(bytes.fromhex('000041c1eaf111802559bad61b60d62b1f897c63928a'), 111)
147+
check_base58(bytes.fromhex('00000041c1eaf111802559bad61b60d62b1f897c63928a'), 111)
148+
check_base58(bytes.fromhex('1f8ea1702a7bd4941bca0941b852c4bbfedb2e05'), 0)
149+
check_base58(bytes.fromhex('3a0b05f4d7f66c3ba7009f453530296c845cc9cf'), 0)
150+
check_base58(bytes.fromhex('41c1eaf111802559bad61b60d62b1f897c63928a'), 0)
151+
check_base58(bytes.fromhex('0041c1eaf111802559bad61b60d62b1f897c63928a'), 0)
152+
check_base58(bytes.fromhex('000041c1eaf111802559bad61b60d62b1f897c63928a'), 0)
153+
check_base58(bytes.fromhex('00000041c1eaf111802559bad61b60d62b1f897c63928a'), 0)

test/functional/test_framework/segwit_addr.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Reference implementation for Bech32 and segwit addresses."""
6-
6+
import unittest
77

88
CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
99

@@ -84,7 +84,7 @@ def convertbits(data, frombits, tobits, pad=True):
8484
return ret
8585

8686

87-
def decode(hrp, addr):
87+
def decode_segwit_address(hrp, addr):
8888
"""Decode a segwit address."""
8989
hrpgot, data = bech32_decode(addr)
9090
if hrpgot != hrp:
@@ -99,9 +99,23 @@ def decode(hrp, addr):
9999
return (data[0], decoded)
100100

101101

102-
def encode(hrp, witver, witprog):
102+
def encode_segwit_address(hrp, witver, witprog):
103103
"""Encode a segwit address."""
104104
ret = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5))
105-
if decode(hrp, ret) == (None, None):
105+
if decode_segwit_address(hrp, ret) == (None, None):
106106
return None
107107
return ret
108+
109+
class TestFrameworkScript(unittest.TestCase):
110+
def test_segwit_encode_decode(self):
111+
def test_python_bech32(addr):
112+
hrp = addr[:4]
113+
self.assertEqual(hrp, "bcrt")
114+
(witver, witprog) = decode_segwit_address(hrp, addr)
115+
self.assertEqual(encode_segwit_address(hrp, witver, witprog), addr)
116+
117+
# P2WPKH
118+
test_python_bech32('bcrt1qthmht0k2qnh3wy7336z05lu2km7emzfpm3wg46')
119+
# P2WSH
120+
test_python_bech32('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj')
121+
test_python_bech32('bcrt1qft5p2uhsdcdc3l2ua4ap5qqfg4pjaqlp250x7us7a8qqhrxrxfsqseac85')

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"blocktools",
7272
"muhash",
7373
"script",
74+
"segwit_addr",
7475
"util",
7576
]
7677

test/functional/wallet_address_types.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@
6464
assert_raises_rpc_error,
6565
connect_nodes,
6666
)
67-
from test_framework.segwit_addr import (
68-
encode,
69-
decode,
70-
)
7167

7268
class AddressTypeTest(BitcoinTestFramework):
7369
def set_test_params(self):
@@ -101,13 +97,6 @@ def get_balances(self, key='trusted'):
10197
"""Return a list of balances."""
10298
return [self.nodes[i].getbalances()['mine'][key] for i in range(4)]
10399

104-
# Quick test of python bech32 implementation
105-
def test_python_bech32(self, addr):
106-
hrp = addr[:4]
107-
assert_equal(hrp, "bcrt")
108-
(witver, witprog) = decode(hrp, addr)
109-
assert_equal(encode(hrp, witver, witprog), addr)
110-
111100
def test_address(self, node, address, multisig, typ):
112101
"""Run sanity checks on an address."""
113102
info = self.nodes[node].getaddressinfo(address)
@@ -132,7 +121,6 @@ def test_address(self, node, address, multisig, typ):
132121
assert_equal(info['witness_version'], 0)
133122
assert_equal(len(info['witness_program']), 40)
134123
assert 'pubkey' in info
135-
self.test_python_bech32(info["address"])
136124
elif typ == 'legacy':
137125
# P2SH-multisig
138126
assert info['isscript']
@@ -158,7 +146,6 @@ def test_address(self, node, address, multisig, typ):
158146
assert_equal(info['witness_version'], 0)
159147
assert_equal(len(info['witness_program']), 64)
160148
assert 'pubkeys' in info
161-
self.test_python_bech32(info["address"])
162149
else:
163150
# Unknown type
164151
assert False

0 commit comments

Comments
 (0)