mirror of
https://github.com/aljazceru/nutshell.git
synced 2026-01-12 21:24:21 +01:00
Chore: update dev dependencies (#658)
* update dev dependencies * test * revert tests * fix event loop scope * ruff format * add old test * remove custom event loop * default loop scope * skip earlier * trigger * trigger again
This commit is contained in:
@@ -13,7 +13,7 @@ repos:
|
||||
- id: mixed-line-ending
|
||||
- id: check-case-conflict
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.2.1
|
||||
rev: v0.7.1
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--fix]
|
||||
|
||||
@@ -135,12 +135,12 @@ class Proof(BaseModel):
|
||||
time_created: Union[None, str] = ""
|
||||
time_reserved: Union[None, str] = ""
|
||||
derivation_path: Union[None, str] = "" # derivation path of the proof
|
||||
mint_id: Union[
|
||||
None, str
|
||||
] = None # holds the id of the mint operation that created this proof
|
||||
melt_id: Union[
|
||||
None, str
|
||||
] = None # holds the id of the melt operation that destroyed this proof
|
||||
mint_id: Union[None, str] = (
|
||||
None # holds the id of the mint operation that created this proof
|
||||
)
|
||||
melt_id: Union[None, str] = (
|
||||
None # holds the id of the melt operation that destroyed this proof
|
||||
)
|
||||
|
||||
def __init__(self, **data):
|
||||
super().__init__(**data)
|
||||
@@ -825,43 +825,35 @@ class MintKeyset:
|
||||
class Token(ABC):
|
||||
@property
|
||||
@abstractmethod
|
||||
def proofs(self) -> List[Proof]:
|
||||
...
|
||||
def proofs(self) -> List[Proof]: ...
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def amount(self) -> int:
|
||||
...
|
||||
def amount(self) -> int: ...
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def mint(self) -> str:
|
||||
...
|
||||
def mint(self) -> str: ...
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def keysets(self) -> List[str]:
|
||||
...
|
||||
def keysets(self) -> List[str]: ...
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def memo(self) -> Optional[str]:
|
||||
...
|
||||
def memo(self) -> Optional[str]: ...
|
||||
|
||||
@memo.setter
|
||||
@abstractmethod
|
||||
def memo(self, memo: Optional[str]):
|
||||
...
|
||||
def memo(self, memo: Optional[str]): ...
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def unit(self) -> str:
|
||||
...
|
||||
def unit(self) -> str: ...
|
||||
|
||||
@unit.setter
|
||||
@abstractmethod
|
||||
def unit(self, unit: str):
|
||||
...
|
||||
def unit(self, unit: str): ...
|
||||
|
||||
|
||||
class TokenV3Token(BaseModel):
|
||||
|
||||
@@ -211,9 +211,9 @@ class PostMeltQuoteResponse(BaseModel):
|
||||
quote: str # quote id
|
||||
amount: int # input amount
|
||||
fee_reserve: int # input fee reserve
|
||||
paid: Optional[
|
||||
bool
|
||||
] = None # whether the request has been paid # DEPRECATED as per NUT PR #136
|
||||
paid: Optional[bool] = (
|
||||
None # whether the request has been paid # DEPRECATED as per NUT PR #136
|
||||
)
|
||||
state: Optional[str] # state of the quote
|
||||
expiry: Optional[int] # expiry of the quote
|
||||
payment_preimage: Optional[str] = None # payment preimage
|
||||
|
||||
@@ -32,8 +32,7 @@ class LedgerCrud(ABC):
|
||||
derivation_path: str = "",
|
||||
seed: str = "",
|
||||
conn: Optional[Connection] = None,
|
||||
) -> List[MintKeyset]:
|
||||
...
|
||||
) -> List[MintKeyset]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_proofs_used(
|
||||
@@ -42,8 +41,7 @@ class LedgerCrud(ABC):
|
||||
Ys: List[str],
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> List[Proof]:
|
||||
...
|
||||
) -> List[Proof]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def invalidate_proof(
|
||||
@@ -53,8 +51,7 @@ class LedgerCrud(ABC):
|
||||
proof: Proof,
|
||||
quote_id: Optional[str] = None,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_all_melt_quotes_from_pending_proofs(
|
||||
@@ -62,8 +59,7 @@ class LedgerCrud(ABC):
|
||||
*,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> List[MeltQuote]:
|
||||
...
|
||||
) -> List[MeltQuote]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_pending_proofs_for_quote(
|
||||
@@ -72,8 +68,7 @@ class LedgerCrud(ABC):
|
||||
quote_id: str,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> List[Proof]:
|
||||
...
|
||||
) -> List[Proof]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_proofs_pending(
|
||||
@@ -82,8 +77,7 @@ class LedgerCrud(ABC):
|
||||
Ys: List[str],
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> List[Proof]:
|
||||
...
|
||||
) -> List[Proof]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def set_proof_pending(
|
||||
@@ -93,8 +87,7 @@ class LedgerCrud(ABC):
|
||||
proof: Proof,
|
||||
quote_id: Optional[str] = None,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
async def unset_proof_pending(
|
||||
@@ -103,8 +96,7 @@ class LedgerCrud(ABC):
|
||||
proof: Proof,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
async def store_keyset(
|
||||
@@ -113,8 +105,7 @@ class LedgerCrud(ABC):
|
||||
db: Database,
|
||||
keyset: MintKeyset,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
async def update_keyset(
|
||||
@@ -123,16 +114,14 @@ class LedgerCrud(ABC):
|
||||
db: Database,
|
||||
keyset: MintKeyset,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_balance(
|
||||
self,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> int:
|
||||
...
|
||||
) -> int: ...
|
||||
|
||||
@abstractmethod
|
||||
async def store_promise(
|
||||
@@ -146,8 +135,7 @@ class LedgerCrud(ABC):
|
||||
e: str = "",
|
||||
s: str = "",
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_promise(
|
||||
@@ -156,8 +144,7 @@ class LedgerCrud(ABC):
|
||||
db: Database,
|
||||
b_: str,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> Optional[BlindedSignature]:
|
||||
...
|
||||
) -> Optional[BlindedSignature]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_promises(
|
||||
@@ -166,8 +153,7 @@ class LedgerCrud(ABC):
|
||||
db: Database,
|
||||
b_s: List[str],
|
||||
conn: Optional[Connection] = None,
|
||||
) -> List[BlindedSignature]:
|
||||
...
|
||||
) -> List[BlindedSignature]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def store_mint_quote(
|
||||
@@ -176,8 +162,7 @@ class LedgerCrud(ABC):
|
||||
quote: MintQuote,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_mint_quote(
|
||||
@@ -188,8 +173,7 @@ class LedgerCrud(ABC):
|
||||
request: Optional[str] = None,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> Optional[MintQuote]:
|
||||
...
|
||||
) -> Optional[MintQuote]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_mint_quote_by_request(
|
||||
@@ -198,8 +182,7 @@ class LedgerCrud(ABC):
|
||||
request: str,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> Optional[MintQuote]:
|
||||
...
|
||||
) -> Optional[MintQuote]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def update_mint_quote(
|
||||
@@ -208,8 +191,7 @@ class LedgerCrud(ABC):
|
||||
quote: MintQuote,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
async def store_melt_quote(
|
||||
@@ -218,8 +200,7 @@ class LedgerCrud(ABC):
|
||||
quote: MeltQuote,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_melt_quote(
|
||||
@@ -230,8 +211,7 @@ class LedgerCrud(ABC):
|
||||
request: Optional[str] = None,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> Optional[MeltQuote]:
|
||||
...
|
||||
) -> Optional[MeltQuote]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def get_melt_quote_by_request(
|
||||
@@ -240,8 +220,7 @@ class LedgerCrud(ABC):
|
||||
request: str,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> Optional[MeltQuote]:
|
||||
...
|
||||
) -> Optional[MeltQuote]: ...
|
||||
|
||||
@abstractmethod
|
||||
async def update_melt_quote(
|
||||
@@ -250,8 +229,7 @@ class LedgerCrud(ABC):
|
||||
quote: MeltQuote,
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> None:
|
||||
...
|
||||
) -> None: ...
|
||||
|
||||
|
||||
class LedgerCrudSqlite(LedgerCrud):
|
||||
@@ -359,7 +337,7 @@ class LedgerCrudSqlite(LedgerCrud):
|
||||
SELECT * from {db.table_with_schema('melt_quotes')} WHERE quote in (SELECT DISTINCT melt_quote FROM {db.table_with_schema('proofs_pending')})
|
||||
"""
|
||||
)
|
||||
return [MeltQuote.from_row(r) for r in rows]
|
||||
return [MeltQuote.from_row(r) for r in rows] # type: ignore
|
||||
|
||||
async def get_pending_proofs_for_quote(
|
||||
self,
|
||||
@@ -601,7 +579,7 @@ class LedgerCrudSqlite(LedgerCrud):
|
||||
""",
|
||||
values,
|
||||
)
|
||||
return MeltQuote.from_row(row) if row else None
|
||||
return MeltQuote.from_row(row) if row else None # type: ignore
|
||||
|
||||
async def get_melt_quote_by_request(
|
||||
self,
|
||||
@@ -617,7 +595,7 @@ class LedgerCrudSqlite(LedgerCrud):
|
||||
""",
|
||||
{"request": request},
|
||||
)
|
||||
return MeltQuote.from_row(row) if row else None
|
||||
return MeltQuote.from_row(row) if row else None # type: ignore
|
||||
|
||||
async def update_melt_quote(
|
||||
self,
|
||||
@@ -685,7 +663,7 @@ class LedgerCrudSqlite(LedgerCrud):
|
||||
db: Database,
|
||||
conn: Optional[Connection] = None,
|
||||
) -> int:
|
||||
row: List = await (conn or db).fetchone(
|
||||
row = await (conn or db).fetchone(
|
||||
f"""
|
||||
SELECT * from {db.table_with_schema('balance')}
|
||||
"""
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
|
||||
"""Reference implementation for Bech32/Bech32m and segwit addresses."""
|
||||
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
|
||||
@@ -45,9 +45,9 @@ class NostrClient:
|
||||
def connect(self):
|
||||
for relay in self.relays:
|
||||
self.relay_manager.add_relay(relay)
|
||||
self.relay_manager.open_connections({
|
||||
"cert_reqs": ssl.CERT_NONE
|
||||
}) # NOTE: This disables ssl certificate verification
|
||||
self.relay_manager.open_connections(
|
||||
{"cert_reqs": ssl.CERT_NONE}
|
||||
) # NOTE: This disables ssl certificate verification
|
||||
|
||||
def close(self):
|
||||
self.relay_manager.close_connections()
|
||||
@@ -105,13 +105,15 @@ class NostrClient:
|
||||
self.relay_manager.publish_event(dm)
|
||||
|
||||
def get_dm(self, sender_publickey: PublicKey, callback_func=None, filter_kwargs={}):
|
||||
filters = Filters([
|
||||
Filter(
|
||||
kinds=[EventKind.ENCRYPTED_DIRECT_MESSAGE],
|
||||
pubkey_refs=[sender_publickey.hex()],
|
||||
**filter_kwargs,
|
||||
)
|
||||
])
|
||||
filters = Filters(
|
||||
[
|
||||
Filter(
|
||||
kinds=[EventKind.ENCRYPTED_DIRECT_MESSAGE],
|
||||
pubkey_refs=[sender_publickey.hex()],
|
||||
**filter_kwargs,
|
||||
)
|
||||
]
|
||||
)
|
||||
subscription_id = os.urandom(4).hex()
|
||||
self.relay_manager.add_subscription(subscription_id, filters)
|
||||
|
||||
|
||||
@@ -77,18 +77,20 @@ class Event:
|
||||
)
|
||||
|
||||
def to_message(self) -> str:
|
||||
return json.dumps([
|
||||
ClientMessageType.EVENT,
|
||||
{
|
||||
"id": self.id,
|
||||
"pubkey": self.public_key,
|
||||
"created_at": self.created_at,
|
||||
"kind": self.kind,
|
||||
"tags": self.tags,
|
||||
"content": self.content,
|
||||
"sig": self.signature,
|
||||
},
|
||||
])
|
||||
return json.dumps(
|
||||
[
|
||||
ClientMessageType.EVENT,
|
||||
{
|
||||
"id": self.id,
|
||||
"pubkey": self.public_key,
|
||||
"created_at": self.created_at,
|
||||
"kind": self.kind,
|
||||
"tags": self.tags,
|
||||
"content": self.content,
|
||||
"sig": self.signature,
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
1017
poetry.lock
generated
1017
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ authors = ["calle <callebtc@protonmail.com>"]
|
||||
license = "MIT"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.8.1"
|
||||
python = "^3.10"
|
||||
SQLAlchemy = {version = "^2.0.35", extras = ["asyncio"]}
|
||||
click = "^8.1.7"
|
||||
pydantic = "^1.10.2"
|
||||
@@ -29,7 +29,6 @@ httpx = {extras = ["socks"], version = "^0.25.1"}
|
||||
bip32 = "^4.0"
|
||||
mnemonic = "^0.20"
|
||||
bolt11 = "^2.0.5"
|
||||
pre-commit = "^3.5.0"
|
||||
websockets = "^12.0"
|
||||
slowapi = "^0.1.9"
|
||||
cbor2 = "^5.6.2"
|
||||
@@ -42,19 +41,23 @@ types-protobuf = "^5.27.0.20240626"
|
||||
grpcio-tools = "^1.65.1"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pytest-asyncio = "^0.21.1"
|
||||
pytest-cov = "^4.0.0"
|
||||
pytest = "^7.4.0"
|
||||
pre-commit = "^3.3.3"
|
||||
fastapi-profiler = "^1.2.0"
|
||||
respx = "^0.20.2"
|
||||
ruff = "^0.2.1"
|
||||
mypy = "^1.8.0"
|
||||
pytest-asyncio = "^0.24.0"
|
||||
pytest-cov = "^6.0.0"
|
||||
pytest = "^8.3.3"
|
||||
fastapi-profiler = "^1.4.1"
|
||||
respx = "^0.21.1"
|
||||
ruff = "^0.7.1"
|
||||
mypy = "^1.13.0"
|
||||
pre-commit = "^4.0.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
asyncio_mode = "strict"
|
||||
asyncio_default_fixture_loop_scope = "function"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
mint = "cashu.mint.main:main"
|
||||
cashu = "cashu.wallet.cli.cli:cli"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import asyncio
|
||||
import importlib
|
||||
import multiprocessing
|
||||
import os
|
||||
@@ -60,14 +59,6 @@ Path(settings.cashu_dir).mkdir(parents=True, exist_ok=True)
|
||||
# from cashu.mint.startup import lightning_backend # noqa
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def event_loop():
|
||||
policy = asyncio.get_event_loop_policy()
|
||||
loop = policy.new_event_loop()
|
||||
yield loop
|
||||
loop.close()
|
||||
|
||||
|
||||
class UvicornServer(multiprocessing.Process):
|
||||
def __init__(self, config: Config):
|
||||
super().__init__()
|
||||
|
||||
@@ -115,36 +115,40 @@ async def test_db_get_connection(ledger: Ledger):
|
||||
assert isinstance(conn, Connection)
|
||||
|
||||
|
||||
# @pytest.mark.asyncio
|
||||
# async def test_db_get_connection_locked(wallet: Wallet, ledger: Ledger):
|
||||
# mint_quote = await wallet.request_mint(64)
|
||||
@pytest.mark.asyncio
|
||||
async def test_db_get_connection_locked(wallet: Wallet, ledger: Ledger):
|
||||
mint_quote = await wallet.request_mint(64)
|
||||
|
||||
# async def get_connection():
|
||||
# """This code makes sure that only the error of the second connection is raised (which we check in the assert_err)"""
|
||||
# try:
|
||||
# async with ledger.db.get_connection(lock_table="mint_quotes"):
|
||||
# try:
|
||||
# async with ledger.db.get_connection(
|
||||
# lock_table="mint_quotes", lock_timeout=0.1
|
||||
# ) as conn2:
|
||||
# # write something with conn1, we never reach this point if the lock works
|
||||
# await conn2.execute(
|
||||
# f"INSERT INTO mint_quotes (quote, amount) VALUES ('{mint_quote.quote}', 100);"
|
||||
# )
|
||||
# except Exception as exc:
|
||||
# # this is expected to raise
|
||||
# raise Exception(f"conn2: {exc}")
|
||||
async def get_connection():
|
||||
"""This code makes sure that only the error of the second connection is raised (which we check in the assert_err)"""
|
||||
try:
|
||||
async with ledger.db.get_connection(lock_table="mint_quotes"):
|
||||
try:
|
||||
async with ledger.db.get_connection(
|
||||
lock_table="mint_quotes", lock_timeout=0.1
|
||||
) as conn2:
|
||||
# write something with conn1, we never reach this point if the lock works
|
||||
await conn2.execute(
|
||||
f"INSERT INTO mint_quotes (quote, amount) VALUES ('{mint_quote.quote}', 100);"
|
||||
)
|
||||
except Exception as exc:
|
||||
# this is expected to raise
|
||||
raise Exception(f"conn2: {exc}")
|
||||
|
||||
# except Exception as exc:
|
||||
# if str(exc).startswith("conn2"):
|
||||
# raise exc
|
||||
# else:
|
||||
# raise Exception("not expected to happen")
|
||||
except Exception as exc:
|
||||
if str(exc).startswith("conn2"):
|
||||
raise exc
|
||||
else:
|
||||
raise Exception("not expected to happen")
|
||||
|
||||
# await assert_err(get_connection(), "failed to acquire database lock")
|
||||
await assert_err(get_connection(), "failed to acquire database lock")
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skipif(
|
||||
not settings.mint_database.startswith("postgres"),
|
||||
reason="SQLite does not support row locking",
|
||||
)
|
||||
async def test_db_get_connection_lock_row(wallet: Wallet, ledger: Ledger):
|
||||
if ledger.db.type == db.SQLITE:
|
||||
pytest.skip("SQLite does not support row locking")
|
||||
@@ -247,6 +251,10 @@ async def test_db_verify_spent_proofs_and_set_pending_no_race_condition_differen
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.skipif(
|
||||
not settings.mint_database.startswith("postgres"),
|
||||
reason="SQLite does not support row locking",
|
||||
)
|
||||
async def test_db_get_connection_lock_different_row(wallet: Wallet, ledger: Ledger):
|
||||
if ledger.db.type == db.SQLITE:
|
||||
pytest.skip("SQLite does not support row locking")
|
||||
|
||||
Reference in New Issue
Block a user