mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-25 07:48:10 +00:00
fix(python): drop simple-rlp dependency and use internal copy
This commit is contained in:
parent
df42c99bc9
commit
9b78dd107b
11
poetry.lock
generated
11
poetry.lock
generated
@ -1429,16 +1429,6 @@ colorama = "*"
|
||||
dev = ["black", "flake8", "isort"]
|
||||
tests = ["pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "simple-rlp"
|
||||
version = "0.1.2"
|
||||
description = "RLP (Recursive Length Prefix) - Encode and decode data structures"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "simple-rlp-0.1.2.tar.gz", hash = "sha256:5c4a9c58f1b742f7fa8af0fe4ea6ff9fb02294ae041912f771570dfaf339d2b9"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
@ -1580,7 +1570,6 @@ ecdsa = ">=0.9"
|
||||
libusb1 = ">=1.6.4"
|
||||
mnemonic = ">=0.20"
|
||||
requests = ">=2.4.0"
|
||||
simple-rlp = {version = ">=0.1.2", markers = "python_version >= \"3.7\""}
|
||||
typing_extensions = ">=3.10"
|
||||
|
||||
[package.extras]
|
||||
|
@ -55,7 +55,6 @@ ed25519 = "^1.4"
|
||||
requests = "^2.31"
|
||||
termcolor = "*"
|
||||
Pillow = "^9"
|
||||
simple-rlp = "^0.1.2"
|
||||
|
||||
# crypto
|
||||
ecdsa = "^0.16"
|
||||
|
1
python/.changelog.d/3045.fixed
Normal file
1
python/.changelog.d/3045.fixed
Normal file
@ -0,0 +1 @@
|
||||
Drop simple-rlp dependency and use internal copy
|
@ -6,5 +6,4 @@ libusb1>=1.6.4
|
||||
construct>=2.9,!=2.10.55
|
||||
typing_extensions>=3.10
|
||||
dataclasses ; python_version<'3.7'
|
||||
simple-rlp>=0.1.2 ; python_version>='3.7'
|
||||
construct-classes>=0.1.2
|
||||
|
@ -25,7 +25,7 @@ per-file-ignores =
|
||||
helper-scripts/*:I
|
||||
tools/*:I
|
||||
tests/*:I
|
||||
known-modules = libusb1:[usb1],hidapi:[hid],PyQt5:[PyQt5.QtWidgets,PyQt5.QtGui,PyQt5.QtCore],simple-rlp:[rlp]
|
||||
known-modules = libusb1:[usb1],hidapi:[hid],PyQt5:[PyQt5.QtWidgets,PyQt5.QtGui,PyQt5.QtCore]
|
||||
|
||||
[isort]
|
||||
profile = black
|
||||
|
55
python/src/trezorlib/_rlp.py
Normal file
55
python/src/trezorlib/_rlp.py
Normal file
@ -0,0 +1,55 @@
|
||||
# inspired by core/src/trezor/crypto/rlp.py
|
||||
|
||||
import typing as t
|
||||
from collections.abc import Sequence
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
RLPItem = t.Union[t.Sequence["RLPItem"], bytes, int]
|
||||
|
||||
|
||||
def _byte_size(x: int) -> int:
|
||||
if x < 0:
|
||||
raise ValueError("only unsigned ints are supported")
|
||||
return (x.bit_length() + 7) // 8
|
||||
|
||||
|
||||
def _int_to_bytes(n: int) -> bytes:
|
||||
"""Convert to a correctly sized bytes object."""
|
||||
return n.to_bytes(_byte_size(n), "big")
|
||||
|
||||
|
||||
def _encode_with_length(value: bytes, header_byte: int) -> bytes:
|
||||
length = len(value)
|
||||
if length == 1 and value[0] <= 0x7F:
|
||||
return value
|
||||
elif length <= 55:
|
||||
return (header_byte + length).to_bytes(1, "big") + value
|
||||
else:
|
||||
encoded_length = _int_to_bytes(length)
|
||||
return (
|
||||
(header_byte + 55 + len(encoded_length)).to_bytes(1, "big")
|
||||
+ encoded_length
|
||||
+ value
|
||||
)
|
||||
|
||||
|
||||
def encode(value: "RLPItem") -> bytes:
|
||||
"""Encode lists or objects to bytes."""
|
||||
if isinstance(value, int):
|
||||
# ints are stored as byte strings
|
||||
value = _int_to_bytes(value)
|
||||
|
||||
# sanity check: `str` is a Sequence so it would be incorrectly
|
||||
# picked up by the Sequence branch below
|
||||
assert not isinstance(value, str)
|
||||
|
||||
# check for bytes type first, because bytes is a Sequence too
|
||||
if isinstance(value, bytes):
|
||||
header_byte = 0x80
|
||||
elif isinstance(value, Sequence):
|
||||
header_byte = 0xC0
|
||||
value = b"".join(encode(item) for item in value)
|
||||
else:
|
||||
raise TypeError("Unsupported type")
|
||||
|
||||
return _encode_with_length(value, header_byte)
|
@ -20,21 +20,11 @@ import sys
|
||||
import tarfile
|
||||
from decimal import Decimal
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Dict,
|
||||
List,
|
||||
NoReturn,
|
||||
Optional,
|
||||
Sequence,
|
||||
TextIO,
|
||||
Tuple,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, NoReturn, Optional, TextIO
|
||||
|
||||
import click
|
||||
|
||||
from .. import definitions, ethereum, tools
|
||||
from .. import _rlp, definitions, ethereum, tools
|
||||
from ..messages import EthereumDefinitions
|
||||
from . import with_client
|
||||
|
||||
@ -162,7 +152,7 @@ def _erc20_contract(token_address: str, to_address: str, amount: int) -> str:
|
||||
|
||||
def _format_access_list(
|
||||
access_list: List[ethereum.messages.EthereumAccessList],
|
||||
) -> List[Tuple[bytes, Sequence[bytes]]]:
|
||||
) -> "_rlp.RLPItem":
|
||||
return [
|
||||
(ethereum.decode_hex(item.address), item.storage_keys) for item in access_list
|
||||
]
|
||||
@ -386,11 +376,6 @@ def sign_tx(
|
||||
try to connect to an ethereum node and auto-fill these values. You can configure
|
||||
the connection with WEB3_PROVIDER_URI environment variable.
|
||||
"""
|
||||
try:
|
||||
import rlp
|
||||
except ImportError:
|
||||
_print_eth_dependencies_and_die()
|
||||
|
||||
is_eip1559 = eip2718_type == 2
|
||||
if (
|
||||
(not is_eip1559 and gas_price is None)
|
||||
@ -490,8 +475,6 @@ def sign_tx(
|
||||
|
||||
to = ethereum.decode_hex(to_address)
|
||||
|
||||
# NOTE: rlp.encode needs a list input to iterate through all its items,
|
||||
# it does not work with a tuple
|
||||
if is_eip1559:
|
||||
transaction_items = [
|
||||
chain_id,
|
||||
@ -518,7 +501,7 @@ def sign_tx(
|
||||
data_bytes,
|
||||
*sig,
|
||||
]
|
||||
transaction = rlp.encode(transaction_items)
|
||||
transaction = _rlp.encode(transaction_items)
|
||||
|
||||
if eip2718_type is not None:
|
||||
eip2718_prefix = f"{eip2718_type:02x}"
|
||||
|
33
python/tests/test_rlp.py
Normal file
33
python/tests/test_rlp.py
Normal file
@ -0,0 +1,33 @@
|
||||
import pytest
|
||||
|
||||
from trezorlib import _rlp
|
||||
|
||||
VECTORS = ( # data, expected
|
||||
(b"\x10", b"\x10"),
|
||||
(b"dog", b"\x83dog"),
|
||||
(b"A" * 55, b"\xb7" + b"A" * 55),
|
||||
(b"A" * 56, b"\xb8\x38" + b"A" * 56),
|
||||
(b"A" * 1024, b"\xb9\x04\x00" + b"A" * 1024),
|
||||
([b"dog", b"cat", [b"spy"]], b"\xcd\x83dog\x83cat\xc4\x83spy"),
|
||||
([b"A" * 1024], b"\xf9\x04\x03\xb9\x04\x00" + b"A" * 1024),
|
||||
([], b"\xc0"),
|
||||
([b"A"] * 55, b"\xf7" + b"A" * 55),
|
||||
([b"A"] * 56, b"\xf8\x38" + b"A" * 56),
|
||||
([b"A"] * 1024, b"\xf9\x04\x00" + b"A" * 1024),
|
||||
([b"dog"] * 1024, b"\xf9\x10\x00" + b"\x83dog" * 1024),
|
||||
(b"", b"\x80"),
|
||||
(1, b"\x01"),
|
||||
(0x7F, b"\x7f"),
|
||||
(0x80, b"\x81\x80"),
|
||||
(0x1_0000_0001, b"\x85\x01\x00\x00\x00\x01"),
|
||||
(2 ** (54 * 8), b"\xb7\x01" + b"\x00" * 54),
|
||||
(2 ** (55 * 8), b"\xb8\x38\x01" + b"\x00" * 55),
|
||||
([0x1234, 0x5678], b"\xc6\x82\x12\x34\x82\x56\x78"),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data, expected", VECTORS)
|
||||
def test_encode(data: "_rlp.RLPItem", expected: bytes):
|
||||
actual = _rlp.encode(data)
|
||||
assert len(actual) == len(expected)
|
||||
assert actual == expected
|
Loading…
Reference in New Issue
Block a user