fix: enforce order of payments (#2313)

* fix: enforce order of payments

* fix: do not return wallet by key if the wallet is deleted
This commit is contained in:
Vlad Stan 2024-03-12 15:31:40 +02:00 committed by GitHub
parent 54dec171f9
commit 65b8868c36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 6 additions and 8 deletions

View file

@ -554,7 +554,8 @@ async def get_wallet_for_key(
row = await (conn or db).fetchone(
"""
SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0)
AS balance_msat FROM wallets WHERE adminkey = ? OR inkey = ?
AS balance_msat FROM wallets
WHERE (adminkey = ? OR inkey = ?) AND deleted = false
""",
(key, key),
)
@ -602,6 +603,7 @@ async def get_standalone_payment(
SELECT *
FROM apipayments
WHERE {clause}
ORDER BY amount
LIMIT 1
""",
tuple(values),

View file

@ -539,10 +539,7 @@ async def api_payment(payment_hash, X_Api_Key: Optional[str] = Header(None)):
# We use X_Api_Key here because we want this call to work with and without keys
# If a valid key is given, we also return the field "details", otherwise not
wallet = await get_wallet_for_key(X_Api_Key) if isinstance(X_Api_Key, str) else None
wallet = wallet if wallet and not wallet.deleted else None
# we have to specify the wallet id here, because postgres and sqlite return
# internal payments in different order and get_standalone_payment otherwise
# just fetches the first one, causing unpredictable results
payment = await get_standalone_payment(
payment_hash, wallet_id=wallet.id if wallet else None
)

View file

@ -62,7 +62,7 @@ class KeyChecker(SecurityBase):
# avoided here. Also, we should not return the wallet here - thats
# silly. Possibly store it in a Redis DB
wallet = await get_wallet_for_key(key_value, self._key_type)
if not wallet or wallet.deleted:
if not wallet:
raise HTTPException(
status_code=HTTPStatus.UNAUTHORIZED,
detail="Invalid key or wallet.",

View file

@ -34,5 +34,4 @@ async def test_create_wallet_and_delete_wallet(app, to_user):
assert del_wallet.deleted is True
del_wallet = await get_wallet_for_key(wallet.inkey)
assert del_wallet is not None
assert del_wallet.deleted is True
assert del_wallet is None