electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit beeb81e179143795546a8c67a376754111824a22
parent e54f0fbafa502589a4f197245e46545feeb73a12
Author: SomberNight <somber.night@protonmail.com>
Date:   Fri, 16 Aug 2019 22:44:07 +0200

lnpeer: use correct failure codes in _maybe_forward_htlc

Diffstat:
Melectrum/lnpeer.py | 26+++++++++++++++++---------
Melectrum/lnrouter.py | 10++++++++--
Melectrum/lnutil.py | 2++
3 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py @@ -46,6 +46,7 @@ from .lnutil import FeeUpdate from .lntransport import LNTransport, LNTransportBase from .lnmsg import encode_msg, decode_msg from .interface import GracefulDisconnect, NetworkException +from .lnrouter import fee_for_edge_msat if TYPE_CHECKING: from .lnworker import LNWorker @@ -1290,22 +1291,25 @@ class Peer(Logger): reason = OnionRoutingFailureMessage(code=OnionFailureCode.UNKNOWN_NEXT_PEER, data=b'') await self.fail_htlc(chan, htlc.htlc_id, onion_packet, reason) return + outgoing_chan_upd = self.get_outgoing_gossip_channel_update_for_chan(next_chan)[2:] + outgoing_chan_upd_len = len(outgoing_chan_upd).to_bytes(2, byteorder="big") if next_chan.get_state() != 'OPEN': self.logger.info(f"cannot forward htlc. next_chan not OPEN: {next_chan_scid} in state {next_chan.get_state()}") - #reason = OnionRoutingFailureMessage(code=OnionFailureCode.TEMPORARY_CHANNEL_FAILURE, data=) # FIXME data - reason = OnionRoutingFailureMessage(code=OnionFailureCode.TEMPORARY_NODE_FAILURE, data=b'') + reason = OnionRoutingFailureMessage(code=OnionFailureCode.TEMPORARY_CHANNEL_FAILURE, + data=outgoing_chan_upd_len+outgoing_chan_upd) await self.fail_htlc(chan, htlc.htlc_id, onion_packet, reason) return next_cltv_expiry = int.from_bytes(dph.outgoing_cltv_value, 'big') if htlc.cltv_expiry - next_cltv_expiry < NBLOCK_OUR_CLTV_EXPIRY_DELTA: - #reason = OnionRoutingFailureMessage(code=OnionFailureCode.INCORRECT_CLTV_EXPIRY, data=) # FIXME data - reason = OnionRoutingFailureMessage(code=OnionFailureCode.TEMPORARY_NODE_FAILURE, data=b'') + reason = OnionRoutingFailureMessage(code=OnionFailureCode.INCORRECT_CLTV_EXPIRY, + data=(htlc.cltv_expiry.to_bytes(4, byteorder="big") + + outgoing_chan_upd_len + outgoing_chan_upd)) await self.fail_htlc(chan, htlc.htlc_id, onion_packet, reason) return if htlc.cltv_expiry - lnutil.NBLOCK_DEADLINE_BEFORE_EXPIRY_FOR_RECEIVED_HTLCS <= local_height \ or next_cltv_expiry <= local_height: - #reason = OnionRoutingFailureMessage(code=OnionFailureCode.EXPIRY_TOO_SOON, data=) # FIXME data - reason = OnionRoutingFailureMessage(code=OnionFailureCode.TEMPORARY_NODE_FAILURE, data=b'') + reason = OnionRoutingFailureMessage(code=OnionFailureCode.EXPIRY_TOO_SOON, + data=outgoing_chan_upd_len+outgoing_chan_upd) await self.fail_htlc(chan, htlc.htlc_id, onion_packet, reason) return if max(htlc.cltv_expiry, next_cltv_expiry) > local_height + lnutil.NBLOCK_CLTV_EXPIRY_TOO_FAR_INTO_FUTURE: @@ -1313,9 +1317,13 @@ class Peer(Logger): await self.fail_htlc(chan, htlc.htlc_id, onion_packet, reason) return next_amount_msat_htlc = int.from_bytes(dph.amt_to_forward, 'big') - if htlc.amount_msat - next_amount_msat_htlc < 0: # TODO fees? - # reason = OnionRoutingFailureMessage(code=OnionFailureCode.FEE_INSUFFICIENT, data=) # FIXME data - reason = OnionRoutingFailureMessage(code=OnionFailureCode.TEMPORARY_NODE_FAILURE, data=b'') + forwarding_fees = fee_for_edge_msat(forwarded_amount_msat=next_amount_msat_htlc, + fee_base_msat=lnutil.OUR_FEE_BASE_MSAT, + fee_proportional_millionths=lnutil.OUR_FEE_PROPORTIONAL_MILLIONTHS) + if htlc.amount_msat - next_amount_msat_htlc < forwarding_fees: + reason = OnionRoutingFailureMessage(code=OnionFailureCode.FEE_INSUFFICIENT, + data=(next_amount_msat_htlc.to_bytes(8, byteorder="big") + + outgoing_chan_upd_len + outgoing_chan_upd)) await self.fail_htlc(chan, htlc.htlc_id, onion_packet, reason) return diff --git a/electrum/lnrouter.py b/electrum/lnrouter.py @@ -41,6 +41,11 @@ class NoChannelPolicy(Exception): super().__init__(f'cannot find channel policy for short_channel_id: {bh2u(short_channel_id)}') +def fee_for_edge_msat(forwarded_amount_msat: int, fee_base_msat: int, fee_proportional_millionths: int) -> int: + return fee_base_msat \ + + (forwarded_amount_msat * fee_proportional_millionths // 1_000_000) + + class RouteEdge(NamedTuple("RouteEdge", [('node_id', bytes), ('short_channel_id', bytes), ('fee_base_msat', int), @@ -49,8 +54,9 @@ class RouteEdge(NamedTuple("RouteEdge", [('node_id', bytes), """if you travel through short_channel_id, you will reach node_id""" def fee_for_edge(self, amount_msat: int) -> int: - return self.fee_base_msat \ - + (amount_msat * self.fee_proportional_millionths // 1_000_000) + return fee_for_edge_msat(forwarded_amount_msat=amount_msat, + fee_base_msat=self.fee_base_msat, + fee_proportional_millionths=self.fee_proportional_millionths) @classmethod def from_channel_policy(cls, channel_policy: 'Policy', diff --git a/electrum/lnutil.py b/electrum/lnutil.py @@ -137,6 +137,8 @@ NBLOCK_DEADLINE_BEFORE_EXPIRY_FOR_RECEIVED_HTLCS = 72 # the cltv_expiry_delta for channels when we are forwarding payments NBLOCK_OUR_CLTV_EXPIRY_DELTA = 144 +OUR_FEE_BASE_MSAT = 1000 +OUR_FEE_PROPORTIONAL_MILLIONTHS = 1 NBLOCK_CLTV_EXPIRY_TOO_FAR_INTO_FUTURE = 4032