URI: 
       ttrampoline MPP: fix total_msat in trampoline onion, and bucketing - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit ba4d6bc8b34d17a998c011276ef57aab7f0c5106
   DIR parent 253907fb606f131a9cbd76743b137d744421b2f3
  HTML Author: ThomasV <thomasv@electrum.org>
       Date:   Thu,  4 Mar 2021 10:05:09 +0100
       
       ttrampoline MPP: fix total_msat in trampoline onion, and bucketing
       
       Diffstat:
         M electrum/lnworker.py                |      27 +++++++++++++++------------
         M electrum/trampoline.py              |      24 +++++++++++-------------
       
       2 files changed, 26 insertions(+), 25 deletions(-)
       ---
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -1145,7 +1145,10 @@ class LNWallet(LNWorker):
        
                key = (payment_hash, short_channel_id, htlc.htlc_id)
                self.sent_htlcs_routes[key] = route, payment_secret, amount_msat, total_msat
       -        self.sent_buckets[payment_secret] = total_msat
       +        # if we sent MPP to a trampoline, add item to sent_buckets
       +        if not self.channel_db and amount_msat != total_msat:
       +            if payment_secret not in self.sent_buckets:
       +                self.sent_buckets[payment_secret] = total_msat
                util.trigger_callback('htlc_added', chan, htlc, SENT)
        
            def handle_error_code_from_failed_htlc(self, htlc_log):
       t@@ -1299,7 +1302,6 @@ class LNWallet(LNWorker):
                    payment_hash,
                    payment_secret,
                    full_path: LNPaymentPath = None) -> Sequence[Tuple[LNPaymentRoute, int]]:
       -        # FIXME trampoline case broken if amount_msat != final_total_msat
        
                """Creates multiple routes for splitting a payment over the available
                private channels.
       t@@ -1323,7 +1325,7 @@ class LNWallet(LNWorker):
                                continue
                            trampoline_onion, trampoline_fee, amount_with_fees, cltv_delta = create_trampoline_route_and_onion(
                                amount_msat=amount_msat,
       -                        bucket_amount_msat=amount_msat,
       +                        total_msat=final_total_msat,
                                min_cltv_expiry=min_cltv_expiry,
                                my_pubkey=self.node_keypair.pubkey,
                                invoice_pubkey=invoice_pubkey,
       t@@ -1387,8 +1389,8 @@ class LNWallet(LNWorker):
                                for node_id, bucket in buckets.items():
                                    bucket_amount_msat = sum([x[1] for x in bucket])
                                    trampoline_onion, trampoline_fee, bucket_amount_with_fees, bucket_cltv_delta = create_trampoline_route_and_onion(
       -                                amount_msat=amount_msat,
       -                                bucket_amount_msat=bucket_amount_msat,
       +                                amount_msat=bucket_amount_msat,
       +                                total_msat=final_total_msat,
                                        min_cltv_expiry=min_cltv_expiry,
                                        my_pubkey=self.node_keypair.pubkey,
                                        invoice_pubkey=invoice_pubkey,
       t@@ -1707,13 +1709,14 @@ class LNWallet(LNWorker):
                        sender_idx = None
                    self.logger.info(f"htlc_failed {failure_message}")
        
       -            # FIXME: maybe only check this bucketing stuff if not using trampoline?
       -            # if payment_secret in self.sent_buckets:
       -            #     self.sent_buckets[payment_secret] -= amount_msat
       -            #     if self.sent_buckets[payment_secret] > 0:
       -            #         return
       -            #     else:
       -            #         amount_msat = bucket_msat
       +            # check sent_buckets if we use trampoline
       +            if self.channel_db is None and payment_secret in self.sent_buckets:
       +                self.sent_buckets[payment_secret] -= amount_msat
       +                if self.sent_buckets[payment_secret] > 0:
       +                    return
       +                else:
       +                    amount_msat = bucket_msat
       +
                    htlc_log = HtlcLog(
                        success=False,
                        route=route,
   DIR diff --git a/electrum/trampoline.py b/electrum/trampoline.py
       t@@ -63,7 +63,6 @@ def encode_routing_info(r_tags):
        def create_trampoline_route(
                *,
                amount_msat:int,
       -        bucket_amount_msat:int,
                min_cltv_expiry:int,
                invoice_pubkey:bytes,
                invoice_features:int,
       t@@ -161,7 +160,7 @@ def create_trampoline_route(
            return route
        
        
       -def create_trampoline_onion(route, amount_msat, final_cltv, total_msat, payment_hash, payment_secret):
       +def create_trampoline_onion(*, route, amount_msat, final_cltv, total_msat, payment_hash, payment_secret):
            # all edges are trampoline
            hops_data, amount_msat, cltv = calc_hops_data_for_payment(
                route,
       t@@ -196,7 +195,7 @@ def create_trampoline_onion(route, amount_msat, final_cltv, total_msat, payment_
        def create_trampoline_route_and_onion(
                *,
                amount_msat,
       -        bucket_amount_msat,
       +        total_msat,
                min_cltv_expiry,
                invoice_pubkey,
                invoice_features,
       t@@ -211,7 +210,6 @@ def create_trampoline_route_and_onion(
            # create route for the trampoline_onion
            trampoline_route = create_trampoline_route(
                amount_msat=amount_msat,
       -        bucket_amount_msat=bucket_amount_msat,
                min_cltv_expiry=min_cltv_expiry,
                my_pubkey=my_pubkey,
                invoice_pubkey=invoice_pubkey,
       t@@ -223,15 +221,15 @@ def create_trampoline_route_and_onion(
                trampoline2_list=trampoline2_list)
            # compute onion and fees
            final_cltv = local_height + min_cltv_expiry
       -    trampoline_onion, bucket_amount_with_fees, bucket_cltv = create_trampoline_onion(
       -        trampoline_route,
       -        bucket_amount_msat,
       -        final_cltv,
       -        amount_msat,
       -        payment_hash,
       -        payment_secret)
       +    trampoline_onion, amount_with_fees, bucket_cltv = create_trampoline_onion(
       +        route=trampoline_route,
       +        amount_msat=amount_msat,
       +        final_cltv=final_cltv,
       +        total_msat=total_msat,
       +        payment_hash=payment_hash,
       +        payment_secret=payment_secret)
            bucket_cltv_delta = bucket_cltv - local_height
            bucket_cltv_delta += trampoline_route[0].cltv_expiry_delta
            # trampoline fee for this very trampoline
       -    trampoline_fee = trampoline_route[0].fee_for_edge(bucket_amount_with_fees)
       -    return trampoline_onion, trampoline_fee, bucket_amount_with_fees, bucket_cltv_delta
       +    trampoline_fee = trampoline_route[0].fee_for_edge(amount_with_fees)
       +    return trampoline_onion, trampoline_fee, amount_with_fees, bucket_cltv_delta