Skip to content

Commit

Permalink
refactor(python/stellar): Since the firmware does not support MuxedAc…
Browse files Browse the repository at this point in the history
…count, we refuse to process this type of transaction.
  • Loading branch information
overcat authored and matejcik committed Nov 4, 2021
1 parent 62b649e commit b3ac52e
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 1 deletion.
1 change: 1 addition & 0 deletions python/.changelog.d/1838.changed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`trezorlib.stellar` will refuse to process transactions containing MuxedAccount
14 changes: 14 additions & 0 deletions python/src/trezorlib/stellar.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
Price,
Network,
ManageBuyOffer,
MuxedAccount,
)
from stellar_sdk.xdr.signer_key_type import SignerKeyType

Expand Down Expand Up @@ -92,6 +93,7 @@ def from_envelope(envelope: "TransactionEnvelope"):
else:
raise ValueError("Unsupported memo type")

_raise_if_account_muxed_id_exists(parsed_tx.source)
tx = messages.StellarSignTx(
source_account=parsed_tx.source.account_id,
fee=parsed_tx.fee,
Expand All @@ -113,6 +115,7 @@ def from_envelope(envelope: "TransactionEnvelope"):
def _read_operation(op: "Operation"):
# TODO: Let's add muxed account support later.
if op.source:
_raise_if_account_muxed_id_exists(op.source)
source_account = op.source.account_id
else:
source_account = None
Expand All @@ -123,13 +126,15 @@ def _read_operation(op: "Operation"):
starting_balance=_read_amount(op.starting_balance),
)
if isinstance(op, Payment):
_raise_if_account_muxed_id_exists(op.destination)
return messages.StellarPaymentOp(
source_account=source_account,
destination_account=op.destination.account_id,
asset=_read_asset(op.asset),
amount=_read_amount(op.amount),
)
if isinstance(op, PathPaymentStrictReceive):
_raise_if_account_muxed_id_exists(op.destination)
operation = messages.StellarPathPaymentStrictReceiveOp(
source_account=source_account,
send_asset=_read_asset(op.send_asset),
Expand Down Expand Up @@ -212,6 +217,7 @@ def _read_operation(op: "Operation"):
is_authorized=bool(op.authorize.value),
)
if isinstance(op, AccountMerge):
_raise_if_account_muxed_id_exists(op.destination)
return messages.StellarAccountMergeOp(
source_account=source_account,
destination_account=op.destination.account_id,
Expand Down Expand Up @@ -239,6 +245,7 @@ def _read_operation(op: "Operation"):
offer_id=op.offer_id,
)
if isinstance(op, PathPaymentStrictSend):
_raise_if_account_muxed_id_exists(op.destination)
operation = messages.StellarPathPaymentStrictSendOp(
source_account=source_account,
send_asset=_read_asset(op.send_asset),
Expand All @@ -252,6 +259,13 @@ def _read_operation(op: "Operation"):
raise ValueError(f"Unknown operation type: {op.__class__.__name__}")


def _raise_if_account_muxed_id_exists(account: "MuxedAccount"):
# Currently Trezor firmware does not support MuxedAccount,
# so we throw an exception here.
if account.account_muxed_id is not None:
raise ValueError("MuxedAccount is not supported")


def _read_amount(amount: str) -> int:
return Operation.to_xdr_amount(amount)

Expand Down
169 changes: 168 additions & 1 deletion python/tests/test_stellar.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@
# You should have received a copy of the License along with this library.
# If not, see <https://www.gnu.org/licenses/lgpl-3.0.html>.
import pytest
from stellar_sdk import Account, Asset, Network, TransactionBuilder, TrustLineEntryFlag
from stellar_sdk import (
Account,
Asset,
Network,
TransactionBuilder,
TrustLineEntryFlag,
MuxedAccount,
)
from stellar_sdk.strkey import StrKey

from trezorlib import messages, stellar
Expand Down Expand Up @@ -837,3 +844,163 @@ def test_path_payment_strict_send():
assert operations[0].paths[1].type == messages.StellarAssetType.ALPHANUM12
assert operations[0].paths[1].code == path_asset2.code
assert operations[0].paths[1].issuer == path_asset2.issuer


def test_payment_muxed_account_not_support_raise():
tx = make_default_tx()
destination = MuxedAccount(
"GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", 1
)
amount = "50.0111"
asset_code = "XLM"
asset_issuer = None
operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V"

envelope = tx.append_payment_op(
destination=destination,
amount=amount,
asset_code=asset_code,
asset_issuer=asset_issuer,
source=operation_source,
).build()

with pytest.raises(ValueError, match="MuxedAccount is not supported"):
stellar.from_envelope(envelope)


def test_path_payment_strict_send_muxed_account_not_support_raise():
tx = make_default_tx()
destination = MuxedAccount(
"GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", 1
)
send_amount = "50.0112"
dest_min = "120"
send_code = "XLM"
send_issuer = None
dest_code = "USD"
dest_issuer = "GCSJ7MFIIGIRMAS4R3VT5FIFIAOXNMGDI5HPYTWS5X7HH74FSJ6STSGF"
operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V"
path_asset1 = Asset(
"JPY", "GD6PV7DXQJX7AGVXFQ2MTCLTCH6LR3E6IO2EO2YDZD7F7IOZZCCB5DSQ"
)
path_asset2 = Asset(
"BANANA", "GC7EKO37HNSKQ3V6RZ274EO7SFOWASQRHLX3OR5FIZK6UMV6LIEDXHGZ"
)

envelope = tx.append_path_payment_strict_send_op(
destination=destination,
send_code=send_code,
send_issuer=send_issuer,
send_amount=send_amount,
dest_code=dest_code,
dest_issuer=dest_issuer,
dest_min=dest_min,
path=[path_asset1, path_asset2],
source=operation_source,
).build()

with pytest.raises(ValueError, match="MuxedAccount is not supported"):
stellar.from_envelope(envelope)


def test_path_payment_strict_receive_muxed_account_not_support_raise():
tx = make_default_tx()
destination = MuxedAccount(
"GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", 1
)
send_max = "50.0111"
dest_amount = "100"
send_code = "XLM"
send_issuer = None
dest_code = "USD"
dest_issuer = "GCSJ7MFIIGIRMAS4R3VT5FIFIAOXNMGDI5HPYTWS5X7HH74FSJ6STSGF"
operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V"
path_asset1 = Asset(
"JPY", "GD6PV7DXQJX7AGVXFQ2MTCLTCH6LR3E6IO2EO2YDZD7F7IOZZCCB5DSQ"
)
path_asset2 = Asset(
"BANANA", "GC7EKO37HNSKQ3V6RZ274EO7SFOWASQRHLX3OR5FIZK6UMV6LIEDXHGZ"
)

envelope = tx.append_path_payment_strict_receive_op(
destination=destination,
send_code=send_code,
send_issuer=send_issuer,
send_max=send_max,
dest_code=dest_code,
dest_issuer=dest_issuer,
dest_amount=dest_amount,
path=[path_asset1, path_asset2],
source=operation_source,
).build()

with pytest.raises(ValueError, match="MuxedAccount is not supported"):
stellar.from_envelope(envelope)


def test_account_merge_muxed_account_not_support_raise():
tx = make_default_tx()
destination = MuxedAccount(
"GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6", 1
)
operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V"

envelope = tx.append_account_merge_op(
destination=destination, source=operation_source
).build()

with pytest.raises(ValueError, match="MuxedAccount is not supported"):
stellar.from_envelope(envelope)


def test_op_source_muxed_account_not_support_raise():
tx = make_default_tx()
destination = "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6"
amount = "50.0111"
asset_code = "XLM"
asset_issuer = None
operation_source = MuxedAccount(
"GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V", 2
)

envelope = tx.append_payment_op(
destination=destination,
amount=amount,
asset_code=asset_code,
asset_issuer=asset_issuer,
source=operation_source,
).build()

with pytest.raises(ValueError, match="MuxedAccount is not supported"):
stellar.from_envelope(envelope)


def test_tx_source_muxed_account_not_support_raise():
source_account = Account(
account_id=MuxedAccount(TX_SOURCE, 123456), sequence=SEQUENCE
)
destination = "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6"
amount = "50.0111"
asset_code = "XLM"
asset_issuer = None
operation_source = "GAEB4MRKRCONK4J7MVQXAHTNDPAECUCCCNE7YC5CKM34U3OJ673A4D6V"

envelope = (
TransactionBuilder(
source_account=source_account,
network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
base_fee=BASE_FEE,
)
.add_time_bounds(TIMEBOUNDS_START, TIMEBOUNDS_END)
.append_payment_op(
destination=destination,
amount=amount,
asset_code=asset_code,
asset_issuer=asset_issuer,
source=operation_source,
)
.build()
)

with pytest.raises(ValueError, match="MuxedAccount is not supported"):
stellar.from_envelope(envelope)

0 comments on commit b3ac52e

Please sign in to comment.