mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-20 10:34:20 +01:00
Use m̶u̶l̶t̶i̶p̶r̶o̶c̶e̶s̶s̶i̶n̶g̶ asyncio locks instead of db locks (#256)
* use mp locks instead of db locks * replace mp.Lock with asyncio.Lock * make format * push * remove db connection (and lock) and delete asyncio locks
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import asyncio
|
||||
import math
|
||||
from typing import Dict, List, Literal, Optional, Set, Union
|
||||
|
||||
@@ -15,7 +16,7 @@ from ..core.base import (
|
||||
from ..core.crypto import b_dhke
|
||||
from ..core.crypto.keys import derive_pubkey, random_hash
|
||||
from ..core.crypto.secp import PublicKey
|
||||
from ..core.db import Connection, Database, lock_table
|
||||
from ..core.db import Connection, Database
|
||||
from ..core.helpers import fee_reserve, sum_proofs
|
||||
from ..core.script import verify_script
|
||||
from ..core.settings import settings
|
||||
@@ -25,6 +26,11 @@ from ..mint.crud import LedgerCrud
|
||||
|
||||
|
||||
class Ledger:
|
||||
locks: Dict[str, asyncio.Lock] = {} # holds multiprocessing locks
|
||||
proofs_pending_lock: asyncio.Lock = (
|
||||
asyncio.Lock()
|
||||
) # holds locks for proofs_pending database
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
db: Database,
|
||||
@@ -433,6 +439,7 @@ class Ledger:
|
||||
Exception: At least one proof already in pending table.
|
||||
"""
|
||||
# first we check whether these proofs are pending aready
|
||||
async with self.proofs_pending_lock:
|
||||
await self._validate_proofs_pending(proofs, conn)
|
||||
for p in proofs:
|
||||
try:
|
||||
@@ -456,6 +463,7 @@ class Ledger:
|
||||
"""
|
||||
# we try: except: this block in order to avoid that any errors here
|
||||
# could block the _invalidate_proofs() call that happens afterwards.
|
||||
async with self.proofs_pending_lock:
|
||||
try:
|
||||
for p in proofs:
|
||||
logger.trace(
|
||||
@@ -469,7 +477,9 @@ class Ledger:
|
||||
print(e)
|
||||
pass
|
||||
|
||||
async def _validate_proofs_pending(self, proofs: List[Proof], conn):
|
||||
async def _validate_proofs_pending(
|
||||
self, proofs: List[Proof], conn: Optional[Connection] = None
|
||||
):
|
||||
"""Checks if any of the provided proofs is in the pending proofs table.
|
||||
|
||||
Args:
|
||||
@@ -633,8 +643,9 @@ class Ledger:
|
||||
keyset (Optional[MintKeyset], optional): Keyset to use. If not provided, uses active keyset. Defaults to None.
|
||||
|
||||
Raises:
|
||||
Exception: Lightning invvoice is not paid.
|
||||
Exception: Lightning is turned on but no payment hash is provided.
|
||||
e: Something went wrong with the invoice check.
|
||||
Exception: Something went wrong with the invoice check.
|
||||
Exception: Amount too large.
|
||||
|
||||
Returns:
|
||||
@@ -643,20 +654,17 @@ class Ledger:
|
||||
logger.trace("called mint")
|
||||
amounts = [b.amount for b in B_s]
|
||||
amount = sum(amounts)
|
||||
async with self.db.connect() as conn:
|
||||
logger.trace("attempting lock table invoice")
|
||||
await conn.execute(lock_table(self.db, "invoices"))
|
||||
logger.trace("locked table invoice")
|
||||
# check if lightning invoice was paid
|
||||
|
||||
if settings.lightning:
|
||||
if not hash:
|
||||
raise Exception("no hash provided.")
|
||||
try:
|
||||
logger.trace("checking lightning invoice")
|
||||
paid = await self._check_lightning_invoice(amount, hash, conn)
|
||||
logger.trace(f"invoice paid: {paid}")
|
||||
except Exception as e:
|
||||
raise e
|
||||
self.locks[hash] = (
|
||||
self.locks.get(hash) or asyncio.Lock()
|
||||
) # create a new lock if it doesn't exist
|
||||
async with self.locks[hash]:
|
||||
# will raise an exception if the invoice is not paid or tokens are already issued
|
||||
await self._check_lightning_invoice(amount, hash)
|
||||
del self.locks[hash]
|
||||
|
||||
for amount in amounts:
|
||||
if amount not in [2**i for i in range(settings.max_order)]:
|
||||
@@ -687,15 +695,7 @@ class Ledger:
|
||||
|
||||
logger.trace("melt called")
|
||||
|
||||
async with self.db.connect() as conn:
|
||||
logger.trace("attempting lock table proofs_pending")
|
||||
await conn.execute(lock_table(self.db, "proofs_pending"))
|
||||
logger.trace("locked table proofs_pending")
|
||||
# validate and set proofs as pending
|
||||
logger.trace("setting proofs pending")
|
||||
await self._set_proofs_pending(proofs, conn)
|
||||
logger.trace(f"set proofs as pending")
|
||||
logger.trace("unlocked table proofs_pending")
|
||||
await self._set_proofs_pending(proofs)
|
||||
|
||||
try:
|
||||
await self._verify_proofs(proofs)
|
||||
@@ -751,14 +751,7 @@ class Ledger:
|
||||
raise e
|
||||
finally:
|
||||
# delete proofs from pending list
|
||||
async with self.db.connect() as conn:
|
||||
logger.trace("attempting lock table proofs_pending")
|
||||
await conn.execute(lock_table(self.db, "proofs_pending"))
|
||||
logger.trace("locked table proofs_pending")
|
||||
logger.trace("unsetting proofs as pending")
|
||||
await self._unset_proofs_pending(proofs, conn)
|
||||
logger.trace(f"unset proofs as pending")
|
||||
logger.trace("unlocked table proofs_pending")
|
||||
await self._unset_proofs_pending(proofs)
|
||||
|
||||
return status, preimage, return_promises
|
||||
|
||||
@@ -829,15 +822,9 @@ class Ledger:
|
||||
Tuple[List[BlindSignature],List[BlindSignature]]: Promises on both sides of the split.
|
||||
"""
|
||||
logger.trace(f"split called")
|
||||
# set proofs as pending
|
||||
async with self.db.connect() as conn:
|
||||
logger.trace("attempting lock table proofs_pending")
|
||||
await conn.execute(lock_table(self.db, "proofs_pending"))
|
||||
logger.trace("locked table proofs_pending")
|
||||
# validate and set proofs as pending
|
||||
logger.trace("setting proofs pending")
|
||||
await self._set_proofs_pending(proofs, conn)
|
||||
logger.trace(f"set proofs as pending")
|
||||
|
||||
await self._set_proofs_pending(proofs)
|
||||
|
||||
total = sum_proofs(proofs)
|
||||
|
||||
try:
|
||||
@@ -863,13 +850,7 @@ class Ledger:
|
||||
raise e
|
||||
finally:
|
||||
# delete proofs from pending list
|
||||
async with self.db.connect() as conn:
|
||||
logger.trace("attempting lock table proofs_pending")
|
||||
await conn.execute(lock_table(self.db, "proofs_pending"))
|
||||
logger.trace("locked table proofs_pending")
|
||||
logger.trace("unsetting proofs as pending")
|
||||
await self._unset_proofs_pending(proofs, conn)
|
||||
logger.trace(f"unset proofs as pending")
|
||||
await self._unset_proofs_pending(proofs)
|
||||
|
||||
# Mark proofs as used and prepare new promises
|
||||
logger.trace(f"invalidating proofs")
|
||||
|
||||
@@ -453,6 +453,7 @@ async def pending(ctx: Context, legacy, number: int, offset: int):
|
||||
tokenObj = deserialize_token_from_string(token)
|
||||
mint = [t.mint for t in tokenObj.token][0]
|
||||
# token_hidden_secret = await wallet.serialize_proofs(grouped_proofs)
|
||||
assert grouped_proofs[0].time_reserved
|
||||
reserved_date = datetime.utcfromtimestamp(
|
||||
int(grouped_proofs[0].time_reserved)
|
||||
).strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
Reference in New Issue
Block a user