Skip to content

Commit

Permalink
Fix cancel action
Browse files Browse the repository at this point in the history
  • Loading branch information
KoalaSat committed Feb 28, 2025
1 parent 17699e2 commit 11b38c8
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 52 deletions.
72 changes: 37 additions & 35 deletions api/logics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1039,43 +1039,46 @@ def cancel_order(cls, order, user, state=None):

return True, None

# 2.a) When maker cancels after bond
#
# The order disapears from book and goes to cancelled. If strict, maker is charged the bond
# to prevent DDOS on the LN node and order book. If not strict, maker is returned
# the bond (more user friendly).
elif (
order.status in [Order.Status.PUB, Order.Status.PAU] and order.maker == user
):
# Return the maker bond (Maker gets returned the bond for cancelling public order)
if cls.return_bond(order.maker_bond):
order.update_status(Order.Status.UCA)
elif order.status in [Order.Status.PUB, Order.Status.PAU]:
if order.maker == user:
# 2.a) When maker cancels after bond
#
# The order disapears from book and goes to cancelled. If strict, maker is charged the bond
# to prevent DDOS on the LN node and order book. If not strict, maker is returned
# the bond (more user friendly).
# Return the maker bond (Maker gets returned the bond for cancelling public order)
if cls.return_bond(order.maker_bond):
order.update_status(Order.Status.UCA)

order.log("Order cancelled by maker while public or paused")
order.log("Maker bond was <b>unlocked</b>")

order.log("Order cancelled by maker while public or paused")
order.log("Maker bond was <b>unlocked</b>")
take_orders_queryset = TakeOrder.objects.filter(order=order)
for idx, take_order in enumerate(take_orders_queryset):
order.log("Pretaker bond was <b>unlocked</b>")
take_order.cancel(cls)

take_orders_queryset = TakeOrder.objects.filter(order=order)
for idx, take_order in enumerate(take_orders_queryset):
order.log("Pretaker bond was <b>unlocked</b>")
take_order.cancel(cls)
send_notification.delay(
order_id=order.id, message="public_order_cancelled"
)
nostr_send_order_event.delay(order_id=order.id)

send_notification.delay(
order_id=order.id, message="public_order_cancelled"
return True, None
else:
# 2.b) When pretaker cancels before bond
# LNPayment "take_order" is expired
take_order_query = TakeOrder.objects.filter(
order=order, taker=user, expires_at__gt=timezone.now()
)
nostr_send_order_event.delay(order_id=order.id)

return True, None

# 3) When taker cancels before bond
# The order goes back to the book as public.
# LNPayment "order.taker_bond" is deleted()
elif order.status == Order.Status.PUB and order.taker == user:
# adds a timeout penalty
cls.kick_taker(take_order)
if take_order_query.exists():
take_order = take_order_query.first()
# adds a timeout penalty
cls.kick_taker(take_order)

order.log("Taker cancelled before locking the bond")
order.log("Taker cancelled before locking the bond")

return True, None
return True, None

# 4) When taker or maker cancel after bond (before escrow)
#
Expand Down Expand Up @@ -1178,11 +1181,10 @@ def cancel_order(cls, order, user, state=None):
)
return True, None

else:
order.log(
f"Cancel request was sent by Robot({user.robot.id},{user.username}) on an invalid status {order.status}: <i>{Order.Status(order.status).label}</i>"
)
return False, {"bad_request": "You cannot cancel this order"}
order.log(
f"Cancel request was sent by Robot({user.robot.id},{user.username}) on an invalid status {order.status}: <i>{Order.Status(order.status).label}</i>"
)
return False, {"bad_request": "You cannot cancel this order"}

@classmethod
def collaborative_cancel(cls, order):
Expand Down
1 change: 1 addition & 0 deletions api/models/take_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class TakeOrder(models.Model):
def cancel(self, cls):
if self.expires_at > timezone.now():
self.expires_at = timezone.now()
self.save(update_fields=["expires_at"])
cls.cancel_bond(self.taker_bond)

def __str__(self):
Expand Down
33 changes: 18 additions & 15 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,10 @@ def get(self, request, format=None):
and data["is_pretaker"]
and not data["is_taker"]
):
data["total_secs_exp"] = order.t_to_expire(Order.Status.TAK)

valid, context = Logics.gen_taker_hold_invoice(order, request.user)

if valid:
data = {**data, **context}
else:
Expand Down Expand Up @@ -561,14 +564,20 @@ def take_update_confirm_dispute_cancel(self, request, format=None):
status.HTTP_400_BAD_REQUEST,
)

# 2) If action is cancel
elif action == "cancel":
valid, context = Logics.cancel_order(order, request.user)
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)

# Any other action is only allowed if the user is a participant
if not (order.maker == request.user or order.taker == request.user):
elif not (order.maker == request.user or order.taker == request.user):
return Response(
{"bad_request": "You are not a participant in this order"},
status.HTTP_403_FORBIDDEN,
)

# 2) If action is 'update invoice'
# 3) If action is 'update invoice'
elif action == "update_invoice":
# DEPRECATE post v0.5.1.
valid_signature, invoice = verify_signed_message(
Expand All @@ -587,7 +596,7 @@ def take_update_confirm_dispute_cancel(self, request, format=None):
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)

# 2.b) If action is 'update address'
# 3.b) If action is 'update address'
elif action == "update_address":
valid_signature, address = verify_signed_message(
request.user.robot.public_key, pgp_address
Expand All @@ -605,25 +614,19 @@ def take_update_confirm_dispute_cancel(self, request, format=None):
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)

# 3) If action is cancel
elif action == "cancel":
valid, context = Logics.cancel_order(order, request.user)
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)

# 4) If action is confirm
# 5) If action is confirm
elif action == "confirm":
valid, context = Logics.confirm_fiat(order, request.user)
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)

# 4.b) If action is confirm
# 5.b) If action is confirm
elif action == "undo_confirm":
valid, context = Logics.undo_confirm_fiat_sent(order, request.user)
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)

# 5) If action is dispute
# 6) If action is dispute
elif action == "dispute":
valid, context = Logics.open_dispute(order, request.user)
if not valid:
Expand All @@ -634,18 +637,18 @@ def take_update_confirm_dispute_cancel(self, request, format=None):
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)

# 6) If action is rate
# 7) If action is rate
elif action == "rate_user" and rating:
"""No user rating"""
pass

# 7) If action is rate_platform
# 8) If action is rate_platform
elif action == "rate_platform" and rating:
valid, context = Logics.rate_platform(request.user, rating)
if not valid:
return Response(context, status.HTTP_400_BAD_REQUEST)

# 8) If action is rate_platform
# 9) If action is rate_platform
elif action == "pause":
valid, context = Logics.pause_unpause_public_order(order, request.user)
if not valid:
Expand Down
30 changes: 28 additions & 2 deletions tests/test_trade_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,8 @@ def test_make_and_take_order_multiple_takers(self):
< timedelta(minutes=4)
)

third_invoice = data["bond_invoice"]

## Maker TAKE
trade.take_order()

Expand All @@ -508,6 +510,7 @@ def test_make_and_take_order_multiple_takers(self):
self.assertEqual(trade.response.status_code, 200)
self.assertResponse(trade.response)

self.assertNotEqual(third_invoice, data["bond_invoice"])
self.assertEqual(data["status_message"], Order.Status(Order.Status.PUB).label)
self.assertEqual(
data["ur_nick"], read_file(f"tests/robots/{trade.taker_index}/nickname")
Expand Down Expand Up @@ -986,7 +989,19 @@ def test_cancel_public_order_by_taker(self):

trade.cancel_order(trade.taker_index)
data = trade.response.json()
self.assertEqual(data["bad_request"], "You are not a participant in this order")
self.assertEqual(trade.response.status_code, 200)
self.assertFalse(data["is_participant"])
self.assertFalse(data["is_pretaker"])
self.assertFalse(data["is_taker"])
self.assertFalse(data["is_maker"])
self.assertTrue(
(timezone.datetime.fromisoformat(data["penalty"]) - timezone.now())
> timedelta(minutes=0)
)
self.assertTrue(
(timezone.datetime.fromisoformat(data["penalty"]) - timezone.now())
< timedelta(minutes=2)
)

trade.get_order(trade.maker_index)
data = trade.response.json()
Expand Down Expand Up @@ -1016,7 +1031,18 @@ def test_cancel_public_order_by_third(self):
trade.cancel_order(trade.third_index)

data = trade.response.json()
self.assertEqual(data["bad_request"], "You are not a participant in this order")
self.assertFalse(data["is_participant"])
self.assertFalse(data["is_pretaker"])
self.assertFalse(data["is_taker"])
self.assertFalse(data["is_maker"])
self.assertTrue(
(timezone.datetime.fromisoformat(data["penalty"]) - timezone.now())
> timedelta(minutes=0)
)
self.assertTrue(
(timezone.datetime.fromisoformat(data["penalty"]) - timezone.now())
< timedelta(minutes=2)
)

trade.get_order(trade.maker_index)
data = trade.response.json()
Expand Down

0 comments on commit 11b38c8

Please sign in to comment.