@@ -1389,7 +1389,9 @@ async def add_hold_invoice(
13891389 ) -> dict :
13901390 """
13911391 Create a lightning hold invoice for the given payment hash. Hold invoices have to get settled manually later.
1392- HTLCs will get failed automatically if block_height + 144 > htlc.cltv_abs.
1392+ HTLCs will get failed automatically if block_height + 144 > htlc.cltv_abs, if the intention is to
1393+ settle them as late as possible a safety margin of some blocks should be used to prevent them
1394+ from getting failed accidentally.
13931395
13941396 arg:str:payment_hash:Hex encoded payment hash to be used for the invoice
13951397 arg:decimal:amount:Optional requested amount (in btc)
@@ -1399,7 +1401,7 @@ async def add_hold_invoice(
13991401 """
14001402 assert len (payment_hash ) == 64 , f"Invalid payment hash length: { len (payment_hash )} != 64"
14011403 assert payment_hash not in wallet .lnworker .payment_info , "Payment hash already used!"
1402- assert payment_hash not in wallet .lnworker .dont_settle_htlcs , "Payment hash already used!"
1404+ assert payment_hash not in wallet .lnworker .dont_expire_htlcs , "Payment hash already used!"
14031405 assert wallet .lnworker .get_preimage (bfh (payment_hash )) is None , "Already got a preimage for this payment hash!"
14041406 assert MIN_FINAL_CLTV_DELTA_ACCEPTED < min_final_cltv_expiry_delta < 576 , "Use a sane min_final_cltv_expiry_delta value"
14051407 amount = amount if amount and satoshis (amount ) > 0 else None # make amount either >0 or None
@@ -1419,7 +1421,9 @@ async def add_hold_invoice(
14191421 message = memo ,
14201422 fallback_address = None
14211423 )
1422- wallet .lnworker .dont_settle_htlcs [payment_hash ] = None
1424+ # this prevents incoming htlcs from getting expired while the preimage isn't set.
1425+ # If their blocks to expiry fall below MIN_FINAL_CLTV_DELTA_ACCEPTED they will get failed.
1426+ wallet .lnworker .dont_expire_htlcs [payment_hash ] = MIN_FINAL_CLTV_DELTA_ACCEPTED
14231427 wallet .set_label (payment_hash , memo )
14241428 result = {
14251429 "invoice" : invoice
@@ -1439,12 +1443,11 @@ async def settle_hold_invoice(self, preimage: str, wallet: Abstract_Wallet = Non
14391443 assert payment_hash not in wallet .lnworker ._preimages , f"Invoice { payment_hash = } already settled"
14401444 assert payment_hash in wallet .lnworker .payment_info , \
14411445 f"Couldn't find lightning invoice for { payment_hash = } "
1442- assert payment_hash in wallet .lnworker .dont_settle_htlcs , f"Invoice { payment_hash = } not a hold invoice?"
1446+ assert payment_hash in wallet .lnworker .dont_expire_htlcs , f"Invoice { payment_hash = } not a hold invoice?"
14431447 assert wallet .lnworker .is_complete_mpp (bfh (payment_hash )), \
14441448 f"MPP incomplete, cannot settle hold invoice { payment_hash } yet"
14451449 info : Optional ['PaymentInfo' ] = wallet .lnworker .get_payment_info (bfh (payment_hash ))
14461450 assert (wallet .lnworker .get_payment_mpp_amount_msat (bfh (payment_hash )) or 0 ) >= (info .amount_msat or 0 )
1447- del wallet .lnworker .dont_settle_htlcs [payment_hash ]
14481451 wallet .lnworker .save_preimage (bfh (payment_hash ), bfh (preimage ))
14491452 util .trigger_callback ('wallet_updated' , wallet )
14501453 result = {
@@ -1462,15 +1465,15 @@ async def cancel_hold_invoice(self, payment_hash: str, wallet: Abstract_Wallet =
14621465 assert payment_hash in wallet .lnworker .payment_info , \
14631466 f"Couldn't find lightning invoice for payment hash { payment_hash } "
14641467 assert payment_hash not in wallet .lnworker ._preimages , "Cannot cancel anymore, preimage already given."
1465- assert payment_hash in wallet .lnworker .dont_settle_htlcs , f"{ payment_hash = } not a hold invoice?"
1468+ assert payment_hash in wallet .lnworker .dont_expire_htlcs , f"{ payment_hash = } not a hold invoice?"
14661469 # set to PR_UNPAID so it can get deleted
14671470 wallet .lnworker .set_payment_status (bfh (payment_hash ), PR_UNPAID )
14681471 wallet .lnworker .delete_payment_info (payment_hash )
14691472 wallet .set_label (payment_hash , None )
1473+ del wallet .lnworker .dont_expire_htlcs [payment_hash ]
14701474 while wallet .lnworker .is_complete_mpp (bfh (payment_hash )):
1471- # wait until the htlcs got failed so the payment won't get settled accidentally in a race
1475+ # block until the htlcs got failed
14721476 await asyncio .sleep (0.1 )
1473- del wallet .lnworker .dont_settle_htlcs [payment_hash ]
14741477 result = {
14751478 "cancelled" : payment_hash
14761479 }
@@ -1503,15 +1506,14 @@ async def check_hold_invoice(self, payment_hash: str, wallet: Abstract_Wallet =
15031506 elif not is_complete_mpp and not wallet .lnworker .get_preimage_hex (payment_hash ):
15041507 # is_complete_mpp is False for settled payments
15051508 result ["status" ] = "unpaid"
1506- elif is_complete_mpp and payment_hash in wallet .lnworker .dont_settle_htlcs :
1509+ elif is_complete_mpp and payment_hash in wallet .lnworker .dont_expire_htlcs :
15071510 result ["status" ] = "paid"
15081511 payment_key : str = wallet .lnworker ._get_payment_key (bfh (payment_hash )).hex ()
15091512 htlc_status = wallet .lnworker .received_mpp_htlcs [payment_key ]
15101513 result ["closest_htlc_expiry_height" ] = min (
1511- htlc .cltv_abs for _ , htlc in htlc_status .htlc_set
1514+ mpp_htlc . htlc .cltv_abs for mpp_htlc in htlc_status .htlcs
15121515 )
1513- elif wallet .lnworker .get_preimage_hex (payment_hash ) is not None \
1514- and payment_hash not in wallet .lnworker .dont_settle_htlcs :
1516+ elif wallet .lnworker .get_preimage_hex (payment_hash ) is not None :
15151517 result ["status" ] = "settled"
15161518 plist = wallet .lnworker .get_payments (status = 'settled' )[bfh (payment_hash )]
15171519 _dir , amount_msat , _fee , _ts = wallet .lnworker .get_payment_value (info , plist )
0 commit comments