Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new param current_status to /api/order cancel #1325

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion api/logics.py
Original file line number Diff line number Diff line change
Expand Up @@ -991,7 +991,17 @@ def is_penalized(user):
return False, None

@classmethod
def cancel_order(cls, order, user, state=None):
def cancel_order(cls, order, user, current_status=None):
# If current status is specified, do no cancel the order
# if it is not the correct one.
# This prevents the client from cancelling an order that
# recently changed status.
if current_status is not None:
if order.status != current_status:
return False, {
"bad_request": f"Wrong status, current one is {order.status}"
}

# Do not change order status if an is in order
# any of these status
do_not_cancel = [
Expand Down
5 changes: 5 additions & 0 deletions api/oas_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ class OrderViewSchema:
- `17` - Maker lost dispute
- `18` - Taker lost dispute

The client can specify `current_status` to make sure that the
order is cancelled just if it is in right status.
If the order is not in the specified status, the server will
return an error without cancelling the trade.

Note that there are penalties involved for cancelling a order
mid-trade so use this action carefully:

Expand Down
8 changes: 8 additions & 0 deletions api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,14 @@ class UpdateOrderSerializer(serializers.Serializer):
mining_fee_rate = serializers.DecimalField(
max_digits=6, decimal_places=3, allow_null=True, required=False, default=None
)
current_status = serializers.ChoiceField(
choices=Order.Status.choices,
default=None,
allow_null=True,
allow_blank=True,
required=False,
help_text="Current order status for the client",
)


class ClaimRewardSerializer(serializers.Serializer):
Expand Down
5 changes: 4 additions & 1 deletion api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ def take_update_confirm_dispute_cancel(self, request, format=None):
mining_fee_rate = serializer.data.get("mining_fee_rate")
statement = serializer.data.get("statement")
rating = serializer.data.get("rating")
current_status = serializer.data.get("current_status", None)

# 1) If action is take, it is a taker request!
if action == "take":
Expand Down Expand Up @@ -586,7 +587,9 @@ def take_update_confirm_dispute_cancel(self, request, format=None):

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

Expand Down
35 changes: 34 additions & 1 deletion docs/assets/schemas/api-latest.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: RoboSats REST API
version: 0.6.0
version: 0.6.2
x-logo:
url: https://raw.githubusercontent.com/Reckless-Satoshi/robosats/main/frontend/static/assets/images/robosats-0.1.1-banner.png
backgroundColor: '#FFFFFF'
Expand Down Expand Up @@ -469,6 +469,11 @@ paths:
- `17` - Maker lost dispute
- `18` - Taker lost dispute

The client can specify `current_status` to make sure that the
order is cancelled just if it is in right status.
If the order is not in the specified status, the server will
return an error without cancelling the trade.

Note that there are penalties involved for cancelling a order
mid-trade so use this action carefully:

Expand Down Expand Up @@ -1950,6 +1955,34 @@ components:
format: decimal
pattern: ^-?\d{0,3}(?:\.\d{0,3})?$
nullable: true
current_status:
nullable: true
description: |-
Current order status for the client

* `0` - Waiting for maker bond
* `1` - Public
* `2` - Paused
* `3` - Waiting for taker bond
* `4` - Cancelled
* `5` - Expired
* `6` - Waiting for trade collateral and buyer invoice
* `7` - Waiting only for seller trade collateral
* `8` - Waiting only for buyer invoice
* `9` - Sending fiat - In chatroom
* `10` - Fiat sent - In chatroom
* `11` - In dispute
* `12` - Collaboratively cancelled
* `13` - Sending satoshis to buyer
* `14` - Sucessful trade
* `15` - Failed lightning network routing
* `16` - Wait for dispute resolution
* `17` - Maker lost dispute
* `18` - Taker lost dispute
oneOf:
- $ref: '#/components/schemas/StatusEnum'
- $ref: '#/components/schemas/BlankEnum'
- $ref: '#/components/schemas/NullEnum'
required:
- action
Version:
Expand Down
3 changes: 3 additions & 0 deletions robosats/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@
}
},
"REDOC_DIST": "SIDECAR",
"ENUM_NAME_OVERRIDES": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha! TIL 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also learned it today, well yesterday, while searching how to remove that warning ahahaha

"StatusEnum": "api.models.order.Order.Status",
}
}


Expand Down
14 changes: 13 additions & 1 deletion tests/test_trade_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,19 @@ def test_cancel_public_order(self):
"""
trade = Trade(self.client)
trade.publish_order()
trade.cancel_order()

trade.cancel_order(current_status_int=6)

data = trade.response.json()

self.assertEqual(trade.response.status_code, 400)
self.assertResponse(trade.response)

self.assertEqual(
data["bad_request"], "Wrong status, current one is 1"
)

trade.cancel_order(current_status_int=1)

data = trade.response.json()

Expand Down
4 changes: 3 additions & 1 deletion tests/utils/trade.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,13 @@ def get_order(self, robot_index=1, first_encounter=False):
self.response = self.client.get(path + params, **headers)

@patch("api.tasks.send_notification.delay", send_notification)
def cancel_order(self, robot_index=1):
def cancel_order(self, robot_index=1, current_status_int=None):
path = reverse("order")
params = f"?order_id={self.order_id}"
headers = self.get_robot_auth(robot_index)
body = {"action": "cancel"}
if current_status_int is not None:
body.update({"current_status": current_status_int})
self.response = self.client.post(path + params, body, **headers)

def pause_order(self, robot_index=1):
Expand Down