Skip to content

Commit a1e3885

Browse files
MarcoFalkeknst
authored andcommitted
Merge bitcoin#19239: tests: move generate_wif_key to wallet_util.py
3a83a01 [tests] move generate_wif_key to wallet_util.py (John Newbery) b216b0b [tests] sort imports in rpc_createmultisig.py (John Newbery) e380818 Revert "[TESTS] Move base58 to own module to break circular dependency" (John Newbery) Pull request description: generate_wif_key is a wallet utility function. Move it from the EC key module to the wallet util module. This fixes the circular dependency issue in bitcoin#17977 ACKs for top commit: MarcoFalke: ACK 3a83a01 🍪 Tree-SHA512: 24985dffb75202721ccc0c6c5b52f1fa5d1ce7963bccde24389feb913cab4dad0c265274ca67892c46c8b64e6a065a0f23263a89be4fb9134dfefbdbe5c7238a
1 parent eaf31ad commit a1e3885

File tree

6 files changed

+90
-96
lines changed

6 files changed

+90
-96
lines changed

test/functional/rpc_createmultisig.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test multisig RPCs"""
6+
import binascii
7+
import decimal
8+
import itertools
9+
import json
10+
import os
611

712
from test_framework.authproxy import JSONRPCException
813
from test_framework.descriptors import descsum_create, drop_origins
14+
from test_framework.key import ECPubKey, ECKey
915
from test_framework.test_framework import BitcoinTestFramework
1016
from test_framework.util import (
1117
assert_raises_rpc_error,
1218
assert_equal,
1319
)
14-
from test_framework.key import ECPubKey, ECKey, bytes_to_wif
15-
16-
import binascii
17-
import decimal
18-
import itertools
19-
import json
20-
import os
20+
from test_framework.wallet_util import bytes_to_wif
2121

2222
class RpcCreateMultiSigTest(BitcoinTestFramework):
2323
def set_test_params(self):

test/functional/test_framework/address.py

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,64 @@
99
# This file encodes and decodes BASE58 P2PKH and P2SH addresses
1010
#
1111

12-
from .base58 import byte_to_base58
13-
from .script import hash160, CScript
12+
import unittest
13+
14+
from .script import hash160, hash256, CScript
1415
from .util import hex_str_to_bytes
1516

17+
from test_framework.util import assert_equal
18+
1619
# Note unlike in bitcoin, this address isn't bech32 since we don't (at this time) support bech32.
1720
ADDRESS_BCRT1_UNSPENDABLE = 'yVg3NBUHNEhgDceqwVUjsZHreC5PBHnUo9'
1821
ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(yVg3NBUHNEhgDceqwVUjsZHreC5PBHnUo9)#e5kt0jtk'
1922
ADDRESS_BCRT1_P2SH_OP_TRUE = '8zJctvfrzGZ5s1zQ3kagwyW1DsPYSQ4V2P'
2023

2124

25+
chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
26+
27+
28+
def byte_to_base58(b, version):
29+
result = ''
30+
str = b.hex()
31+
str = chr(version).encode('latin-1').hex() + str
32+
checksum = hash256(hex_str_to_bytes(str)).hex()
33+
str += checksum[:8]
34+
value = int('0x'+str,0)
35+
while value > 0:
36+
result = chars[value % 58] + result
37+
value //= 58
38+
while (str[:2] == '00'):
39+
result = chars[0] + result
40+
str = str[2:]
41+
return result
42+
43+
44+
def base58_to_byte(s, verify_checksum=True):
45+
if not s:
46+
return b''
47+
n = 0
48+
for c in s:
49+
n *= 58
50+
assert c in chars
51+
digit = chars.index(c)
52+
n += digit
53+
h = '%x' % n
54+
if len(h) % 2:
55+
h = '0' + h
56+
res = n.to_bytes((n.bit_length() + 7) // 8, 'big')
57+
pad = 0
58+
for c in s:
59+
if c == chars[0]:
60+
pad += 1
61+
else:
62+
break
63+
res = b'\x00' * pad + res
64+
if verify_checksum:
65+
assert_equal(hash256(res[:-4])[:4], res[-4:])
66+
67+
return res[1:-4], int(res[0])
68+
69+
2270
def keyhash_to_p2pkh(hash, main = False):
2371
assert len(hash) == 20
2472
version = 76 if main else 140
@@ -50,3 +98,22 @@ def check_script(script):
5098
if (type(script) is bytes or type(script) is CScript):
5199
return script
52100
assert False
101+
102+
103+
class TestFrameworkScript(unittest.TestCase):
104+
def test_base58encodedecode(self):
105+
def check_base58(data, version):
106+
self.assertEqual(base58_to_byte(byte_to_base58(data, version)), (data, version))
107+
108+
check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 111)
109+
check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 111)
110+
check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
111+
check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
112+
check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
113+
check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 111)
114+
check_base58(b'\x1f\x8e\xa1p*{\xd4\x94\x1b\xca\tA\xb8R\xc4\xbb\xfe\xdb.\x05', 0)
115+
check_base58(b':\x0b\x05\xf4\xd7\xf6l;\xa7\x00\x9fE50)l\x84\\\xc9\xcf', 0)
116+
check_base58(b'A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
117+
check_base58(b'\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
118+
check_base58(b'\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)
119+
check_base58(b'\0\0\0A\xc1\xea\xf1\x11\x80%Y\xba\xd6\x1b`\xd6+\x1f\x89|c\x92\x8a', 0)

test/functional/test_framework/base58.py

Lines changed: 0 additions & 70 deletions
This file was deleted.

test/functional/test_framework/key.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import unittest
1515

1616
from test_framework.crypto import secp256k1
17-
from .base58 import byte_to_base58
1817

1918
# Order of the secp256k1 curve
2019
ORDER = secp256k1.GE.ORDER
@@ -185,17 +184,6 @@ def sign_ecdsa(self, msg, low_s=True, rfc6979=False):
185184
sb = s.to_bytes((s.bit_length() + 8) // 8, 'big')
186185
return b'\x30' + bytes([4 + len(rb) + len(sb), 2, len(rb)]) + rb + bytes([2, len(sb)]) + sb
187186

188-
def bytes_to_wif(b, compressed=True):
189-
if compressed:
190-
b += b'\x01'
191-
return byte_to_base58(b, 239)
192-
193-
def generate_wif_key():
194-
# Makes a WIF privkey for imports
195-
k = ECKey()
196-
k.generate()
197-
return bytes_to_wif(k.get_bytes(), k.is_compressed)
198-
199187
def compute_xonly_pubkey(key):
200188
"""Compute an x-only (32 byte) public key from a (32 byte) private key.
201189

test/functional/test_framework/wallet_util.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,11 @@
66
from collections import namedtuple
77

88
from test_framework.address import (
9+
byte_to_base58,
910
key_to_p2pkh,
1011
script_to_p2sh,
1112
)
12-
from test_framework.key import (
13-
bytes_to_wif,
14-
ECKey,
15-
)
13+
from test_framework.key import ECKey
1614
from test_framework.script import (
1715
CScript,
1816
OP_2,
@@ -90,3 +88,14 @@ def test_address(node, address, **kwargs):
9088
raise AssertionError("key {} unexpectedly returned in getaddressinfo.".format(key))
9189
elif addr_info[key] != value:
9290
raise AssertionError("key {} value {} did not match expected value {}".format(key, addr_info[key], value))
91+
92+
def bytes_to_wif(b, compressed=True):
93+
if compressed:
94+
b += b'\x01'
95+
return byte_to_base58(b, 239)
96+
97+
def generate_wif_key():
98+
# Makes a WIF privkey for imports
99+
k = ECKey()
100+
k.generate()
101+
return bytes_to_wif(k.get_bytes(), k.is_compressed)

test/functional/test_runner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
# List of framework modules containing unit tests. Should be kept in sync with
7171
# the output of `git grep unittest.TestCase ./test/functional/test_framework`
7272
TEST_FRAMEWORK_MODULES = [
73-
"base58",
73+
"address",
7474
"crypto.bip324_cipher",
7575
"blocktools",
7676
"crypto.chacha20",

0 commit comments

Comments
 (0)