From cb7eea28d3f5e0ae19aab24f008c1604adfd5ace Mon Sep 17 00:00:00 2001 From: lollerfirst Date: Fri, 2 Aug 2024 15:09:15 +0200 Subject: [PATCH] better threshold check + test --- cashu/mint/verification.py | 20 ++++++++++++++++++-- tests/test_dlc.py | 27 ++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/cashu/mint/verification.py b/cashu/mint/verification.py index 9f98ced9..fd0f87f2 100644 --- a/cashu/mint/verification.py +++ b/cashu/mint/verification.py @@ -346,11 +346,27 @@ async def _verify_dlc_amount_threshold(self, funding_amount: int, proofs: List[P """For every SCT proof verify that secret's threshold is less or equal to the funding_amount """ + def raise_if_err(err): + if len(err) > 0: + logger.error("Failed to verify DLC inputs") + raise DlcVerificationFail(bad_inputs=err) sct_proofs, _ = await self.filter_sct_proofs(proofs) dlc_witnesses = [DLCWitness.from_witness(p.witness or "") for p in sct_proofs] dlc_secrets = [Secret.deserialize(w.leaf_secret) for w in dlc_witnesses] - if not all([int(s.tags.get_tag('threshold')) <= funding_amount for s in dlc_secrets]): - raise TransactionError("Some inputs' funding thresholds were not met") + errors = [] + for i, s in enumerate(dlc_secrets): + if s.tags.get_tag('threshold') is not None: + threshold = None + try: + threshold = int(s.tags.get_tag('threshold')) + except Exception: + pass + if threshold is not None and funding_amount < threshold: + errors.append(DlcBadInput( + index=i, + detail="Threshold amount not respected" + )) + raise_if_err(errors) async def _verify_dlc_inputs( self, diff --git a/tests/test_dlc.py b/tests/test_dlc.py index 5d4471fd..275acb99 100644 --- a/tests/test_dlc.py +++ b/tests/test_dlc.py @@ -337,6 +337,31 @@ async def test_registration_dlc_locked_proofs(wallet: Wallet, ledger: Ledger): "Could not verify funding proof" ) +@pytest.mark.asyncio +async def test_registration_threshold(wallet: Wallet, ledger: Ledger): + invoice = await wallet.request_mint(64) + await pay_if_regtest(invoice.bolt11) + minted = await wallet.mint(64, id=invoice.id) + + # Get locked proofs + dlc_root = sha256("TESTING".encode()).hexdigest() + _, locked = await wallet.split(minted, 64, dlc_data=(dlc_root, 128)) + assert len(_) == 0 + + # Add witnesses to proofs + locked = await wallet.add_sct_witnesses_to_proofs(locked) + + dlc = DiscreetLogContract( + funding_amount=64, + unit="sat", + dlc_root=dlc_root, + inputs=locked, + ) + + request = PostDlcRegistrationRequest(registrations=[dlc]) + response = await ledger.register_dlc(request) + assert response.errors and response.errors[0].bad_inputs[0].detail == "Threshold amount not respected" + @pytest.mark.asyncio async def test_fund_same_dlc_twice(wallet: Wallet, ledger: Ledger): invoice = await wallet.request_mint(128) @@ -412,5 +437,5 @@ async def test_get_dlc_status(wallet: Wallet, ledger: Ledger): response.settled == False and response.funding_amount == 128 and response.unit == "sat", - f"GetDlcStatusResponse did not respect the format" + f"GetDlcStatusResponse with unexpected fields" ) \ No newline at end of file