Skip to content

Commit

Permalink
new pack and unpack for enhancedsend
Browse files Browse the repository at this point in the history
  • Loading branch information
Ouziel committed Mar 3, 2025
1 parent 6ce116e commit b625ade
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import logging
import struct

from counterparty_rs import utils # pylint: disable=no-name-in-module

from counterpartycore.lib import config, exceptions, ledger
from counterpartycore.lib.messages.versions import send1
from counterpartycore.lib.parser import messagetype, protocol
Expand All @@ -16,7 +18,41 @@
ID = 2 # 0x02


def new_unpack(message):
try:
data_content = struct.unpack(f">{len(message)}s", message)[0].split(b"|")
arg_count = len(data_content)
(

Check warning on line 25 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L22-L25

Added lines #L22 - L25 were not covered by tests
asset_id_bytes,
quantity_bytes,
short_address_bytes,
) = data_content[0 : arg_count - 1]
# The memo is placed last to be able to contain `|`.
memo_bytes = b"|".join(data_content[arg_count - 1 :])

Check warning on line 31 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L31

Added line #L31 was not covered by tests

asset_id = helpers.bytes_to_int(asset_id_bytes)
asset = ledger.issuances.generate_asset_name(asset_id)
if asset == config.BTC:
raise exceptions.AssetNameError(f"{config.BTC} not allowed")

Check warning on line 36 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L33-L36

Added lines #L33 - L36 were not covered by tests

quantity = helpers.bytes_to_int(quantity_bytes)

Check warning on line 38 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L38

Added line #L38 was not covered by tests

full_address = utils.unpack_address(short_address_bytes)

Check warning on line 40 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L40

Added line #L40 was not covered by tests

return {

Check warning on line 42 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L42

Added line #L42 was not covered by tests
"asset": asset,
"quantity": quantity,
"address": full_address,
"memo": memo_bytes,
}
except Exception as e: # pylint: disable=broad-exception-caught
raise exceptions.UnpackError("could not unpack") from e

Check warning on line 49 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L48-L49

Added lines #L48 - L49 were not covered by tests


def unpack(message):
if protocol.enabled("taproot_support"):
return new_unpack(message)

Check warning on line 54 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L53-L54

Added lines #L53 - L54 were not covered by tests

try:
# account for memo bytes
memo_bytes_length = len(message) - LENGTH
Expand Down Expand Up @@ -136,8 +172,7 @@ def compose(
elif memo_is_hex:
memo_bytes = bytes.fromhex(memo)
else:
memo = memo.encode("utf-8")
memo_bytes = struct.pack(f">{len(memo)}s", memo)
memo_bytes = memo.encode("utf-8")

Check warning on line 175 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L175

Added line #L175 was not covered by tests

problems = validate(db, destination, asset, quantity, memo_bytes)
if problems and not skip_validation:
Expand All @@ -150,9 +185,22 @@ def compose(

short_address_bytes = address.pack(destination)

data = messagetype.pack(ID)
data += struct.pack(FORMAT, asset_id, quantity, short_address_bytes)
data += memo_bytes
if protocol.enabled("taproot_support"):
data = struct.pack(config.SHORT_TXTYPE_FORMAT, ID)
data_content = b"|".join(

Check warning on line 190 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L188-L190

Added lines #L188 - L190 were not covered by tests
[
helpers.int_to_bytes(asset_id),
helpers.int_to_bytes(quantity),
short_address_bytes,
memo_bytes,
]
)
data += struct.pack(f">{len(data_content)}s", data_content)

Check warning on line 198 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L198

Added line #L198 was not covered by tests
else:
memo_bytes = struct.pack(f">{len(memo)}s", memo)
data = messagetype.pack(ID)
data += struct.pack(FORMAT, asset_id, quantity, short_address_bytes)
data += memo_bytes

Check warning on line 203 in counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/messages/versions/enhancedsend.py#L200-L203

Added lines #L200 - L203 were not covered by tests

cursor.close()
# return an empty array as the second argument because we don't need to send BTC dust to the recipient
Expand Down
13 changes: 11 additions & 2 deletions counterparty-core/counterpartycore/lib/utils/address.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import logging

import bitcoin
from bitcoin.bech32 import CBech32Data
from bitcoinutils.keys import P2pkhAddress, P2shAddress, P2trAddress, P2wpkhAddress
Expand All @@ -7,6 +9,8 @@
from counterpartycore.lib.parser.protocol import enabled
from counterpartycore.lib.utils import base58, helpers, multisig

logger = logging.getLogger(config.LOGGER_NAME)


def is_pubkeyhash(monosig_address):
"""Check if PubKeyHash is valid P2PKH address."""
Expand Down Expand Up @@ -77,9 +81,10 @@ def pack(address):
if enabled("taproot_support"):
try:
packed = bytes(utils.pack_address(address, config.NETWORK_NAME))
print("packed", packed)
logger.warning(f"{address} packed: {packed}")

Check warning

Code scanning / pylint

Use lazy % formatting in logging functions. Warning

Use lazy % formatting in logging functions.
return packed
except Exception as e: # pylint: disable=broad-except # noqa: F841
logger.error(f"Error packing address: {e}")

Check warning

Code scanning / pylint

Use lazy % formatting in logging functions. Warning

Use lazy % formatting in logging functions.
raise exceptions.AddressError( # noqa: B904

Check warning on line 88 in counterparty-core/counterpartycore/lib/utils/address.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/utils/address.py#L81-L88

Added lines #L81 - L88 were not covered by tests
f"The address {address} is not a valid bitcoin address ({config.NETWORK_NAME})"
) from e
Expand Down Expand Up @@ -118,8 +123,12 @@ def unpack(short_address_bytes):
"""
if enabled("taproot_support"):
try:
return utils.unpack_address(short_address_bytes, config.NETWORK_NAME)
logger.warning(f"short_address_bytes: {short_address_bytes}")

Check warning

Code scanning / pylint

Use lazy % formatting in logging functions. Warning

Use lazy % formatting in logging functions.
unpacked = utils.unpack_address(short_address_bytes, config.NETWORK_NAME)
logger.warning(f"unpacked: {unpacked}")

Check warning

Code scanning / pylint

Use lazy % formatting in logging functions. Warning

Use lazy % formatting in logging functions.
return unpacked
except Exception as e: # pylint: disable=broad-except # noqa: F841
logger.error(f"Error unpacking address: {e}")

Check warning

Code scanning / pylint

Use lazy % formatting in logging functions. Warning

Use lazy % formatting in logging functions.
raise exceptions.DecodeError( # noqa: B904

Check warning on line 132 in counterparty-core/counterpartycore/lib/utils/address.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/utils/address.py#L124-L132

Added lines #L124 - L132 were not covered by tests
f"T{short_address_bytes} is not a valid packed bitcoin address ({config.NETWORK_NAME})"
) from e
Expand Down
12 changes: 12 additions & 0 deletions counterparty-core/counterpartycore/lib/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,15 @@ def dhash(text):

def dhash_string(text):
return binascii.hexlify(dhash(text)).decode()


def int_to_bytes(integer_in: int) -> bytes:
if integer_in == 0:
return b"\x00"
binary = bin(integer_in)[2:]
byte_length = (len(binary) + 7) // 8
return integer_in.to_bytes(byte_length, "little")

Check warning on line 149 in counterparty-core/counterpartycore/lib/utils/helpers.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/utils/helpers.py#L145-L149

Added lines #L145 - L149 were not covered by tests


def bytes_to_int(bytes_in: bytes) -> int:
return int.from_bytes(bytes_in, "little")

Check warning on line 153 in counterparty-core/counterpartycore/lib/utils/helpers.py

View check run for this annotation

Codecov / codecov/patch

counterparty-core/counterpartycore/lib/utils/helpers.py#L153

Added line #L153 was not covered by tests
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,14 @@ def test_taproot_scenario_1(empty_ledger_db, bitcoind_mock, defaults):
defaults["addresses"][0],
"6f488077d790fa369c53bccd1d09a548201fad6c56f48cf150f6c2f0e7062a01",
)


def test_taproot_scenario_2(empty_ledger_db, bitcoind_mock, defaults):
check_standard_scenario(
empty_ledger_db,
bitcoind_mock,
defaults,
defaults["addresses"][0],
defaults["p2tr_addresses"][0],
"",
)

0 comments on commit b625ade

Please sign in to comment.