Skip to content

Commit

Permalink
fix for out of spec debts map
Browse files Browse the repository at this point in the history
  • Loading branch information
lollerfirst committed Sep 14, 2024
1 parent 52729b2 commit 231eb25
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 28 deletions.
34 changes: 10 additions & 24 deletions cashu/mint/db/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,14 @@ async def _settle_dlc(
raise DlcSettlementFail(detail="No DLC with this root hash")
if dlc.settled is True:
raise DlcSettlementFail(detail="DLC already settled")

assert settlement.outcome
await self.crud.set_dlc_settled_and_debts(settlement.dlc_root, settlement.outcome.P, self.db, conn)

# Calculate debts map
weights = json.loads(settlement.outcome.P)
weight_sum = sum(weights.values())
debts = dict(((pubkey, dlc.funding_amount * weight // weight_sum) for pubkey, weight in weights.items()))

await self.crud.set_dlc_settled_and_debts(settlement.dlc_root, json.dumps(debts), self.db, conn)
settled.append(DlcSettlementAck(dlc_root=settlement.dlc_root))
except (CashuError, Exception) as e:
errors.append(DlcSettlementError(
Expand Down Expand Up @@ -366,36 +371,17 @@ async def _verify_and_update_dlc_payouts(

# We have already checked the amounts before, so we just sum them
blind_messages_amount = sum([b.amount for b in payout.outputs])
denom = sum(dlc.debts.values())
nom = dlc.debts[payout.pubkey]
eligible_amount = int(nom / denom * dlc.funding_amount)
eligible_amount = dlc.debts[payout.pubkey]

# Verify the amount of the blind messages is LEQ than the eligible amount
if blind_messages_amount > eligible_amount:
raise DlcPayoutFail(detail=f"amount requested ({blind_messages_amount}) is bigger than eligible amount ({eligible_amount})")

# Discriminate what to do next based on whether the requested amount is exact or less
if blind_messages_amount == eligible_amount:
# Simply remove the entry
if blind_messages_amount == eligible_amount:
del dlc.debts[payout.pubkey]
else:
# Get a new weight for dlc.debts[payout.pubkey]
# e == eligible_amount, b = blind_messages_amount
# f == funding_amount
# e - b > 0
# fx / (x + y + z) == e - b
# fx == (e - b)*(x + y + z)
# fx == (ex + ey + ez - bx - by - bz)
# fx - ex + bx == (ey + ez - by - bz)
# x*(f-e+b) == ey + ez - by - bz
# x == (ey + ez - by - bz) / (f-e+b)
# x == (e*(y+z) - b*(y+z)) / (f-e+b)
w = int((eligible_amount*denom - blind_messages_amount*denom)
/ (dlc.funding_amount-eligible_amount+blind_messages_amount))
if w > 0:
dlc.debts[payout.pubkey] = w
else:
del dlc.debts[payout.pubkey]
dlc.debts[payout.pubkey] -= blind_messages_amount

await self.crud.set_dlc_settled_and_debts(dlc.dlc_root, json.dumps(dlc.debts), self.db, conn)
verified.append(payout)
Expand Down
2 changes: 2 additions & 0 deletions cashu/mint/dlc.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from typing import Dict
import json

from ..core.base import DlcSettlement
from ..core.errors import TransactionError
from ..core.nuts import DLC_NUT
from .features import LedgerFeatures
Expand Down
4 changes: 3 additions & 1 deletion cashu/mint/ledger.py
Original file line number Diff line number Diff line change
Expand Up @@ -1232,12 +1232,14 @@ async def settle_dlc(self, request: PostDlcSettleRequest) -> PostDlcSettleRespon
try:
# Verify inclusion of payout structure and associated attestation in the DLC
assert settlement.outcome and settlement.merkle_proof, "outcome or merkle proof not provided"
await self._verify_dlc_payout(settlement.outcome.P)
await self._verify_dlc_inclusion(settlement.dlc_root, settlement.outcome, settlement.merkle_proof)

verified.append(settlement)
except (DlcSettlementFail, AssertionError) as e:
errors.append(DlcSettlementError(
dlc_root=settlement.dlc_root,
details=e.detail if isinstance(e, DlcSettlementFail) else str(e)
details=str(e)
))
# Database dance:
settled, db_errors = await self.db_write._settle_dlc(verified)
Expand Down
3 changes: 0 additions & 3 deletions cashu/mint/verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,9 +446,6 @@ async def _verify_dlc_payout(self, P: str):
raise DlcSettlementFail(detail="cannot decode the provided payout structure")

async def _verify_dlc_inclusion(self, dlc_root: str, outcome: DlcOutcome, merkle_proof: List[str]):
# Verify payout structure
await self._verify_dlc_payout(outcome.P)

dlc_root_bytes = None
merkle_proof_bytes = None
P = outcome.P.encode("utf-8")
Expand Down

0 comments on commit 231eb25

Please sign in to comment.