Skip to content

Commit

Permalink
Avoid type conversions when parsing transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
Cryp Toon committed Mar 18, 2024
1 parent 6c75717 commit 85e316e
Showing 1 changed file with 14 additions and 7 deletions.
21 changes: 14 additions & 7 deletions bitcoinlib/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -888,24 +888,31 @@ def parse(cls, rawtx, strict=True, network=DEFAULT_NETWORK):
:return Transaction:
"""
raw_bytes = b''
if isinstance(rawtx, bytes):
raw_bytes = rawtx
rawtx = BytesIO(rawtx)
elif isinstance(rawtx, str):
raw_bytes = bytes.fromhex(rawtx)
rawtx = BytesIO(bytes.fromhex(rawtx))

return cls.parse_bytesio(rawtx, strict, network)
return cls.parse_bytesio(rawtx, strict, network, raw_bytes=raw_bytes)

@classmethod
def parse_bytesio(cls, rawtx, strict=True, network=DEFAULT_NETWORK, index=None):
def parse_bytesio(cls, rawtx, strict=True, network=DEFAULT_NETWORK, index=None, raw_bytes=b''):
"""
Parse a raw transaction and create a Transaction object
:param rawtx: Raw transaction string
:param rawtx: Raw transaction bytes stream
:type rawtx: BytesIO
:param strict: Raise exception when transaction is malformed, incomplete or not understood
:type strict: bool
:param network: Network, leave empty for default network
:type network: str, Network
:param index: index position in block
:type index: int
:param raw_bytes: Raw transaction as bytes if available
:param raw_bytes: bytes
:return Transaction:
"""
Expand All @@ -915,7 +922,6 @@ def parse_bytesio(cls, rawtx, strict=True, network=DEFAULT_NETWORK, index=None):
network = network
if not isinstance(network, Network):
cls.network = Network(network)
raw_bytes = b''

try:
pos_start = rawtx.tell()
Expand Down Expand Up @@ -995,7 +1001,7 @@ def parse_bytesio(cls, rawtx, strict=True, network=DEFAULT_NETWORK, index=None):
inputs[n].update_scripts()

locktime_bytes = rawtx.read(4)[::-1]
if len(locktime_bytes) != 4:
if len(locktime_bytes) != 4 and strict:
raise TransactionError("Invalid transaction size, locktime bytes incomplete")

locktime = int.from_bytes(locktime_bytes, 'big')
Expand Down Expand Up @@ -1025,7 +1031,8 @@ def parse_hex(cls, rawtx, strict=True, network=DEFAULT_NETWORK):
:return Transaction:
"""

return cls.parse_bytesio(BytesIO(bytes.fromhex(rawtx)), strict, network)
raw_bytes = bytes.fromhex(rawtx)
return cls.parse_bytesio(BytesIO(raw_bytes), strict, network, raw_bytes=raw_bytes)

@classmethod
def parse_bytes(cls, rawtx, strict=True, network=DEFAULT_NETWORK):
Expand All @@ -1043,7 +1050,7 @@ def parse_bytes(cls, rawtx, strict=True, network=DEFAULT_NETWORK):
:return Transaction:
"""

return cls.parse(BytesIO(rawtx), strict, network)
return cls.parse(BytesIO(rawtx), strict, network, raw_bytes=raw_bytes)

@staticmethod
def load(txid=None, filename=None):
Expand Down

0 comments on commit 85e316e

Please sign in to comment.