diff --git a/README.md b/README.md index ebcef43..f6c974d 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ This command runs the mint on your local computer. Skip this step if you want to ## Docker ``` -docker run -d -p 3338:3338 --name nutshell -e MINT_BACKEND_BOLT11_SAT=FakeWallet -e MINT_LISTEN_HOST=0.0.0.0 -e MINT_LISTEN_PORT=3338 -e MINT_PRIVATE_KEY=TEST_PRIVATE_KEY cashubtc/nutshell:0.18.0 poetry run mint +docker run -d -p 3338:3338 --name nutshell -e MINT_BACKEND_BOLT11_SAT=FakeWallet -e MINT_LISTEN_HOST=0.0.0.0 -e MINT_LISTEN_PORT=3338 -e MINT_PRIVATE_KEY=TEST_PRIVATE_KEY cashubtc/nutshell:0.18.1 poetry run mint ``` ## From this repository diff --git a/cashu/core/settings.py b/cashu/core/settings.py index 42d9f40..97753c8 100644 --- a/cashu/core/settings.py +++ b/cashu/core/settings.py @@ -8,7 +8,7 @@ from pydantic import BaseSettings, Extra, Field env = Env() -VERSION = "0.18.0" +VERSION = "0.18.1" def find_env_file(): diff --git a/cashu/lightning/blink.py b/cashu/lightning/blink.py index 61006a2..18f1143 100644 --- a/cashu/lightning/blink.py +++ b/cashu/lightning/blink.py @@ -72,7 +72,7 @@ class BlinkWallet(LightningBackend): "Content-Type": "application/json", }, base_url=self.endpoint, - timeout=15, + timeout=None, ) async def status(self) -> StatusResponse: diff --git a/cashu/lightning/clnrest.py b/cashu/lightning/clnrest.py index 8fb85a0..fe8c056 100644 --- a/cashu/lightning/clnrest.py +++ b/cashu/lightning/clnrest.py @@ -80,7 +80,7 @@ class CLNRestWallet(LightningBackend): self.cert = settings.mint_clnrest_cert or False self.client = httpx.AsyncClient( - base_url=self.url, verify=self.cert, headers=self.auth + base_url=self.url, verify=self.cert, headers=self.auth, timeout=None, ) self.last_pay_index = 0 diff --git a/cashu/lightning/lnbits.py b/cashu/lightning/lnbits.py index c5e0ab6..e4392ae 100644 --- a/cashu/lightning/lnbits.py +++ b/cashu/lightning/lnbits.py @@ -40,6 +40,7 @@ class LNbitsWallet(LightningBackend): self.client = httpx.AsyncClient( verify=not settings.debug, headers={"X-Api-Key": settings.mint_lnbits_key}, + timeout=None, ) self.ws_url = f"{self.endpoint.replace('http', 'ws', 1)}/api/v1/ws/{settings.mint_lnbits_key}" self.old_api = True diff --git a/cashu/lightning/lndrest.py b/cashu/lightning/lndrest.py index fd5990a..f8057fe 100644 --- a/cashu/lightning/lndrest.py +++ b/cashu/lightning/lndrest.py @@ -100,7 +100,7 @@ class LndRestWallet(LightningBackend): self.auth = {"Grpc-Metadata-macaroon": self.macaroon} self.client = httpx.AsyncClient( - base_url=self.endpoint, headers=self.auth, verify=self.cert + base_url=self.endpoint, headers=self.auth, verify=self.cert, timeout=None, ) if self.supports_mpp: logger.info("LNDRestWallet enabling MPP feature") diff --git a/cashu/lightning/strike.py b/cashu/lightning/strike.py index 7142a8c..3745e3e 100644 --- a/cashu/lightning/strike.py +++ b/cashu/lightning/strike.py @@ -124,6 +124,7 @@ class StrikeWallet(LightningBackend): self.client = httpx.AsyncClient( verify=not settings.debug, headers=bearer_auth, + timeout=None, ) async def status(self) -> StatusResponse: diff --git a/cashu/mint/migrations.py b/cashu/mint/migrations.py index 3ebfe12..433c3e1 100644 --- a/cashu/mint/migrations.py +++ b/cashu/mint/migrations.py @@ -1137,3 +1137,21 @@ async def m028_promises_c_allow_null_add_melt_quote(db: Database): # recreate the balance views await create_balance_views(db, conn) + + +async def m029_remove_overlong_witness_values(db: Database): + """ + Delete any witness values longer than 1024 characters in proofs tables. + """ + async with db.connect() as conn: + # Clean proofs_used + await conn.execute( + f"UPDATE {db.table_with_schema('proofs_used')} SET witness = NULL " + "WHERE witness IS NOT NULL AND LENGTH(witness) > 1024" + ) + + # Clean proofs_pending (column exists in newer schemas) + await conn.execute( + f"UPDATE {db.table_with_schema('proofs_pending')} SET witness = NULL " + "WHERE witness IS NOT NULL AND LENGTH(witness) > 1024" + ) diff --git a/pyproject.toml b/pyproject.toml index 70dd10c..0c645c7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "cashu" -version = "0.18.0" +version = "0.18.1" description = "Ecash wallet and mint" authors = ["calle "] license = "MIT" diff --git a/setup.py b/setup.py index af59b17..4bd51f6 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ entry_points = {"console_scripts": ["cashu = cashu.wallet.cli.cli:cli"]} setuptools.setup( name="cashu", - version="0.18.0", + version="0.18.1", description="Ecash wallet and mint", long_description=long_description, long_description_content_type="text/markdown", diff --git a/tests/mint/test_mint_migrations.py b/tests/mint/test_mint_migrations.py new file mode 100644 index 0000000..dd97d21 --- /dev/null +++ b/tests/mint/test_mint_migrations.py @@ -0,0 +1,74 @@ +import pytest + +from cashu.core.db import Database +from cashu.core.migrations import migrate_databases +from cashu.mint import migrations as mint_migrations + + +@pytest.mark.asyncio +async def test_m029_witness_cleanup(): + db = Database("mint", "./test_data/mig_witness_cleanup") + + # Ensure schema is at latest so tables exist + await migrate_databases(db, mint_migrations) + + long_witness = "a" * 1025 + short_witness = "b" * 10 + + async with db.connect() as conn: + # Insert into proofs_used + await conn.execute( + f""" + INSERT INTO {db.table_with_schema('proofs_used')} (amount, id, c, secret, y, witness, created, melt_quote) + VALUES (1, 'kid', 'c_used_long', 's_used_long', 'y_used_long', :w, {db.timestamp_now}, NULL) + """, + {"w": long_witness}, + ) + await conn.execute( + f""" + INSERT INTO {db.table_with_schema('proofs_used')} (amount, id, c, secret, y, witness, created, melt_quote) + VALUES (1, 'kid', 'c_used_short', 's_used_short', 'y_used_short', :w, {db.timestamp_now}, NULL) + """, + {"w": short_witness}, + ) + + # Insert into proofs_pending + await conn.execute( + f""" + INSERT INTO {db.table_with_schema('proofs_pending')} (amount, id, c, secret, y, witness, created, melt_quote) + VALUES (1, 'kid', 'c_pend_long', 's_pend_long', 'y_pend_long', :w, {db.timestamp_now}, NULL) + """, + {"w": long_witness}, + ) + await conn.execute( + f""" + INSERT INTO {db.table_with_schema('proofs_pending')} (amount, id, c, secret, y, witness, created, melt_quote) + VALUES (1, 'kid', 'c_pend_short', 's_pend_short', 'y_pend_short', :w, {db.timestamp_now}, NULL) + """, + {"w": short_witness}, + ) + + # Run the migration under test directly + await mint_migrations.m029_remove_overlong_witness_values(db) + + # Validate cleanup + async with db.connect() as conn: + row = await conn.fetchone( + f"SELECT witness FROM {db.table_with_schema('proofs_used')} WHERE secret = 's_used_long'" + ) + assert row["witness"] is None + + row = await conn.fetchone( + f"SELECT witness FROM {db.table_with_schema('proofs_used')} WHERE secret = 's_used_short'" + ) + assert row["witness"] == short_witness + + row = await conn.fetchone( + f"SELECT witness FROM {db.table_with_schema('proofs_pending')} WHERE secret = 's_pend_long'" + ) + assert row["witness"] is None + + row = await conn.fetchone( + f"SELECT witness FROM {db.table_with_schema('proofs_pending')} WHERE secret = 's_pend_short'" + ) + assert row["witness"] == short_witness