Browse Source

lnworker: amount passed in HtlcLog must be without fees

master
ThomasV 5 years ago
parent
commit
693583edc5
  1. 6
      electrum/lnchannel.py
  2. 11
      electrum/lnworker.py
  3. 12
      electrum/tests/test_lnpeer.py

6
electrum/lnchannel.py

@ -993,7 +993,7 @@ class Channel(AbstractChannel):
if self.lnworker: if self.lnworker:
sent = self.hm.sent_in_ctn(new_ctn) sent = self.hm.sent_in_ctn(new_ctn)
for htlc in sent: for htlc in sent:
self.lnworker.htlc_fulfilled(self, htlc.payment_hash, htlc.htlc_id, htlc.amount_msat) self.lnworker.htlc_fulfilled(self, htlc.payment_hash, htlc.htlc_id)
failed = self.hm.failed_in_ctn(new_ctn) failed = self.hm.failed_in_ctn(new_ctn)
for htlc in failed: for htlc in failed:
try: try:
@ -1004,7 +1004,7 @@ class Channel(AbstractChannel):
if self.lnworker.get_payment_info(htlc.payment_hash) is None: if self.lnworker.get_payment_info(htlc.payment_hash) is None:
self.save_fail_htlc_reason(htlc.htlc_id, error_bytes, failure_message) self.save_fail_htlc_reason(htlc.htlc_id, error_bytes, failure_message)
else: else:
self.lnworker.htlc_failed(self, htlc.payment_hash, htlc.htlc_id, htlc.amount_msat, error_bytes, failure_message) self.lnworker.htlc_failed(self, htlc.payment_hash, htlc.htlc_id, error_bytes, failure_message)
def save_fail_htlc_reason( def save_fail_htlc_reason(
self, self,
@ -1049,7 +1049,7 @@ class Channel(AbstractChannel):
info = self.lnworker.get_payment_info(payment_hash) info = self.lnworker.get_payment_info(payment_hash)
if info is not None and info.status != PR_PAID: if info is not None and info.status != PR_PAID:
if is_sent: if is_sent:
self.lnworker.htlc_fulfilled(self, payment_hash, htlc.htlc_id, htlc.amount_msat) self.lnworker.htlc_fulfilled(self, payment_hash, htlc.htlc_id)
else: else:
# FIXME # FIXME
#self.lnworker.htlc_received(self, payment_hash) #self.lnworker.htlc_received(self, payment_hash)

11
electrum/lnworker.py

@ -658,7 +658,7 @@ class LNWallet(LNWorker):
self._channels[bfh(channel_id)] = Channel(c, sweep_address=self.sweep_address, lnworker=self) self._channels[bfh(channel_id)] = Channel(c, sweep_address=self.sweep_address, lnworker=self)
self.sent_htlcs = defaultdict(asyncio.Queue) # type: Dict[bytes, asyncio.Queue[HtlcLog]] self.sent_htlcs = defaultdict(asyncio.Queue) # type: Dict[bytes, asyncio.Queue[HtlcLog]]
self.sent_htlcs_routes = dict() # (RHASH, scid, htlc_id) -> route self.sent_htlcs_routes = dict() # (RHASH, scid, htlc_id) -> route, amount_for_receiver
self.received_htlcs = dict() # RHASH -> mpp_status, htlc_set self.received_htlcs = dict() # RHASH -> mpp_status, htlc_set
self.swap_manager = SwapManager(wallet=self.wallet, lnworker=self) self.swap_manager = SwapManager(wallet=self.wallet, lnworker=self)
@ -1166,7 +1166,7 @@ class LNWallet(LNWorker):
min_final_cltv_expiry=min_cltv_expiry, min_final_cltv_expiry=min_cltv_expiry,
payment_secret=payment_secret, payment_secret=payment_secret,
fwd_trampoline_onion=trampoline_onion) fwd_trampoline_onion=trampoline_onion)
self.sent_htlcs_routes[(payment_hash, short_channel_id, htlc.htlc_id)] = route self.sent_htlcs_routes[(payment_hash, short_channel_id, htlc.htlc_id)] = route, amount_msat
util.trigger_callback('htlc_added', chan, htlc, SENT) util.trigger_callback('htlc_added', chan, htlc, SENT)
def handle_error_code_from_failed_htlc(self, htlc_log): def handle_error_code_from_failed_htlc(self, htlc_log):
@ -1739,11 +1739,11 @@ class LNWallet(LNWorker):
info = info._replace(status=status) info = info._replace(status=status)
self.save_payment_info(info) self.save_payment_info(info)
def htlc_fulfilled(self, chan, payment_hash: bytes, htlc_id:int, amount_msat:int): def htlc_fulfilled(self, chan, payment_hash: bytes, htlc_id:int):
util.trigger_callback('htlc_fulfilled', payment_hash, chan.channel_id) util.trigger_callback('htlc_fulfilled', payment_hash, chan.channel_id)
q = self.sent_htlcs.get(payment_hash) q = self.sent_htlcs.get(payment_hash)
if q: if q:
route = self.sent_htlcs_routes[(payment_hash, chan.short_channel_id, htlc_id)] route, amount_msat = self.sent_htlcs_routes[(payment_hash, chan.short_channel_id, htlc_id)]
htlc_log = HtlcLog( htlc_log = HtlcLog(
success=True, success=True,
route=route, route=route,
@ -1759,14 +1759,13 @@ class LNWallet(LNWorker):
chan: Channel, chan: Channel,
payment_hash: bytes, payment_hash: bytes,
htlc_id: int, htlc_id: int,
amount_msat:int,
error_bytes: Optional[bytes], error_bytes: Optional[bytes],
failure_message: Optional['OnionRoutingFailure']): failure_message: Optional['OnionRoutingFailure']):
util.trigger_callback('htlc_failed', payment_hash, chan.channel_id) util.trigger_callback('htlc_failed', payment_hash, chan.channel_id)
q = self.sent_htlcs.get(payment_hash) q = self.sent_htlcs.get(payment_hash)
if q: if q:
route = self.sent_htlcs_routes[(payment_hash, chan.short_channel_id, htlc_id)] route, amount_msat = self.sent_htlcs_routes[(payment_hash, chan.short_channel_id, htlc_id)]
if error_bytes: if error_bytes:
# TODO "decode_onion_error" might raise, catch and maybe blacklist/penalise someone? # TODO "decode_onion_error" might raise, catch and maybe blacklist/penalise someone?
try: try:

12
electrum/tests/test_lnpeer.py

@ -134,7 +134,7 @@ class MockLNWallet(Logger, NetworkRetryManager[LNPeerAddr]):
self.enable_htlc_settle.set() self.enable_htlc_settle.set()
self.received_htlcs = dict() self.received_htlcs = dict()
self.sent_htlcs = defaultdict(asyncio.Queue) self.sent_htlcs = defaultdict(asyncio.Queue)
self.sent_htlcs_routes = defaultdict(list) self.sent_htlcs_routes = dict()
def get_invoice_status(self, key): def get_invoice_status(self, key):
pass pass
@ -498,26 +498,24 @@ class TestPeer(ElectrumTestCase):
# alice sends htlc BUT NOT COMMITMENT_SIGNED # alice sends htlc BUT NOT COMMITMENT_SIGNED
p1.maybe_send_commitment = lambda x: None p1.maybe_send_commitment = lambda x: None
route1, amount_msat1 = w1.create_routes_from_invoice(lnaddr2.get_amount_msat(), decoded_invoice=lnaddr2)[0] route1, amount_msat1 = w1.create_routes_from_invoice(lnaddr2.get_amount_msat(), decoded_invoice=lnaddr2)[0]
p1.pay( await w1.pay_to_route(
route=route1, route=route1,
chan=alice_channel,
amount_msat=lnaddr2.get_amount_msat(), amount_msat=lnaddr2.get_amount_msat(),
total_msat=lnaddr2.get_amount_msat(), total_msat=lnaddr2.get_amount_msat(),
payment_hash=lnaddr2.paymenthash, payment_hash=lnaddr2.paymenthash,
min_final_cltv_expiry=lnaddr2.get_min_final_cltv_expiry(), min_cltv_expiry=lnaddr2.get_min_final_cltv_expiry(),
payment_secret=lnaddr2.payment_secret, payment_secret=lnaddr2.payment_secret,
) )
p1.maybe_send_commitment = _maybe_send_commitment1 p1.maybe_send_commitment = _maybe_send_commitment1
# bob sends htlc BUT NOT COMMITMENT_SIGNED # bob sends htlc BUT NOT COMMITMENT_SIGNED
p2.maybe_send_commitment = lambda x: None p2.maybe_send_commitment = lambda x: None
route2, amount_msat2 = w2.create_routes_from_invoice(lnaddr1.get_amount_msat(), decoded_invoice=lnaddr1)[0] route2, amount_msat2 = w2.create_routes_from_invoice(lnaddr1.get_amount_msat(), decoded_invoice=lnaddr1)[0]
p2.pay( await w2.pay_to_route(
route=route2, route=route2,
chan=bob_channel,
amount_msat=lnaddr1.get_amount_msat(), amount_msat=lnaddr1.get_amount_msat(),
total_msat=lnaddr1.get_amount_msat(), total_msat=lnaddr1.get_amount_msat(),
payment_hash=lnaddr1.paymenthash, payment_hash=lnaddr1.paymenthash,
min_final_cltv_expiry=lnaddr1.get_min_final_cltv_expiry(), min_cltv_expiry=lnaddr1.get_min_final_cltv_expiry(),
payment_secret=lnaddr1.payment_secret, payment_secret=lnaddr1.payment_secret,
) )
p2.maybe_send_commitment = _maybe_send_commitment2 p2.maybe_send_commitment = _maybe_send_commitment2

Loading…
Cancel
Save