Skip to content

Commit 600cb13

Browse files
pre-commit-ci[bot]giacomocaironifametrano
authored
new release (#116)
* [pre-commit.ci] pre-commit autoupdate updates: - [github.com/asottile/pyupgrade: v3.8.0 → v3.9.0](asottile/pyupgrade@v3.8.0...v3.9.0) - [github.com/PyCQA/docformatter: v1.7.3 → v1.7.4](PyCQA/docformatter@v1.7.3...v1.7.4) - [github.com/psf/black: 23.3.0 → 23.7.0](psf/black@23.3.0...23.7.0) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Upgrade pre-commit * Update history * Update documentation * Bump version * assorted fixes * fixed * Test taproot script byte serialization * Remove some type: ignore --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Giacomo Caironi <[email protected]> Co-authored-by: fametrano <[email protected]>
1 parent dc546f0 commit 600cb13

21 files changed

+144
-52
lines changed

.pre-commit-config.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ repos:
5454
language: python
5555
types: [python]
5656
- repo: https://github.com/asottile/pyupgrade
57-
rev: v3.8.0
57+
rev: v3.9.0
5858
hooks:
5959
- id: pyupgrade
6060
args: [--py37-plus]
@@ -70,7 +70,7 @@ repos:
7070
language: python
7171
types: [python]
7272
- repo: https://github.com/PyCQA/docformatter
73-
rev: v1.7.3
73+
rev: v1.7.5
7474
hooks:
7575
- id: docformatter
7676
description: "Formats docstrings to follow PEP 257."
@@ -103,7 +103,7 @@ repos:
103103
language: python
104104
types: [python]
105105
- repo: https://github.com/psf/black
106-
rev: 23.3.0
106+
rev: 23.7.0
107107
hooks:
108108
- id: black
109109
name: black (in place fixes)

HISTORY.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,18 @@ Notable changes to the codebase are documented here.
55
Release names follow *[calendar versioning](https://calver.org/)*:
66
full year, short month, short day (YYYY-M-D)
77

8-
## v2023.6 (work in progress, not released yet)
8+
## v2023.7.12
9+
10+
This is the last release supporting py37.
911

1012
Major changes include:
1113

12-
- add descriptor util functions
14+
- added first draft implementation of descriptors
15+
- added first draft implementation of script engine
16+
- added taproot psbt fields
17+
- improved bip32 derivation (speeded-up, added one more test)
18+
- supported py3.12 with btclib_libsecp256k1
19+
- updated toolchain
1320

1421
## v2023.5.30
1522

btclib/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"""__init__ module for the btclib package."""
1111

1212
name = "btclib"
13-
__version__ = "2023.5.30"
13+
__version__ = "2023.7.12"
1414
__author__ = "The btclib developers"
1515
__author_email__ = "[email protected]"
1616
__copyright__ = "Copyright (C) 2017-2023 The btclib developers"

btclib/block/block.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def height(self) -> int | None:
5353
script_sig.
5454
5555
https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki
56-
Block 227,835 (2013-03-24 15
56+
Block 227,835 (2013-03-24 15
5757
:49: 13 GMT) was the last version 1 block.
5858
"""
5959
if not self.transactions[0].is_coinbase():

btclib/ec/curve_group.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -703,9 +703,9 @@ def _multi_mult(
703703
704704
Use Bos-Coster's algorithm for efficient computation.
705705
706-
The input points are assumed to be on curve,
707-
the scalar coefficients are assumed to have been reduced mod n
708-
if appropriate (e.g. cyclic groups of order n).
706+
The input points are assumed to be on curve, the scalar coefficients
707+
are assumed to have been reduced mod n if appropriate (e.g. cyclic
708+
groups of order n).
709709
"""
710710
# source: https://cr.yp.to/badbatch/boscoster2.py
711711
if len(scalars) != len(jac_points):

btclib/psbt/psbt.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -189,13 +189,16 @@ def to_dict(self, check_validity: bool = True) -> dict[str, Any]:
189189
def from_dict(
190190
cls: type[Psbt], dict_: Mapping[str, Any], check_validity: bool = True
191191
) -> Psbt:
192+
hd_key_paths = cast(
193+
Mapping[Octets, BIP32KeyOrigin],
194+
decode_from_bip32_derivs(dict_["bip32_derivs"]),
195+
)
192196
return cls(
193197
Tx.from_dict(dict_["tx"]),
194198
[PsbtIn.from_dict(psbt_in, False) for psbt_in in dict_["inputs"]],
195199
[PsbtOut.from_dict(psbt_out, False) for psbt_out in dict_["outputs"]],
196200
dict_["version"],
197-
# FIXME
198-
decode_from_bip32_derivs(dict_["bip32_derivs"]), # type: ignore[arg-type]
201+
hd_key_paths,
199202
dict_["unknown"],
200203
check_validity,
201204
)
@@ -483,7 +486,7 @@ def _sort_or_shuffle_together(
483486
if ordering_func is None:
484487
random.shuffle(tmp)
485488
else:
486-
tmp.sort(key=lambda t: ordering_func(t[0])) # type: ignore
489+
tmp.sort(key=lambda t: ordering_func(t[0])) # type: ignore[misc]
487490
tuple_a, tuple_b = zip(*tmp)
488491
return list(tuple_a), list(tuple_b)
489492

btclib/psbt/psbt_in.py

+15-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
# Standard library imports
1717
from dataclasses import dataclass
18-
from typing import Any, Mapping
18+
from typing import Any, List, Mapping, Tuple, cast
1919

2020
from btclib.alias import Octets
2121
from btclib.bip32.key_origin import (
@@ -54,7 +54,6 @@
5454
serialize_hd_key_paths,
5555
serialize_leaf_scripts,
5656
serialize_taproot_bip32,
57-
taproot_bip32_from_dict,
5857
taproot_bip32_to_dict,
5958
)
6059
from btclib.script import Witness
@@ -319,6 +318,14 @@ def to_dict(self, check_validity: bool = True) -> dict[str, Any]:
319318
def from_dict(
320319
cls: type[PsbtIn], dict_: Mapping[str, Any], check_validity: bool = True
321320
) -> PsbtIn:
321+
hd_key_paths = cast(
322+
Mapping[Octets, BIP32KeyOrigin],
323+
decode_from_bip32_derivs(dict_["bip32_derivs"]),
324+
)
325+
taproot_hd_key_paths = cast(
326+
Mapping[Octets, Tuple[List[Octets], BIP32KeyOrigin]],
327+
decode_from_bip32_derivs(dict_["taproot_hd_key_paths"]),
328+
)
322329
return cls(
323330
Tx.from_dict(dict_["non_witness_utxo"], False)
324331
if dict_["non_witness_utxo"]
@@ -330,8 +337,7 @@ def from_dict(
330337
dict_["sig_hash"],
331338
dict_["redeem_script"],
332339
dict_["witness_script"],
333-
# FIXME
334-
decode_from_bip32_derivs(dict_["bip32_derivs"]), # type: ignore
340+
hd_key_paths,
335341
dict_["final_script_sig"],
336342
Witness.from_dict(dict_["final_script_witness"], False),
337343
dict_["ripemd160_preimages"],
@@ -341,7 +347,7 @@ def from_dict(
341347
dict_["taproot_key_spend_signature"],
342348
dict_["taproot_script_spend_signatures"],
343349
dict_["taproot_leaf_scripts"],
344-
taproot_bip32_from_dict(dict_["taproot_hd_key_paths"]), # type: ignore
350+
taproot_hd_key_paths,
345351
dict_["taproot_internal_key"],
346352
dict_["taproot_merkle_root"],
347353
dict_["unknown"],
@@ -526,7 +532,10 @@ def parse(
526532
elif k[:1] == PSBT_IN_TAP_LEAF_SCRIPT:
527533
taproot_leaf_scripts[k[1:]] = parse_leaf_script(v)
528534
elif k[:1] == PSBT_IN_TAP_BIP32_DERIVATION:
529-
taproot_hd_key_paths[k[1:]] = parse_taproot_bip32(v) # type: ignore
535+
taproot_hd_key_path = cast(
536+
Tuple[List[Octets], BIP32KeyOrigin], parse_taproot_bip32(v)
537+
)
538+
taproot_hd_key_paths[k[1:]] = taproot_hd_key_path
530539
elif k[:1] == PSBT_IN_TAP_INTERNAL_KEY:
531540
taproot_internal_key = deserialize_bytes(k, v, "taproot internal key")
532541
elif k[:1] == PSBT_IN_TAP_MERKLE_ROOT:

btclib/psbt/psbt_out.py

+14-8
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from __future__ import annotations
1616

1717
from dataclasses import dataclass
18-
from typing import Any, Mapping, Sequence
18+
from typing import Any, List, Mapping, Sequence, Tuple, cast
1919

2020
from btclib.alias import Octets
2121
from btclib.bip32 import (
@@ -126,15 +126,21 @@ def to_dict(self, check_validity: bool = True) -> dict[str, Any]:
126126
def from_dict(
127127
cls: type[PsbtOut], dict_: Mapping[str, Any], check_validity: bool = True
128128
) -> PsbtOut:
129+
hd_key_paths = cast(
130+
Mapping[Octets, BIP32KeyOrigin],
131+
decode_from_bip32_derivs(dict_["bip32_derivs"]),
132+
)
133+
taproot_hd_key_paths = cast(
134+
Mapping[Octets, Tuple[List[bytes], BIP32KeyOrigin]],
135+
taproot_bip32_from_dict(dict_["taproot_hd_key_paths"]),
136+
)
129137
return cls(
130138
dict_["redeem_script"],
131139
dict_["witness_script"],
132-
# FIXME
133-
decode_from_bip32_derivs(dict_["bip32_derivs"]), # type: ignore
140+
hd_key_paths,
134141
dict_["taproot_internal_key"],
135142
dict_["taproot_tree"],
136-
# FIXME
137-
taproot_bip32_from_dict(dict_["taproot_hd_key_paths"]), # type: ignore
143+
taproot_hd_key_paths,
138144
dict_["unknown"],
139145
check_validity,
140146
)
@@ -195,7 +201,7 @@ def parse(
195201
hd_key_paths: dict[Octets, BIP32KeyOrigin] = {}
196202
taproot_internal_key = b""
197203
taproot_tree: list[tuple[int, int, bytes]] = []
198-
taproot_hd_key_paths: dict[Octets, tuple[list[Octets], BIP32KeyOrigin]] = {}
204+
taproot_hd_key_paths: dict[Octets, tuple[list[bytes], BIP32KeyOrigin]] = {}
199205
unknown: dict[Octets, Octets] = {}
200206

201207
for k, v in output_map.items():
@@ -212,7 +218,7 @@ def parse(
212218
taproot_tree = parse_taproot_tree(v)
213219
elif k[:1] == PSBT_OUT_TAP_BIP32_DERIVATION:
214220
#  parse just one hd key path at time :-(
215-
taproot_hd_key_paths[k[1:]] = parse_taproot_bip32(v) # type: ignore
221+
taproot_hd_key_paths[k[1:]] = parse_taproot_bip32(v)
216222
else: # unknown
217223
unknown[k] = v
218224

@@ -222,7 +228,7 @@ def parse(
222228
hd_key_paths,
223229
taproot_internal_key,
224230
taproot_tree,
225-
taproot_hd_key_paths, # type: ignore
231+
taproot_hd_key_paths,
226232
unknown,
227233
check_validity,
228234
)

btclib/script/engine/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
from __future__ import annotations
1313

14-
from typing import cast
15-
1614
from btclib.alias import Command, ScriptList
1715
from btclib.exceptions import BTClibValueError
1816
from btclib.hashes import sha256

btclib/script/engine/script.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
try:
1717
from btclib_libsecp256k1.dsa import verify as dsa_verify
1818
except ImportError:
19-
from btclib.ecc.dsa import verify_ as dsa_verify # type: ignore
19+
from btclib.ecc.dsa import verify_ as dsa_verify # type: ignore[assignment]
2020

2121
from btclib.alias import ScriptList
2222
from btclib.ecc.dsa import Sig
@@ -125,7 +125,7 @@ def op_checksig(
125125
msg_hash = sig_hash.segwit_v0(script_code, tx, i, signature[-1], prevout_value)
126126
else:
127127
msg_hash = sig_hash.legacy(script_code, tx, i, signature[-1])
128-
return dsa_verify(msg_hash, pub_key, signature[:-1]) # type: ignore
128+
return bool(dsa_verify(msg_hash, pub_key, signature[:-1]))
129129

130130

131131
def script_op_count(count: int, increment: int):

btclib/script/engine/tapscript.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def verify_key_path(
6464
pub_key = type_and_payload(script_pub_key)[1]
6565
msg_hash = sig_hash.taproot(tx, i, prevouts, sighash_type, 0, annex, b"")
6666

67-
if not ssa_verify(msg_hash, pub_key, signature[:64]): # type: ignore
67+
if not ssa_verify(msg_hash, pub_key, signature[:64]):
6868
raise BTClibValueError()
6969

7070

@@ -93,7 +93,7 @@ def op_checksig(
9393
tapleaf_hash = tagged_hash(b"TapLeaf", preimage)
9494
ext = tapleaf_hash + b"\x00" + codesep_pos.to_bytes(4, "little")
9595
msg_hash = sig_hash.taproot(tx, i, prevouts, sighash_type, 1, annex, ext)
96-
if not ssa_verify(msg_hash, pub_key, signature[:64]): # type: ignore
96+
if not ssa_verify(msg_hash, pub_key, signature[:64]):
9797
raise BTClibValueError()
9898
stack.append(_from_num(int(bool(signature))))
9999
return budget

docs/source/btclib.script.engine.rst

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
btclib.script.engine package
2+
============================
3+
4+
Submodules
5+
----------
6+
7+
btclib.script.engine.script module
8+
----------------------------------
9+
10+
.. automodule:: btclib.script.engine.script
11+
:members:
12+
:undoc-members:
13+
:show-inheritance:
14+
15+
btclib.script.engine.script\_op\_codes module
16+
---------------------------------------------
17+
18+
.. automodule:: btclib.script.engine.script_op_codes
19+
:members:
20+
:undoc-members:
21+
:show-inheritance:
22+
23+
btclib.script.engine.tapscript module
24+
-------------------------------------
25+
26+
.. automodule:: btclib.script.engine.tapscript
27+
:members:
28+
:undoc-members:
29+
:show-inheritance:
30+
31+
Module contents
32+
---------------
33+
34+
.. automodule:: btclib.script.engine
35+
:members:
36+
:undoc-members:
37+
:show-inheritance:

docs/source/btclib.script.rst

+16
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
11
btclib.script package
22
=====================
33

4+
Subpackages
5+
-----------
6+
7+
.. toctree::
8+
:maxdepth: 4
9+
10+
btclib.script.engine
11+
412
Submodules
513
----------
614

15+
btclib.script.op\_codes\_tapscript module
16+
-----------------------------------------
17+
18+
.. automodule:: btclib.script.op_codes_tapscript
19+
:members:
20+
:undoc-members:
21+
:show-inheritance:
22+
723
btclib.script.script module
824
---------------------------
925

docs/source/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
project = "btclib"
2121
project_copyright = "2017-2023 The btclib developers"
2222
author = "The btclib developers"
23-
release = "2023.5.30"
23+
release = "2023.7.12"
2424

2525
# -- General configuration ---------------------------------------------------
2626
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# or distributed except according to the terms contained in the LICENSE file.
1010
"""Build script for setuptools."""
1111

12-
from setuptools import find_packages, setup # type: ignore
12+
from setuptools import find_namespace_packages, setup # type: ignore[import]
1313

1414
import btclib
1515

@@ -34,7 +34,7 @@
3434
description="A library for 'bitcoin cryptography'",
3535
long_description=longdescription,
3636
long_description_content_type="text/markdown",
37-
packages=find_packages(exclude=["tests", "tests.*"]),
37+
packages=find_namespace_packages(exclude=["tests", "tests.*"]),
3838
include_package_data=True,
3939
# test_suite="btclib.tests",
4040
install_requires=["btclib_libsecp256k1"],

tests/ecc/test_rfc6979.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from os import path
1515

1616
from btclib.ec import mult
17-
from btclib.ec.curve import CURVES
17+
from btclib.ec.curve import CURVES, Curve
1818
from btclib.ecc import dsa
1919
from btclib.ecc.rfc6979_nonce import rfc6979_nonce_
2020
from btclib.hashes import reduce_to_hlen
@@ -31,7 +31,9 @@ def test_rfc6979() -> None:
3131

3232

3333
def test_rfc6979_nonce_example() -> None:
34-
class _helper: # pylint: disable=too-few-public-methods
34+
class _helper(
35+
Curve
36+
): # pylint: disable=too-few-public-methods, super-init-not-called
3537
def __init__(self, n: int) -> None:
3638
self.n = n
3739
self.nlen = n.bit_length()
@@ -43,7 +45,7 @@ def __init__(self, n: int) -> None:
4345
msg = b"sample"
4446
msg_hash = hashlib.sha256(msg).digest()
4547
k = 0x23AF4074C90A02B3FE61D286D5C87F425E6BDD81B
46-
assert k == rfc6979_nonce_(msg_hash, x, fake_ec) # type: ignore[arg-type]
48+
assert k == rfc6979_nonce_(msg_hash, x, fake_ec)
4749

4850

4951
def test_rfc6979_nonce_tv() -> None:

0 commit comments

Comments
 (0)