From 6304e81c525a23248748bf3f10619f925794cf04 Mon Sep 17 00:00:00 2001 From: BhaagBodeDK Date: Thu, 25 Aug 2022 15:51:45 +0000 Subject: [PATCH 01/87] #124 Show inflight htlc route --- gui/templates/pending_htlcs.html | 4 ++-- gui/views.py | 11 +++++++++-- jobs.py | 8 ++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/gui/templates/pending_htlcs.html b/gui/templates/pending_htlcs.html index babce0e5..b32b572a 100644 --- a/gui/templates/pending_htlcs.html +++ b/gui/templates/pending_htlcs.html @@ -23,7 +23,7 @@

Outgoing HTLCs

{% if htlc.forwarding_alias == '' %}---{% else %}{{ htlc.forwarding_alias }}{% endif %} {{ htlc.amount|intcomma }} {{ htlc.hours_til_expiration }} hours - {{ htlc.hash_lock }} + {{ htlc.hash_lock }} {% endfor %} @@ -50,7 +50,7 @@

Incoming HTLCs

{% if htlc.forwarding_alias == '' %}---{% else %}{{ htlc.forwarding_alias }}{% endif %} {{ htlc.amount|intcomma }} {{ htlc.hours_til_expiration }} hours - {{ htlc.hash_lock }} + {{ htlc.hash_lock }} {% endfor %} diff --git a/gui/views.py b/gui/views.py index 559c504d..910ba1d8 100644 --- a/gui/views.py +++ b/gui/views.py @@ -1259,7 +1259,14 @@ def channel(request): 'graph_links': graph_links(), 'network_links': network_links() } - return render(request, 'channel.html', context) + try: + return render(request, 'channel.html', context) + except Exception as e: + try: + error = str(e.code()) + except: + error = str(e) + return render(request, 'error.html', {'error': error}) else: return redirect('home') @@ -1369,7 +1376,7 @@ def failed_htlcs(request): def payments(request): if request.method == 'GET': context = { - 'payments': Payments.objects.filter(status=2).annotate(ppm=Round((Sum('fee')*1000000)/Sum('value'), output_field=IntegerField())).order_by('-creation_date')[:150], + 'payments': Payments.objects.exclude(status=3).annotate(ppm=Round((Sum('fee')*1000000)/Sum('value'), output_field=IntegerField())).order_by('-creation_date')[:150], } return render(request, 'payments.html', context) else: diff --git a/jobs.py b/jobs.py index 987099f8..49091015 100644 --- a/jobs.py +++ b/jobs.py @@ -31,9 +31,9 @@ def update_payments(stub): try: new_payment = Payments(creation_date=datetime.fromtimestamp(payment.creation_date), payment_hash=payment.payment_hash, value=round(payment.value_msat/1000, 3), fee=round(payment.fee_msat/1000, 3), status=payment.status, index=payment.payment_index) new_payment.save() - if payment.status == 2: + if payment.status == 2 or payment.status == 1: for attempt in payment.htlcs: - if attempt.status == 1: + if attempt.status == 1 or attempt.status == 0: hops = attempt.route.hops hop_count = 0 cost_to = 0 @@ -74,10 +74,10 @@ def update_payment(stub, payment, self_pubkey): db_payment.status = payment.status db_payment.index = payment.payment_index db_payment.save() - if payment.status == 2: + if payment.status == 2 or payment.status == 1: PaymentHops.objects.filter(payment_hash=db_payment).delete() for attempt in payment.htlcs: - if attempt.status == 1: + if attempt.status == 1 or attempt.status == 0: hops = attempt.route.hops hop_count = 0 cost_to = 0 From 9438791b5cc411cc8a4eaac2a2a46c62575e640f Mon Sep 17 00:00:00 2001 From: BhaagBodeDK Date: Thu, 25 Aug 2022 16:52:01 +0000 Subject: [PATCH 02/87] 124 Ignore inflight payments before 30 days --- jobs.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jobs.py b/jobs.py index 49091015..24f73a61 100644 --- a/jobs.py +++ b/jobs.py @@ -20,7 +20,8 @@ def update_payments(stub): inflight_payments = Payments.objects.filter(status=1).order_by('index') for payment in inflight_payments: payment_data = stub.ListPayments(ln.ListPaymentsRequest(include_incomplete=True, index_offset=payment.index-1, max_payments=1)).payments - if len(payment_data) > 0 and payment.payment_hash == payment_data[0].payment_hash: + #Ignore inflight payments before 30 days + if len(payment_data) > 0 and payment.payment_hash == payment_data[0].payment_hash and payment.creation_date > (datetime.now() - timedelta(days=30)): update_payment(stub, payment_data[0], self_pubkey) else: payment.status = 3 From 13a6ef48ef6901b5fb0e70e7ae4177e35fb5bf28 Mon Sep 17 00:00:00 2001 From: BhaagBodeDK Date: Mon, 22 Aug 2022 07:59:34 +0000 Subject: [PATCH 03/87] Add route link to payment/invoice hash --- gui/templates/channel.html | 4 ++-- gui/templates/home.html | 4 ++-- gui/templates/invoices.html | 2 +- gui/templates/payments.html | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gui/templates/channel.html b/gui/templates/channel.html index 62601208..63a2003f 100644 --- a/gui/templates/channel.html +++ b/gui/templates/channel.html @@ -280,7 +280,7 @@

Last 5 Payments Sent

{% for payment in payments %} {{ payment.creation_date|naturaltime }} - {{ payment.payment_hash }} + {{ payment.payment_hash }} {{ payment.value|add:"0"|intcomma }} {{ payment.fee|intcomma }} {{ payment.ppm|intcomma }} @@ -313,7 +313,7 @@

Last 5 Payments Received

{{ invoice.creation_date|naturaltime }} {% if invoice.state == 1 %}{{ invoice.settle_date|naturaltime }}{% else %}---{% endif %} - {{ invoice.r_hash }} + {{ invoice.r_hash }} {{ invoice.value|add:"0"|intcomma }} {% if invoice.state == 1 %}{{ invoice.amt_paid|intcomma }}{% else %}---{% endif %} {% if invoice.state == 0 %}Open{% elif invoice.state == 1 %}Settled{% elif invoice.state == 2 %}Canceled{% else %}{{ invoice.state }}{% endif %} diff --git a/gui/templates/home.html b/gui/templates/home.html index 0c0ebcd6..1d4345d1 100644 --- a/gui/templates/home.html +++ b/gui/templates/home.html @@ -491,7 +491,7 @@

Last 5 Payments Sent

{% for payment in payments %} {{ payment.creation_date|naturaltime }} - {{ payment.payment_hash }} + {{ payment.payment_hash }} {{ payment.value|add:"0"|intcomma }} {{ payment.fee|intcomma }} {{ payment.ppm|intcomma }} @@ -524,7 +524,7 @@

Last 5 Payments Received

{{ invoice.creation_date|naturaltime }} {% if invoice.state == 1 %}{{ invoice.settle_date|naturaltime }}{% else %}---{% endif %} - {{ invoice.r_hash }} + {{ invoice.r_hash }} {{ invoice.value|add:"0"|intcomma }} {% if invoice.state == 1 %}{{ invoice.amt_paid|intcomma }}{% else %}---{% endif %} {% if invoice.state == 0 %}Open{% elif invoice.state == 1 %}Settled{% elif invoice.state == 2 %}Canceled{% else %}{{ invoice.state }}{% endif %} diff --git a/gui/templates/invoices.html b/gui/templates/invoices.html index fa799aa2..08109181 100644 --- a/gui/templates/invoices.html +++ b/gui/templates/invoices.html @@ -21,7 +21,7 @@

Last 150 Invoices

{{ invoice.creation_date|naturaltime }} {% if invoice.state == 1 %}{{ invoice.settle_date|naturaltime }}{% else %}---{% endif %} - {{ invoice.r_hash }} +
{{ invoice.r_hash }} {{ invoice.value|add:"0"|intcomma }} {% if invoice.state == 1 %}{{ invoice.amt_paid|intcomma }}{% else %}---{% endif %} {% if invoice.state == 0 %}Open{% elif invoice.state == 1 %}Settled{% elif invoice.state == 2 %}Canceled{% else %}{{ invoice.state }}{% endif %} diff --git a/gui/templates/payments.html b/gui/templates/payments.html index bf7ad3de..42f0f244 100644 --- a/gui/templates/payments.html +++ b/gui/templates/payments.html @@ -21,7 +21,7 @@

Last 150 Payments

{% for payment in payments %} {{ payment.creation_date|naturaltime }} - {{ payment.payment_hash }} +
{{ payment.payment_hash }} {{ payment.value|add:"0"|intcomma }} {{ payment.fee|intcomma }} {{ payment.ppm|intcomma }} From 6fcec514961e1c3cd82d3f767c990fcfd4d2290c Mon Sep 17 00:00:00 2001 From: BhaagBodeDK Date: Tue, 26 Jul 2022 21:15:56 +0000 Subject: [PATCH 04/87] add last updated time stamp on the pages --- gui/templates/base.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gui/templates/base.html b/gui/templates/base.html index bf24086b..1d0b0a6e 100644 --- a/gui/templates/base.html +++ b/gui/templates/base.html @@ -21,6 +21,11 @@

{{ message. {% endif %}

My Lnd Overview

+

Last Updated :

+
{% block content %}{% endblock %} From 261a9980a0f34037db99293002e6405615243f14 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Tue, 30 Aug 2022 10:17:27 +0000 Subject: [PATCH 05/87] refresh page every 21 minutes --- gui/templates/base.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gui/templates/base.html b/gui/templates/base.html index 1d0b0a6e..4fb13149 100644 --- a/gui/templates/base.html +++ b/gui/templates/base.html @@ -4,6 +4,7 @@ + {% block title %}LNDg{% endblock %} {% load static %} {% load qr_code %} @@ -21,7 +22,7 @@

{{ message. {% endif %}

My Lnd Overview

-

Last Updated :

+

Last Updated : ... refreshing every 21 minutes

{% block content %}{% endblock %} diff --git a/gui/templates/home.html b/gui/templates/home.html index 7e34c10f..28481855 100644 --- a/gui/templates/home.html +++ b/gui/templates/home.html @@ -1,8 +1,14 @@ {% extends "base.html" %} {% block title %} {{ block.super }} - Dashboard{% endblock %} +{% block meta %}{% endblock %} {% block content %} {% load humanize %}
+

Dashboard Last Updated : ... refreshing every 21 minutes

+

{{ node_info.alias }} | {{ node_info.identity_pubkey }}

Public Capacity: {{ total_capacity|intcomma }} | Active Channels: {{ node_info.num_active_channels }} / {{ total_channels }} | Peers: {{ node_info.num_peers }} | DB Size: {% if db_size > 0 %}{{ db_size }} GB{% else %}---{% endif %} | Total States Updates: {% if num_updates > 0 %}{{ num_updates|intcomma }} {% else %}---{% endif %}

{% if total_private > 0 %}

Private Capacity: {{ private_capacity|intcomma }} | Locked Liquidity: {{ private_outbound|intcomma }} | Active Private Channels: {{ active_private }} / {{ total_private }}

{% endif %} From d604ae04f2b79864e0e104ec8fcfb60d5732a351 Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Fri, 30 Sep 2022 16:24:10 -0400 Subject: [PATCH 56/87] adjust hover over on keysend page --- gui/templates/keysends.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gui/templates/keysends.html b/gui/templates/keysends.html index f5830409..ffd7ef10 100644 --- a/gui/templates/keysends.html +++ b/gui/templates/keysends.html @@ -22,9 +22,9 @@

Received Keysends

- {{ keysend.settle_date|naturaltime }} - {% if keysend.chan_in_alias == '' %}---{% else %}{{ keysend.chan_in_alias }}{% endif %} - {{ keysend.amt_paid|intcomma }} + {{ keysend.settle_date|naturaltime }} + {% if keysend.chan_in_alias == '' %}---{% else %}{{ keysend.chan_in_alias }}{% endif %} + {{ keysend.amt_paid|intcomma }} {{ keysend.message }}{% if keysend.sender != None %} | Signed By: {% if keysend.sender_alias != None %}{{ keysend.sender_alias }}{% else %}{{ keysend.sender }}{% endif %}{% endif %} {% endfor %} From 95d0fdbb4888e3aa5760f1009d994b091f5bddb1 Mon Sep 17 00:00:00 2001 From: BhhagBoseDK <87854599+BhaagBoseDK@users.noreply.github.com> Date: Sat, 1 Oct 2022 23:30:52 +0100 Subject: [PATCH 57/87] Correct Spelling for Liquidity --- jobs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jobs.py b/jobs.py index 853a0520..799ed16e 100644 --- a/jobs.py +++ b/jobs.py @@ -93,7 +93,7 @@ def adjust_ar_amt( payment, chan_id ): last_rebalance_duration = Rebalancer.objects.filter(payment_hash=payment.payment_hash)[0].duration if Rebalancer.objects.filter(payment_hash=payment.payment_hash).exists() else 0 #print (f"{datetime.now().strftime('%c')} : DEBUG {last_rebalance_duration=} {payment.payment_hash=}") if last_rebalance_duration <= 1 or payment.status not in (2,3): - print (f"{datetime.now().strftime('%c')} : Skipping Liquidiy Estimation {last_rebalance_duration=} {payment.payment_hash=}") + print (f"{datetime.now().strftime('%c')} : Skipping Liquidity Estimation {last_rebalance_duration=} {payment.payment_hash=}") return #To be coverted to settings later lower_limit = 69420 From c17ce3474f8494f3361f3883036568bbc7f76fdb Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Thu, 1 Sep 2022 12:54:06 +0000 Subject: [PATCH 58/87] Show payment hash on rebalance pages with link to route --- gui/templates/channel.html | 4 +++- gui/templates/home.html | 10 +++++---- gui/templates/rebalances.html | 41 +++++++++++++++++++++++++++++++++- gui/templates/rebalancing.html | 4 +++- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/gui/templates/channel.html b/gui/templates/channel.html index a33a68c1..26772256 100644 --- a/gui/templates/channel.html +++ b/gui/templates/channel.html @@ -243,6 +243,7 @@

Last 5 Rebalance Requests

Fees Paid Last Hop Alias Status + Hash {% for rebalance in rebalances %} @@ -255,8 +256,9 @@

Last 5 Rebalance Requests

{{ rebalance.fee_limit|intcomma }} {{ rebalance.ppm|intcomma }} {% if rebalance.status == 2 %}{{ rebalance.fees_paid|intcomma }}{% else %}---{% endif %} - {% if rebalance.target_alias == '' %}None Specified{% else %}{{ rebalance.target_alias }}{% endif %} + {% if rebalance.target_alias == '' %}---{% else %}{{ rebalance.target_alias }}{% endif %} {% if rebalance.status == 0 %}Pending{% elif rebalance.status == 1 %}In-Flight{% elif rebalance.status == 2 %}Successful{% elif rebalance.status == 3 %}Timeout{% elif rebalance.status == 4 %}No Route{% elif rebalance.status == 5 %}Error{% elif rebalance.status == 6 %}Incorrect Payment Details{% elif rebalance.status == 7 %}Insufficient Balance{% elif rebalance.status == 400 %}Rebalancer Request Failed{% elif rebalance.status == 408 %}Rebalancer Request Timeout{% else %}{{ rebalance.status }}{% endif %} + {% if rebalance.payment_hash == '' %}---{% else %}{{ rebalance.payment_hash }}{% endif %} {% endfor %} diff --git a/gui/templates/home.html b/gui/templates/home.html index 28481855..ba6fa3bd 100644 --- a/gui/templates/home.html +++ b/gui/templates/home.html @@ -459,20 +459,22 @@

Last 10 Rebalance Requests (curren Fees Paid Last Hop Alias Status + Hash {% for rebalance in rebalances %} {{ rebalance.requested|naturaltime }} - {% if rebalance.status == 0 %}---{% else %}{{ rebalance.start|naturaltime }}{% endif %} - {% if rebalance.status > 1 %}{{ rebalance.stop|naturaltime }}{% else %}---{% endif %} + ---{% else %}title="{{ rebalance.start }}">{{ rebalance.start|naturaltime }}{% endif %} + 1 %}title="{{ rebalance.stop }}">{{ rebalance.stop|naturaltime }}{% else %}>---{% endif %} {{ rebalance.duration }} minutes {% if rebalance.status == 2 %}{{ rebalance.stop|timeuntil:rebalance.start }}{% else %}---{% endif %} {{ rebalance.value|intcomma }} {{ rebalance.fee_limit|intcomma }} {{ rebalance.ppm|intcomma }} - {% if rebalance.status == 2 %}{{ rebalance.fees_paid|intcomma}}{% else %}---{% endif %} - {% if rebalance.target_alias == '' %}None Specified{% else %}{{ rebalance.target_alias }}{% endif %} + {% if rebalance.status == 2 %}{{ rebalance.fees_paid|intcomma }}{% else %}---{% endif %} + {% if rebalance.target_alias == '' %}---{% else %}{{ rebalance.target_alias }}{% endif %} {% if rebalance.status == 0 %}Pending{% elif rebalance.status == 1 %}In-Flight{% elif rebalance.status == 2 %}Successful{% elif rebalance.status == 3 %}Timeout{% elif rebalance.status == 4 %}No Route{% elif rebalance.status == 5 %}Error{% elif rebalance.status == 6 %}Incorrect Payment Details{% elif rebalance.status == 7 %}Insufficient Balance{% elif rebalance.status == 400 %}Rebalancer Request Failed{% elif rebalance.status == 408 %}Rebalancer Request Timeout{% else %}{{ rebalance.status }}{% endif %} + {% if rebalance.payment_hash == '' %}---{% else %}{{ rebalance.payment_hash }}{% endif %} {% endfor %} diff --git a/gui/templates/rebalances.html b/gui/templates/rebalances.html index 2e23f7e2..096fa85d 100644 --- a/gui/templates/rebalances.html +++ b/gui/templates/rebalances.html @@ -3,6 +3,43 @@ {% block content %} {% load humanize %} {% if rebalances %} +
+

Last Successful Rebalances

+ + + + + + + + + + + + + + + + {% for rebalance in rebalances %} + {% if rebalance.status == 2 %} + + + + + + + + + + + + + + + {% endif %} + {% endfor %} +
RequestedStartStopScheduled DurationActual DurationValueFee LimitTarget PPMFees PaidLast Hop AliasStatusHash
{{ rebalance.requested|naturaltime }}---{% else %}title="{{ rebalance.start }}">{{ rebalance.start|naturaltime }}{% endif %} 1 %}title="{{ rebalance.stop }}">{{ rebalance.stop|naturaltime }}{% else %}>---{% endif %}{{ rebalance.duration }} minutes{% if rebalance.status == 2 %}{{ rebalance.stop|timeuntil:rebalance.start }}{% else %}---{% endif %}{{ rebalance.value|intcomma }}{{ rebalance.fee_limit|intcomma }}{{ rebalance.ppm|intcomma }}{% if rebalance.status == 2 %}{{ rebalance.fees_paid|intcomma }}{% else %}---{% endif %}{% if rebalance.target_alias == '' %}---{% else %}{{ rebalance.target_alias }}{% endif %}{% if rebalance.status == 0 %}Pending{% elif rebalance.status == 1 %}In-Flight{% elif rebalance.status == 2 %}Successful{% elif rebalance.status == 3 %}Timeout{% elif rebalance.status == 4 %}No Route{% elif rebalance.status == 5 %}Error{% elif rebalance.status == 6 %}Incorrect Payment Details{% elif rebalance.status == 7 %}Insufficient Balance{% elif rebalance.status == 400 %}Rebalancer Request Failed{% elif rebalance.status == 408 %}Rebalancer Request Timeout{% else %}{{ rebalance.status }}{% endif %}{% if rebalance.payment_hash == '' %}---{% else %}{{ rebalance.payment_hash }}{% endif %}
+

Last 150 Rebalances

@@ -18,6 +55,7 @@

Last 150 Rebalances

+ {% for rebalance in rebalances %} @@ -30,8 +68,9 @@

Last 150 Rebalances

- + + {% endfor %}
Fees Paid Last Hop Alias StatusHash
{{ rebalance.fee_limit|intcomma }} {{ rebalance.ppm|intcomma }} {% if rebalance.status == 2 %}{{ rebalance.fees_paid|intcomma }}{% else %}---{% endif %}{% if rebalance.target_alias == '' %}None Specified{% else %}{{ rebalance.target_alias }}{% endif %}{% if rebalance.target_alias == '' %}---{% else %}{{ rebalance.target_alias }}{% endif %} {% if rebalance.status == 0 %}Pending{% elif rebalance.status == 1 %}In-Flight{% elif rebalance.status == 2 %}Successful{% elif rebalance.status == 3 %}Timeout{% elif rebalance.status == 4 %}No Route{% elif rebalance.status == 5 %}Error{% elif rebalance.status == 6 %}Incorrect Payment Details{% elif rebalance.status == 7 %}Insufficient Balance{% elif rebalance.status == 400 %}Rebalancer Request Failed{% elif rebalance.status == 408 %}Rebalancer Request Timeout{% else %}{{ rebalance.status }}{% endif %}{% if rebalance.payment_hash == '' %}---{% else %}{{ rebalance.payment_hash }}{% endif %}
diff --git a/gui/templates/rebalancing.html b/gui/templates/rebalancing.html index 284d605b..d0a75764 100644 --- a/gui/templates/rebalancing.html +++ b/gui/templates/rebalancing.html @@ -108,6 +108,7 @@

Last 20 Rebalance Requests

Fees Paid Last Hop Alias Status + Hash {% for rebalance in rebalancer %} @@ -120,8 +121,9 @@

Last 20 Rebalance Requests

{{ rebalance.fee_limit|intcomma }} {{ rebalance.ppm|intcomma }} {% if rebalance.status == 2 %}{{ rebalance.fees_paid|intcomma }}{% else %}---{% endif %} - {% if rebalance.target_alias == '' %}None Specified{% else %}{{ rebalance.target_alias }}{% endif %} + {% if rebalance.target_alias == '' %}---{% else %}{{ rebalance.target_alias }}{% endif %} {% if rebalance.status == 0 %}Pending{% elif rebalance.status == 1 %}In-Flight{% elif rebalance.status == 2 %}Successful{% elif rebalance.status == 3 %}Timeout{% elif rebalance.status == 4 %}No Route{% elif rebalance.status == 5 %}Error{% elif rebalance.status == 6 %}Incorrect Payment Details{% elif rebalance.status == 7 %}Insufficient Balance{% elif rebalance.status == 400 %}Rebalancer Request Failed{% elif rebalance.status == 408 %}Rebalancer Request Timeout{% else %}{{ rebalance.status }}{% endif %} + {% if rebalance.payment_hash == '' %}---{% else %}{{ rebalance.payment_hash }}{% endif %} {% endfor %} From 11ae671c1483cde321535921d1442082f30a1e07 Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Tue, 4 Oct 2022 08:51:45 -0400 Subject: [PATCH 59/87] Round total fee on route --- gui/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/views.py b/gui/views.py index 0236e645..adc7438d 100644 --- a/gui/views.py +++ b/gui/views.py @@ -542,7 +542,7 @@ def route(request): block_height = stub.GetInfo(ln.GetInfoRequest()).block_height payment_hash = request.GET.urlencode()[1:] route = PaymentHops.objects.filter(payment_hash=payment_hash).annotate(ppm=Round((Sum('fee')/Sum('amt'))*1000000, output_field=IntegerField())) - total_cost = route.aggregate(Sum('fee'))['fee__sum'] + total_cost = round(route.aggregate(Sum('fee'))['fee__sum'], 3) total_ppm = route.aggregate(Sum('ppm'))['ppm__sum'] context = { 'payment_hash': payment_hash, From 91ff35e2912ed49562961774cc5ad7818374c467 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Tue, 4 Oct 2022 16:19:57 +0000 Subject: [PATCH 60/87] autofees logs in channel page --- gui/templates/channel.html | 27 +++++++++++++++++++++++++++ gui/views.py | 6 +++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/gui/templates/channel.html b/gui/templates/channel.html index a33a68c1..cc1e8727 100644 --- a/gui/templates/channel.html +++ b/gui/templates/channel.html @@ -196,6 +196,33 @@

Incoming HTLCs

{% endif %} +{% if autofees %} +
+

30 Days Autofees Logs

+ + + + + + + + + + + {% for log in autofees %} + + + + + + + + + + {% endfor %} +
TimestampChannel IDPeer AliasSettingOld ValueNew ValueChange
{{ log.timestamp|naturaltime }}{{ log.chan_id }}{% if log.peer_alias == '' %}---{% else %}{{ log.peer_alias }}{% endif %}{{ log.setting }}{{ log.old_value }} log.old_value %}style="background-color: #d5fadb"{% else %}style="background-color: #fadbd5"{% endif %}>{{ log.new_value }} log.old_value %}style="background-color: #d5fadb"{% else %}style="background-color: #fadbd5"{% endif %}>{{ log.change }}%
+
+{% endif %} {% if forwards %}

Last 5 Payments Routed

diff --git a/gui/views.py b/gui/views.py index 0236e645..0f4c1f19 100644 --- a/gui/views.py +++ b/gui/views.py @@ -1300,6 +1300,9 @@ def channel(request): rebalancer_df = DataFrame() failed_htlc_df = DataFrame() peer_info_df = DataFrame() + + autofees = Autofees.objects.filter(chan_id=chan_id).filter(timestamp__gte=filter_30day).order_by('-id').annotate(change=(Sum('new_value')-Sum('old_value'))*100/Sum('old_value')) + context = { 'chan_id': chan_id, 'channel': [] if channels_df.empty else channels_df.to_dict(orient='records')[0], @@ -1313,7 +1316,8 @@ def channel(request): 'peer_info': [] if peer_info_df.empty else peer_info_df.to_dict(orient='records')[0], 'network': 'testnet/' if settings.LND_NETWORK == 'testnet' else '', 'graph_links': graph_links(), - 'network_links': network_links() + 'network_links': network_links(), + 'autofees': autofees } try: return render(request, 'channel.html', context) From 2a4e84fa71534f829fdce0d002add5b21f965764 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Tue, 4 Oct 2022 22:06:40 +0000 Subject: [PATCH 61/87] AF-UpdateHours save not working --- gui/views.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/gui/views.py b/gui/views.py index 0236e645..456fde35 100644 --- a/gui/views.py +++ b/gui/views.py @@ -2539,10 +2539,20 @@ def update_setting(request): db_enabled.value = enabled db_enabled.save() messages.success(request, 'Updated autofees daily failed HTLC trigger limit setting to: ' + str(enabled)) + elif key == 'AF-UpdateHours': + enabled = int(value) + try: + db_enabled = LocalSettings.objects.get(key='AF-UpdateHours') + except: + LocalSettings(key='AF-UpdateHours', value='24').save() + db_enabled = LocalSettings.objects.get(key='AF-UpdateHours') + db_enabled.value = enabled + db_enabled.save() + messages.success(request, 'Updated autofees update hours setting to: ' + str(enabled)) else: - messages.error(request, 'Invalid Request. Please try again.') + messages.error(request, 'Invalid Request. Please try again. [' + key +']') else: - messages.error(request, 'Invalid Request. Please try again.') + messages.error(request, 'Invalid Request Form. Please try again.') return redirect(request.META.get('HTTP_REFERER')) @is_login_required(login_required(login_url='/lndg-admin/login/?next=/'), settings.LOGIN_REQUIRED) From a04dbaecd5642bb46e008f2304bae8432b367a25 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Thu, 6 Oct 2022 08:52:50 +0000 Subject: [PATCH 62/87] correcting ppm calculations for route --- gui/views.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gui/views.py b/gui/views.py index 4b0e7362..3389ee96 100644 --- a/gui/views.py +++ b/gui/views.py @@ -541,9 +541,9 @@ def route(request): stub = lnrpc.LightningStub(lnd_connect()) block_height = stub.GetInfo(ln.GetInfoRequest()).block_height payment_hash = request.GET.urlencode()[1:] - route = PaymentHops.objects.filter(payment_hash=payment_hash).annotate(ppm=Round((Sum('fee')/Sum('amt'))*1000000, output_field=IntegerField())) - total_cost = round(route.aggregate(Sum('fee'))['fee__sum'], 3) - total_ppm = route.aggregate(Sum('ppm'))['ppm__sum'] + route = PaymentHops.objects.filter(payment_hash=payment_hash).annotate(ppm=Round((Sum('fee')/Sum('amt'))*1000000, output_field=IntegerField())) if PaymentHops.objects.filter(payment_hash=payment_hash).exists() else None + total_cost = round(route.aggregate(Sum('fee'))['fee__sum'],3) if route is not None else 0 + total_ppm = int(total_cost*1000000/route.filter(step=1).aggregate(Sum('amt'))['amt__sum']) if route is not None else 0 context = { 'payment_hash': payment_hash, 'total_cost': total_cost, From e0f45bb592479bb1dfb029d478e727e862c8ac23 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Wed, 12 Oct 2022 14:07:18 +0000 Subject: [PATCH 63/87] Catch-all AR Reduction on Failure --- jobs.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/jobs.py b/jobs.py index 799ed16e..5b100f7e 100644 --- a/jobs.py +++ b/jobs.py @@ -50,7 +50,7 @@ def update_payment(stub, payment, self_pubkey): db_payment.rebal_chan = None db_payment.save() for attempt in payment.htlcs: - if attempt.status == 1 or attempt.status == 0 or (attempt.status == 2 and attempt.failure.code in (1,2,12)) : + if attempt.status == 1 or attempt.status == 0 or attempt.status == 2: hops = attempt.route.hops hop_count = 0 cost_to = 0 @@ -67,7 +67,8 @@ def update_payment(stub, payment, self_pubkey): alias += f'[ {payment.status}-{attempt.status}-{attempt.failure.code}-{attempt.failure.failure_source_index} ]' #if hop_count == total_hops: #print (f"{datetime.now().strftime('%c')} : Debug Hop {attempt.attempt_id=} {attempt.route.total_amt=} {hop.mpp_record.payment_addr.hex()=} {hop.mpp_record.total_amt_msat=} {hop.amp_record=} {db_payment.payment_hash=}") - PaymentHops(payment_hash=db_payment, attempt_id=attempt.attempt_id, step=hop_count, chan_id=hop.chan_id, alias=alias, chan_capacity=hop.chan_capacity, node_pubkey=hop.pub_key, amt=round(hop.amt_to_forward_msat/1000, 3), fee=round(fee, 3), cost_to=round(cost_to, 3)).save() + if attempt.status == 1 or attempt.status == 0 or (attempt.status == 2 and attempt.failure.code in (1,2,12)): + PaymentHops(payment_hash=db_payment, attempt_id=attempt.attempt_id, step=hop_count, chan_id=hop.chan_id, alias=alias, chan_capacity=hop.chan_capacity, node_pubkey=hop.pub_key, amt=round(hop.amt_to_forward_msat/1000, 3), fee=round(fee, 3), cost_to=round(cost_to, 3)).save() cost_to += fee if hop_count == 1 and attempt.status == 1: if db_payment.chan_out is None: @@ -106,14 +107,15 @@ def adjust_ar_amt( payment, chan_id ): ar_target = 5 #Adjust AR Target Amount, increase if success reduce if failed. + db_channel = Channels.objects.filter(chan_id = chan_id)[0] if Channels.objects.filter(chan_id = chan_id).exists() else None if payment.status == 2 and chan_id is not None: - db_channel = Channels.objects.filter(chan_id = chan_id)[0] if Channels.objects.filter(chan_id = chan_id).exists() else None if db_channel is not None and payment.value_msat/1000 > 1000 : - new_ar_amount = int(min(max(db_channel.ar_amt_target * 1.21, payment.value_msat/1000), db_channel.capacity*ar_target*upper_limit/100)) + new_ar_amount = int(min(max(db_channel.ar_amt_target * 1.11, payment.value_msat/1000), db_channel.capacity*ar_target*upper_limit/100)) if new_ar_amount > db_channel.ar_amt_target: print (f"{datetime.now().strftime('%c')} : Increase AR Target Amount {chan_id=} {db_channel.alias=} {db_channel.ar_amt_target=} {new_ar_amount=}") db_channel.ar_amt_target = new_ar_amount db_channel.save() + if payment.status == 3: estimated_liquidity = 0 for attempt in payment.htlcs: @@ -123,11 +125,16 @@ def adjust_ar_amt( payment, chan_id ): #Failure 1,2 from last hop indicating liquidity available, failure 12 shows fees in sufficient but liquidity available estimated_liquidity += attempt.route.total_amt chan_id=attempt.route.hops[len(attempt.route.hops)-1].chan_id - print (f"{datetime.now().strftime('%c')} : Liquidity Estimation {attempt.attempt_id} {attempt.status=} {attempt.failure.code=} {chan_id=} {attempt.route.total_amt=} {payment.value_msat/1000=} {estimated_liquidity=} {payment.payment_hash=}") + print (f"{datetime.now().strftime('%c')} : Liquidity Estimation {attempt.attempt_id=} {attempt.status=} {attempt.failure.code=} {chan_id=} {attempt.route.total_amt=} {payment.value_msat/1000=} {estimated_liquidity=} {payment.payment_hash=}") + + if estimated_liquidity == 0: + #Could not estimate liquidity, reduce by half + estimated_liquidity = db_channel.ar_amt_target/2 if db_channel is not None else 0 + print (f"{datetime.now().strftime('%c')} : Liquidity Estimation not possible, halving {attempt.attempt_id=} {attempt.status=} {attempt.failure.code=} {chan_id=} {attempt.route.total_amt=} {payment.value_msat/1000=} {estimated_liquidity=} {payment.payment_hash=}") + if payment.value_msat/1000 >= lower_limit and estimated_liquidity <= payment.value_msat/1000 and estimated_liquidity > 0: #Change AR amount. Ignore zero liquidity case which implies breakout from rapid fire AR new_ar_amount = int(estimated_liquidity if estimated_liquidity > lower_limit else lower_limit) - db_channel = Channels.objects.filter(chan_id = chan_id)[0] if Channels.objects.filter(chan_id = chan_id).exists() else None if db_channel is not None and new_ar_amount < db_channel.ar_amt_target: print (f"{datetime.now().strftime('%c')} : Decrease AR Target Amount {chan_id=} {db_channel.alias=} {db_channel.ar_amt_target=} {new_ar_amount=}") db_channel.ar_amt_target = new_ar_amount From 3e821fcdeb1306fcb9d21ead1ce933bfe6c6a21d Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Mon, 17 Oct 2022 08:53:33 -0400 Subject: [PATCH 64/87] Create p2tr addresses if possible --- gui/views.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/gui/views.py b/gui/views.py index 6b17457c..56aa2e59 100644 --- a/gui/views.py +++ b/gui/views.py @@ -17,7 +17,7 @@ from gui.lnd_deps import router_pb2_grpc as lnrouter from gui.lnd_deps import wtclient_pb2 as wtrpc from gui.lnd_deps import wtclient_pb2_grpc as wtstub -from .lnd_deps.lnd_connect import lnd_connect +from gui.lnd_deps.lnd_connect import lnd_connect from lndg import settings from os import path from pandas import DataFrame, merge @@ -1832,7 +1832,12 @@ def new_address_form(request): if request.method == 'POST': try: stub = lnrpc.LightningStub(lnd_connect()) - response = stub.NewAddress(ln.NewAddressRequest(type=0)) + version = stub.GetInfo(ln.GetInfoRequest()).version + # Verify sufficient version to handle p2tr address creation + if float(version[:4]) >= 0.15: + response = stub.NewAddress(ln.NewAddressRequest(type=4)) + else: + response = stub.NewAddress(ln.NewAddressRequest(type=0)) messages.success(request, 'Deposit Address: ' + str(response.address)) except Exception as e: error = str(e) @@ -2844,7 +2849,12 @@ def add_invoice(request): def new_address(request): try: stub = lnrpc.LightningStub(lnd_connect()) - response = stub.NewAddress(ln.NewAddressRequest(type=0)) + version = stub.GetInfo(ln.GetInfoRequest()).version + # Verify sufficient version to handle p2tr address creation + if float(version[:4]) >= 0.15: + response = stub.NewAddress(ln.NewAddressRequest(type=4)) + else: + response = stub.NewAddress(ln.NewAddressRequest(type=0)) return Response({'message': 'Retrieved new deposit address!', 'data':str(response.address)}) except Exception as e: error = str(e) From 73a7053dba6eaf1c552a0635d2ac23be9f2c58f8 Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Mon, 17 Oct 2022 14:05:53 -0400 Subject: [PATCH 65/87] Get missed fee from htlc data --- htlc_stream.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htlc_stream.py b/htlc_stream.py index 9342dbb9..525d6b9b 100644 --- a/htlc_stream.py +++ b/htlc_stream.py @@ -25,7 +25,7 @@ def main(): amount = int(response.link_fail_event.info.outgoing_amt_msat/1000) wire_failure = response.link_fail_event.wire_failure failure_detail = response.link_fail_event.failure_detail - missed_fee = 0 if out_chan == None else round(((amount/1000000) * out_chan.local_fee_rate) + (out_chan.local_base_fee/1000), 3) + missed_fee = (response.link_fail_event.info.incoming_amt_msat - response.link_fail_event.info.outgoing_amt_msat)/1000 FailedHTLCs(amount=amount, chan_id_in=in_chan_id, chan_id_out=out_chan_id, chan_in_alias=in_chan_alias, chan_out_alias=out_chan_alias, chan_out_liq=out_chan_liq, chan_out_pending=out_chan_pending, wire_failure=wire_failure, failure_detail=failure_detail, missed_fee=missed_fee).save() except Exception as e: print('Error while running failed HTLC stream: ' + str(e)) From dfddacb6370f720ea3249f737112a67bacf43ab0 Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Mon, 17 Oct 2022 18:40:53 -0400 Subject: [PATCH 66/87] Fix issue when unknown channel and pulling autofee log --- gui/views.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gui/views.py b/gui/views.py index 56aa2e59..06f155ed 100644 --- a/gui/views.py +++ b/gui/views.py @@ -1292,6 +1292,7 @@ def channel(request): channels_df['cv_30day'] = round((channels_df['revenue_30day']*1216.6667)/(channels_df['capacity']*outbound_ratio) + channels_df['assisted_apy_30day'], 2) channels_df['cv_7day'] = round((channels_df['revenue_7day']*5214.2857)/(channels_df['capacity']*outbound_ratio) + channels_df['assisted_apy_7day'], 2) channels_df['cv_1day'] = round((channels_df['revenue_1day']*36500)/(channels_df['capacity']*outbound_ratio) + channels_df['assisted_apy_1day'], 2) + autofees = Autofees.objects.filter(chan_id=chan_id).filter(timestamp__gte=filter_30day).order_by('-id').annotate(change=(Sum('new_value')-Sum('old_value'))*100/Sum('old_value')) else: channels_df = DataFrame() forwards_df = DataFrame() @@ -1300,9 +1301,7 @@ def channel(request): rebalancer_df = DataFrame() failed_htlc_df = DataFrame() peer_info_df = DataFrame() - - autofees = Autofees.objects.filter(chan_id=chan_id).filter(timestamp__gte=filter_30day).order_by('-id').annotate(change=(Sum('new_value')-Sum('old_value'))*100/Sum('old_value')) - + autofees = [] context = { 'chan_id': chan_id, 'channel': [] if channels_df.empty else channels_df.to_dict(orient='records')[0], From 53cecbe7b959bc4ec94a3f0a798371c6a72af6c6 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Thu, 20 Oct 2022 08:26:20 +0000 Subject: [PATCH 67/87] capture extenal and manual fee change and record in auto fee log --- gui/views.py | 7 +++++++ jobs.py | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gui/views.py b/gui/views.py index 06f155ed..5538e9f9 100644 --- a/gui/views.py +++ b/gui/views.py @@ -1926,10 +1926,13 @@ def update_chan_policy(request): stub.UpdateChannelPolicy(ln.PolicyUpdateRequest(chan_point=channel_point, base_fee_msat=new_base_fee, fee_rate=new_fee_rate, time_lock_delta=new_cltv)) db_channel = Channels.objects.get(chan_id=channel.chan_id) db_channel.local_base_fee = new_base_fee + old_fee_rate = db_channel.local_fee_rate db_channel.local_fee_rate = new_fee_rate*1000000 db_channel.local_cltv = new_cltv if form.cleaned_data['new_fee_rate'] is not None: db_channel.fees_updated = datetime.now() + Autofees(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, setting=(f"Manual"), old_value=old_fee_rate, new_value=db_channel.local_fee_rate).save() + db_channel.save() else: messages.error(request, 'No channels were specified in the update request!') @@ -2118,9 +2121,11 @@ def update_channel(request): channel_point.funding_txid_str = db_channel.funding_txid channel_point.output_index = db_channel.output_index stub.UpdateChannelPolicy(ln.PolicyUpdateRequest(chan_point=channel_point, base_fee_msat=db_channel.local_base_fee, fee_rate=(target/1000000), time_lock_delta=db_channel.local_cltv)) + old_fee_rate = db_channel.local_fee_rate db_channel.local_fee_rate = target db_channel.fees_updated = datetime.now() db_channel.save() + Autofees(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, setting=(f"Manual"), old_value=old_fee_rate, new_value=db_channel.local_fee_rate).save() messages.success(request, 'Fee rate for channel ' + str(db_channel.alias) + ' (' + str(db_channel.chan_id) + ') updated to a value of: ' + str(target)) elif update_target == 2: db_channel.ar_amt_target = target @@ -2417,9 +2422,11 @@ def update_setting(request): channel_point.funding_txid_str = db_channel.funding_txid channel_point.output_index = db_channel.output_index stub.UpdateChannelPolicy(ln.PolicyUpdateRequest(chan_point=channel_point, base_fee_msat=db_channel.local_base_fee, fee_rate=(target/1000000), time_lock_delta=db_channel.local_cltv)) + old_fee_rate = db_channel.local_fee_rate db_channel.local_fee_rate = target db_channel.fees_updated = datetime.now() db_channel.save() + Autofees(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, setting=(f"Manual"), old_value=old_fee_rate, new_value=db_channel.local_fee_rate).save() messages.success(request, 'Fee rate for all open channels updated to a value of: ' + str(target)) elif key == 'ALL-oBase': target = int(value) diff --git a/jobs.py b/jobs.py index 5b100f7e..68c9de1f 100644 --- a/jobs.py +++ b/jobs.py @@ -241,6 +241,7 @@ def update_channels(stub): pending_channel = PendingChannels.objects.filter(funding_txid=txid, output_index=index)[0] if PendingChannels.objects.filter(funding_txid=txid, output_index=index).exists() else None try: chan_data = stub.GetChanInfo(ln.ChanInfoRequest(chan_id=channel.chan_id)) + old_fee_rate = db_channel.local_fee_rate if db_channel.local_fee_rate is not None else 0 if chan_data.node1_pub == channel.remote_pubkey: db_channel.local_base_fee = chan_data.node2_policy.fee_base_msat db_channel.local_fee_rate = chan_data.node2_policy.fee_rate_milli_msat @@ -268,6 +269,7 @@ def update_channels(stub): db_channel.remote_min_htlc_msat = chan_data.node2_policy.min_htlc db_channel.remote_max_htlc_msat = chan_data.node2_policy.max_htlc_msat except: + old_fee_rate = 0 db_channel.local_base_fee = 0 db_channel.local_fee_rate = 0 db_channel.local_disabled = False @@ -345,6 +347,11 @@ def update_channels(stub): db_channel.auto_fees = pending_channel.auto_fees pending_channel.delete() db_channel.save() + if db_channel.local_fee_rate != old_fee_rate: + print (f"{datetime.now().strftime('%c')} : Ext Fee Change Detected {db_channel.chan_id=} {db_channel.alias=} {old_fee_rate=} {db_channel.local_fee_rate=}") + #External Fee change detected, update auto fee log + Autofees(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, setting=(f"Ext"), old_value=old_fee_rate, new_value=db_channel.local_fee_rate).save() + counter += 1 chan_list.append(channel.chan_id) records = Channels.objects.filter(is_open=True).count() @@ -624,7 +631,7 @@ def auto_fees(stub): channel.local_fee_rate = target_channel['new_rate'] channel.fees_updated = datetime.now() channel.save() - Autofees(chan_id=channel.chan_id, peer_alias=channel.alias, setting='Fee Rate', old_value=target_channel['local_fee_rate'], new_value=target_channel['new_rate']).save() + Autofees(chan_id=channel.chan_id, peer_alias=channel.alias, setting=(f"AF [ {target_channel['net_routed_7day']}:{target_channel['in_percent']}:{target_channel['out_percent']} ]"), old_value=target_channel['local_fee_rate'], new_value=target_channel['new_rate']).save() def main(): #print (f"{datetime.now().strftime('%c')} : Entering Jobs") From 0402768e74077a3a8027ddee7c8b1a1598f09d1c Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Sat, 22 Oct 2022 08:10:47 +0000 Subject: [PATCH 68/87] rebalancing page filter for sink and source --- gui/templates/rebalancing.html | 6 +++--- gui/views.py | 21 ++++++++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/gui/templates/rebalancing.html b/gui/templates/rebalancing.html index 284d605b..c8d12613 100644 --- a/gui/templates/rebalancing.html +++ b/gui/templates/rebalancing.html @@ -4,7 +4,7 @@ {% load humanize %} {% if channels %}
-

Channel Rebalancing (currently scheduling {{ eligible_count }} of {{ enabled_count }} enabled channels for rebalancing via {{ available_count }} outbound channels)

+

Channel Rebalancing (currently scheduling {{ eligible_count }} of {{ enabled_count }} enabled channels for rebalancing via {{ available_count }} outbound channels)

@@ -14,8 +14,8 @@

Channel Rebalancing (currently scheduling {{ eligible_count }} of {{ enabled

- - + + diff --git a/gui/views.py b/gui/views.py index 06f155ed..de94e1b9 100644 --- a/gui/views.py +++ b/gui/views.py @@ -1639,9 +1639,9 @@ def forwards(request): @is_login_required(login_required(login_url='/lndg-admin/login/?next=/'), settings.LOGIN_REQUIRED) def rebalancing(request): if request.method == 'GET': + channels_df = DataFrame.from_records(Channels.objects.filter(is_open=True, private=False).annotate(percent_inbound=((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity')).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).order_by('-is_active', 'percent_outbound').values()) filter_7day = datetime.now() - timedelta(days=7) rebalancer_7d_df = DataFrame.from_records(Rebalancer.objects.filter(stop__gte=filter_7day).order_by('-id').values()) - channels_df = DataFrame.from_records(Channels.objects.filter(is_open=True, private=False).annotate(percent_inbound=((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity')).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).order_by('-is_active', 'percent_outbound').values()) if channels_df.shape[0] > 0: channels_df['inbound_can'] = channels_df['percent_inbound'] / channels_df['ar_in_target'] channels_df['local_balance'] = channels_df['local_balance'] + channels_df['pending_outbound'] @@ -1663,6 +1663,25 @@ def rebalancing(request): eligible_count = 0 enabled_count = 0 available_count = 0 + + try: + query = request.GET.urlencode()[1:] + if query == '1': + #Filter Sink (AR Enabled) + channels_df = DataFrame.from_records(Channels.objects.filter(is_open=True, private=False, auto_rebalance=True).annotate(percent_inbound=((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity')).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).order_by('-is_active', 'percent_outbound').values()) + elif query == '2': + #Filter Source (Eligible to rebalance out) + channels_df = DataFrame.from_records(Channels.objects.filter(is_open=True, private=False, auto_rebalance=False).annotate(percent_inbound=((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity')).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).order_by('-is_active', '-percent_outbound').values()) + else: + #Proceed + pass + except Exception as e: + try: + error = str(e.code()) + except: + error = str(e) + return render(request, 'error.html', {'error': error}) + context = { 'eligible_count': eligible_count, 'enabled_count': enabled_count, From 6aed593483daff01370dd4e19b2e8b475fd203bc Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Mon, 24 Oct 2022 14:13:56 -0400 Subject: [PATCH 69/87] Add failure code 22 --- gui/templates/failed_htlcs.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/templates/failed_htlcs.html b/gui/templates/failed_htlcs.html index c68442c8..cb55420a 100644 --- a/gui/templates/failed_htlcs.html +++ b/gui/templates/failed_htlcs.html @@ -28,7 +28,7 @@

Last 150 Failed HTLCs

- + {% endfor %} From db564140f10f84b16136a2f84edb06f5e739e090 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Wed, 26 Oct 2022 16:44:57 +0000 Subject: [PATCH 70/87] rebalancing page filter for sink and source[1] --- gui/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gui/views.py b/gui/views.py index de94e1b9..13761326 100644 --- a/gui/views.py +++ b/gui/views.py @@ -1668,10 +1668,10 @@ def rebalancing(request): query = request.GET.urlencode()[1:] if query == '1': #Filter Sink (AR Enabled) - channels_df = DataFrame.from_records(Channels.objects.filter(is_open=True, private=False, auto_rebalance=True).annotate(percent_inbound=((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity')).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).order_by('-is_active', 'percent_outbound').values()) + channels_df = channels_df[channels_df['auto_rebalance']==True][channels_df['is_active']==True] elif query == '2': #Filter Source (Eligible to rebalance out) - channels_df = DataFrame.from_records(Channels.objects.filter(is_open=True, private=False, auto_rebalance=False).annotate(percent_inbound=((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity')).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).order_by('-is_active', '-percent_outbound').values()) + channels_df = channels_df[channels_df['auto_rebalance']==False][channels_df['is_active']==True].sort_values(by=['percent_outbound'], ascending=False) else: #Proceed pass From 8551976aeb82d794fb6cada472754f77f5955689 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Wed, 26 Oct 2022 16:51:50 +0000 Subject: [PATCH 71/87] capture extenal and manual fee change and record in auto fee log [1] --- gui/templates/autofees.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gui/templates/autofees.html b/gui/templates/autofees.html index 69ae4e4c..11baef63 100644 --- a/gui/templates/autofees.html +++ b/gui/templates/autofees.html @@ -4,7 +4,7 @@ {% load humanize %} {% if autofees %}
Outbound Liquidity Inbound LiquidityRebal Out?Enabled?Rebal Out?Enabled? Fee Ratio Rebal In? Target Amt{{ failed_htlc.amount|intcomma }} {{ failed_htlc.chan_out_liq|intcomma }} ({{ failed_htlc.chan_out_pending|intcomma }}) {{ failed_htlc.missed_fee|intcomma }}{% if failed_htlc.wire_failure == 15 %}Temporary Channel Failure{% elif failed_htlc.wire_failure == 18 %}Unknown Next Peer{% elif failed_htlc.wire_failure == 12 %}Fee Insufficient{% else %}{{ failed_htlc.wire_failure }}{% endif %}{% if failed_htlc.wire_failure == 15 %}Temporary Channel Failure{% elif failed_htlc.wire_failure == 18 %}Unknown Next Peer{% elif failed_htlc.wire_failure == 12 %}Fee Insufficient{% elif failed_htlc.wire_failure == 22 %}Expiry Too Far{% else %}{{ failed_htlc.wire_failure }}{% endif %} {% if failed_htlc.failure_detail == 1 %}---{% elif failed_htlc.failure_detail == 5 %}HTLC Exceeds Max{% elif failed_htlc.failure_detail == 6 %}Insufficient Balance{% elif failed_htlc.failure_detail == 13 %}Invoice Not Open{% elif failed_htlc.failure_detail == 20 %}Invalid Keysend{% elif failed_htlc.failure_detail == 22 %}Circular Route{% else %}{{ failed_htlc.failure_detail }}{% endif %}
@@ -29,8 +29,8 @@

Autofees Logs

{% endif %} {% if not autofees %}
-

No autofees logs to see here yet!

+

No our fees logs to see here yet!

Experimental. This will allow LNDg to automatically act upon the suggestions found here.
{% endif %} -{% endblock %} \ No newline at end of file +{% endblock %} From b6502b9bed72aa7aeda53655829fb38aa5d6241c Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Thu, 27 Oct 2022 09:37:19 +0000 Subject: [PATCH 72/87] capture extenal and manual fee change and record in auto fee log [2] --- gui/templates/channel.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/templates/channel.html b/gui/templates/channel.html index cc1e8727..f78fc327 100644 --- a/gui/templates/channel.html +++ b/gui/templates/channel.html @@ -198,7 +198,7 @@

Incoming HTLCs

{% endif %} {% if autofees %}
Timestamp
From 2d2f882fb1ad36479131967d004d8bd0755c461a Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Sun, 30 Oct 2022 18:28:51 +0000 Subject: [PATCH 73/87] Show payment hash on rebalance pages with link to route[1] --- gui/templates/rebalances.html | 36 +++++++++++++++++------------------ gui/views.py | 18 ++++++++++++++---- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/gui/templates/rebalances.html b/gui/templates/rebalances.html index 096fa85d..b2f3dda2 100644 --- a/gui/templates/rebalances.html +++ b/gui/templates/rebalances.html @@ -2,7 +2,7 @@ {% block title %} {{ block.super }} - Rebalances{% endblock %} {% block content %} {% load humanize %} -{% if rebalances %} +{% if rebalances_success %}

Last Successful Rebalances

Timestamp
@@ -20,26 +20,26 @@

Last Successful Rebalances

- {% for rebalance in rebalances %} - {% if rebalance.status == 2 %} - - - - - - - - - - - - - - - {% endif %} + {% for rebalance in rebalances_success %} + + + + + + + + + + + + + + {% endfor %}
Status Hash
{{ rebalance.requested|naturaltime }}---{% else %}title="{{ rebalance.start }}">{{ rebalance.start|naturaltime }}{% endif %} 1 %}title="{{ rebalance.stop }}">{{ rebalance.stop|naturaltime }}{% else %}>---{% endif %}{{ rebalance.duration }} minutes{% if rebalance.status == 2 %}{{ rebalance.stop|timeuntil:rebalance.start }}{% else %}---{% endif %}{{ rebalance.value|intcomma }}{{ rebalance.fee_limit|intcomma }}{{ rebalance.ppm|intcomma }}{% if rebalance.status == 2 %}{{ rebalance.fees_paid|intcomma }}{% else %}---{% endif %}{% if rebalance.target_alias == '' %}---{% else %}{{ rebalance.target_alias }}{% endif %}{% if rebalance.status == 0 %}Pending{% elif rebalance.status == 1 %}In-Flight{% elif rebalance.status == 2 %}Successful{% elif rebalance.status == 3 %}Timeout{% elif rebalance.status == 4 %}No Route{% elif rebalance.status == 5 %}Error{% elif rebalance.status == 6 %}Incorrect Payment Details{% elif rebalance.status == 7 %}Insufficient Balance{% elif rebalance.status == 400 %}Rebalancer Request Failed{% elif rebalance.status == 408 %}Rebalancer Request Timeout{% else %}{{ rebalance.status }}{% endif %}{% if rebalance.payment_hash == '' %}---{% else %}{{ rebalance.payment_hash }}{% endif %}
{{ rebalance.requested|naturaltime }}---{% else %}title="{{ rebalance.start }}">{{ rebalance.start|naturaltime }}{% endif %} 1 %}title="{{ rebalance.stop }}">{{ rebalance.stop|naturaltime }}{% else %}>---{% endif %}{{ rebalance.duration }} minutes{% if rebalance.status == 2 %}{{ rebalance.stop|timeuntil:rebalance.start }}{% else %}---{% endif %}{{ rebalance.value|intcomma }}{{ rebalance.fee_limit|intcomma }}{{ rebalance.ppm|intcomma }}{% if rebalance.status == 2 %}{{ rebalance.fees_paid|intcomma }}{% else %}---{% endif %}{% if rebalance.target_alias == '' %}---{% else %}{{ rebalance.target_alias }}{% endif %}{% if rebalance.status == 0 %}Pending{% elif rebalance.status == 1 %}In-Flight{% elif rebalance.status == 2 %}Successful{% elif rebalance.status == 3 %}Timeout{% elif rebalance.status == 4 %}No Route{% elif rebalance.status == 5 %}Error{% elif rebalance.status == 6 %}Incorrect Payment Details{% elif rebalance.status == 7 %}Insufficient Balance{% elif rebalance.status == 400 %}Rebalancer Request Failed{% elif rebalance.status == 408 %}Rebalancer Request Timeout{% else %}{{ rebalance.status }}{% endif %}{% if rebalance.payment_hash == '' %}---{% else %}{{ rebalance.payment_hash }}{% endif %}
+{% endif %} +{% if rebalances %}

Last 150 Rebalances

diff --git a/gui/views.py b/gui/views.py index 0236e645..6c012073 100644 --- a/gui/views.py +++ b/gui/views.py @@ -1469,10 +1469,20 @@ def invoices(request): @is_login_required(login_required(login_url='/lndg-admin/login/?next=/'), settings.LOGIN_REQUIRED) def rebalances(request): if request.method == 'GET': - context = { - 'rebalances': Rebalancer.objects.all().annotate(ppm=Round((Sum('fee_limit')*1000000)/Sum('value'), output_field=IntegerField())).order_by('-id')[:150], - } - return render(request, 'rebalances.html', context) + try: + rebalances = Rebalancer.objects.all().annotate(ppm=Round((Sum('fee_limit')*1000000)/Sum('value'), output_field=IntegerField())).order_by('-id') + rebalances_success = rebalances.filter(status=2) + context = { + 'rebalances': rebalances[:150], + 'rebalances_success' : rebalances_success[:69] + } + return render(request, 'rebalances.html', context) + except Exception as e: + try: + error = str(e.code()) + except: + error = str(e) + return render(request, 'error.html', {'error': error}) else: return redirect('home') From fea1d0f327a2dfd1e7dd5cd3aa600bc2cff1de4d Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Fri, 4 Nov 2022 14:26:26 -0400 Subject: [PATCH 74/87] Fix issue with divide by zero --- gui/views.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/gui/views.py b/gui/views.py index 8220d6a4..724601f9 100644 --- a/gui/views.py +++ b/gui/views.py @@ -1292,7 +1292,9 @@ def channel(request): channels_df['cv_30day'] = round((channels_df['revenue_30day']*1216.6667)/(channels_df['capacity']*outbound_ratio) + channels_df['assisted_apy_30day'], 2) channels_df['cv_7day'] = round((channels_df['revenue_7day']*5214.2857)/(channels_df['capacity']*outbound_ratio) + channels_df['assisted_apy_7day'], 2) channels_df['cv_1day'] = round((channels_df['revenue_1day']*36500)/(channels_df['capacity']*outbound_ratio) + channels_df['assisted_apy_1day'], 2) - autofees = Autofees.objects.filter(chan_id=chan_id).filter(timestamp__gte=filter_30day).order_by('-id').annotate(change=(Sum('new_value')-Sum('old_value'))*100/Sum('old_value')) + autofees_df = DataFrame.from_records(Autofees.objects.filter(chan_id=chan_id).filter(timestamp__gte=filter_30day).order_by('-id').values()) + if autofees_df.shape[0]> 0: + autofees_df['change'] = autofees_df.apply(lambda row: 0 if row.old_value == 0 else (row.new_value-row.old_value)*100/row.old_value, axis=1) else: channels_df = DataFrame() forwards_df = DataFrame() @@ -1301,7 +1303,7 @@ def channel(request): rebalancer_df = DataFrame() failed_htlc_df = DataFrame() peer_info_df = DataFrame() - autofees = [] + autofees_df = DataFrame() context = { 'chan_id': chan_id, 'channel': [] if channels_df.empty else channels_df.to_dict(orient='records')[0], @@ -1316,7 +1318,7 @@ def channel(request): 'network': 'testnet/' if settings.LND_NETWORK == 'testnet' else '', 'graph_links': graph_links(), 'network_links': network_links(), - 'autofees': autofees + 'autofees': [] if autofees_df.empty else autofees_df.to_dict(orient='records') } try: return render(request, 'channel.html', context) @@ -1735,11 +1737,13 @@ def autofees(request): if request.method == 'GET': chan_id = request.GET.urlencode()[1:] filter_7d = datetime.now() - timedelta(days=7) - autofees = Autofees.objects.filter(timestamp__gte=filter_7d).order_by('-id').annotate(change=(Sum('new_value')-Sum('old_value'))*100/Sum('old_value')) if chan_id == "" else Autofees.objects.filter(chan_id=chan_id).filter(timestamp__gte=filter_7d).order_by('-id').annotate(change=(Sum('new_value')-Sum('old_value'))*100/Sum('old_value')) + autofees_df = DataFrame.from_records(Autofees.objects.filter(timestamp__gte=filter_7d).order_by('-id').values() if chan_id == "" else Autofees.objects.filter(chan_id=chan_id).filter(timestamp__gte=filter_7d).order_by('-id').values()) + if autofees_df.shape[0]> 0: + autofees_df['change'] = autofees_df.apply(lambda row: 0 if row.old_value == 0 else (row.new_value-row.old_value)*100/row.old_value, axis=1) #print (f"{datetime.now().strftime('%c')} : {chan_id=} {autofees=}") try: context = { - 'autofees': autofees + 'autofees': [] if autofees_df.empty else autofees_df.to_dict(orient='records') } return render(request, 'autofees.html', context) except Exception as e: From 2648981f738ed0076862e26e62d007d43ec5832c Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Tue, 8 Nov 2022 19:15:21 -0500 Subject: [PATCH 75/87] Fix db divide by zero --- gui/views.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/gui/views.py b/gui/views.py index 724601f9..c9ee01d6 100644 --- a/gui/views.py +++ b/gui/views.py @@ -174,6 +174,8 @@ def home(request): pending_outbound = channels.filter(is_open=True).aggregate(Sum('pending_outbound'))['pending_outbound__sum'] if channels.filter(is_open=True).exists() else 0 pending_inbound = channels.filter(is_open=True).aggregate(Sum('pending_inbound'))['pending_inbound__sum'] if channels.filter(is_open=True).exists() else 0 num_updates = channels.filter(is_open=True).aggregate(Sum('num_updates'))['num_updates__sum'] if channels.filter(is_open=True).exists() else 0 + eligible_count = 0 + available_count = 0 detailed_active_channels = [] for channel in active_channels: detailed_channel = {} @@ -207,6 +209,14 @@ def home(request): detailed_channel['htlc_count'] = channel.htlc_count detailed_channel['auto_rebalance'] = channel.auto_rebalance detailed_channel['ar_in_target'] = channel.ar_in_target + detailed_channel['inbound_can'] = (detailed_channel['remote_balance']/channel.capacity)*100 + detailed_channel['outbound_can'] = (detailed_channel['local_balance']/channel.capacity)*100 + detailed_channel['fee_ratio'] = (channel.remote_fee_rate/channel.local_fee_rate)*100 + if channel.auto_rebalance == True and detailed_channel['inbound_can'] >= channel.ar_in_target and detailed_channel['fee_ratio'] <= channel.ar_max_cost: + print(channel.chan_id) + eligible_count += 1 + if channel.auto_rebalance == False and detailed_channel['outbound_can'] >= channel.ar_out_target: + available_count += 1 detailed_active_channels.append(detailed_channel) #Get current inactive channels inactive_channels = channels.filter(is_active=False, is_open=True, private=False).annotate(outbound_percent=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).annotate(inbound_percent=((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity')).order_by('outbound_percent') @@ -298,9 +308,9 @@ def home(request): '1day_payments_ppm': 0 if payments_1day_amt == 0 else int((total_1day_fees/payments_1day_amt)*1000000), '7day_payments_ppm': 0 if payments_7day_amt == 0 else int((total_7day_fees/payments_7day_amt)*1000000), 'liq_ratio': 0 if sum_outbound == 0 else int((sum_inbound/sum_outbound)*100), - 'eligible_count': channels.filter(is_active=True, is_open=True, private=False, auto_rebalance=True).annotate(inbound_can=((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity')).annotate(fee_ratio=(Sum('remote_fee_rate')*100)/Sum('local_fee_rate')).filter(inbound_can__gte=F('ar_in_target'), fee_ratio__lte=F('ar_max_cost')).count(), + 'eligible_count': eligible_count, 'enabled_count': channels.filter(is_open=True, auto_rebalance=True).count(), - 'available_count': channels.filter(is_active=True, is_open=True, private=False, auto_rebalance=False).annotate(outbound_can=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).filter(outbound_can__gte=F('ar_out_target')).count(), + 'available_count': available_count, 'network': 'testnet/' if settings.LND_NETWORK == 'testnet' else '', 'graph_links': graph_links(), 'network_links': network_links(), @@ -1675,7 +1685,6 @@ def rebalancing(request): eligible_count = 0 enabled_count = 0 available_count = 0 - try: query = request.GET.urlencode()[1:] if query == '1': From 5596350fc18de546f6ea2750d72cdaeec2f8a7cb Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Tue, 8 Nov 2022 19:18:53 -0500 Subject: [PATCH 76/87] Fix db divide by zero --- gui/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/views.py b/gui/views.py index c9ee01d6..1c925c49 100644 --- a/gui/views.py +++ b/gui/views.py @@ -211,7 +211,7 @@ def home(request): detailed_channel['ar_in_target'] = channel.ar_in_target detailed_channel['inbound_can'] = (detailed_channel['remote_balance']/channel.capacity)*100 detailed_channel['outbound_can'] = (detailed_channel['local_balance']/channel.capacity)*100 - detailed_channel['fee_ratio'] = (channel.remote_fee_rate/channel.local_fee_rate)*100 + detailed_channel['fee_ratio'] = 100 if channel.local_fee_rate == 0 else (channel.remote_fee_rate/channel.local_fee_rate)*100 if channel.auto_rebalance == True and detailed_channel['inbound_can'] >= channel.ar_in_target and detailed_channel['fee_ratio'] <= channel.ar_max_cost: print(channel.chan_id) eligible_count += 1 From d3ed052f5e6deb693735356603f2804b5c153531 Mon Sep 17 00:00:00 2001 From: Bitcoinite <89652545+Bitcoinite@users.noreply.github.com> Date: Wed, 9 Nov 2022 11:52:00 +0100 Subject: [PATCH 77/87] Fix title for iTarget% --- gui/templates/rebalancing.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/templates/rebalancing.html b/gui/templates/rebalancing.html index ffe67be0..bb626f26 100644 --- a/gui/templates/rebalancing.html +++ b/gui/templates/rebalancing.html @@ -21,7 +21,7 @@

Channel Rebalancing (currently scheduling {{ elig

- + From ff6ed084d358c1a932e19a94a978bec3944fca6d Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Thu, 10 Nov 2022 11:20:13 -0500 Subject: [PATCH 78/87] Remove debug print --- gui/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/gui/views.py b/gui/views.py index 1c925c49..b9a3efb6 100644 --- a/gui/views.py +++ b/gui/views.py @@ -213,7 +213,6 @@ def home(request): detailed_channel['outbound_can'] = (detailed_channel['local_balance']/channel.capacity)*100 detailed_channel['fee_ratio'] = 100 if channel.local_fee_rate == 0 else (channel.remote_fee_rate/channel.local_fee_rate)*100 if channel.auto_rebalance == True and detailed_channel['inbound_can'] >= channel.ar_in_target and detailed_channel['fee_ratio'] <= channel.ar_max_cost: - print(channel.chan_id) eligible_count += 1 if channel.auto_rebalance == False and detailed_channel['outbound_can'] >= channel.ar_out_target: available_count += 1 From f9166ac23c30c71e42652bf149cdc995f00ee89d Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Thu, 10 Nov 2022 18:30:58 +0000 Subject: [PATCH 79/87] AP - Do not disable ar_out_target 100 channels for AR if enabled --- rebalancer.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rebalancer.py b/rebalancer.py index c85cc0f7..1ca29377 100644 --- a/rebalancer.py +++ b/rebalancer.py @@ -193,7 +193,11 @@ def auto_enable(): for peer_channel in lookup_channels.filter(chan_id__in=chan_list): #print('Processing: ', peer_channel.alias, ' : ', peer_channel.chan_id, ' : ', oapD, " : ", iapD, ' : ', outbound_percent, ' : ', inbound_percent) - if oapD > (iapD*1.10) and outbound_percent > 75: + if peer_channel.ar_out_target == 100 and peer_channel.auto_rebalance == True: + #Special Case for LOOP, Wos, etc. Always Auto Rebalance if enabled to keep outbound full. + print (f"{datetime.now().strftime('%c')} : Pass {peer_channel.alias=} {peer_channel.chan_id=} {peer_channel.ar_out_target=} {peer_channel.auto_rebalance=}") + pass + elif oapD > (iapD*1.10) and outbound_percent > 75: #print('Case 1: Pass') pass elif oapD > (iapD*1.10) and inbound_percent > 75 and peer_channel.auto_rebalance == False: From 711b16bac334b88381d903b6d052c3efa4871a50 Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Fri, 11 Nov 2022 08:27:23 -0500 Subject: [PATCH 80/87] Comment nginx user --- nginx.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nginx.sh b/nginx.sh index cf158be2..100410bf 100644 --- a/nginx.sh +++ b/nginx.sh @@ -87,7 +87,8 @@ EOF function setup_nginx() { cat << EOF > /etc/nginx/sites-enabled/lndg -user $INSTALL_USER +# the below setting can sometimes help resolve permission issues +# user $INSTALL_USER upstream django { server unix://$HOME_DIR/lndg/lndg.sock; # for a file socket From 56551ee1dbece28c163bb391acf5a322c72a8332 Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Sun, 13 Nov 2022 08:27:04 -0500 Subject: [PATCH 81/87] Small updates, fix active count when private chan online --- gui/templates/channel.html | 6 +++--- gui/templates/home.html | 2 +- gui/views.py | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/gui/templates/channel.html b/gui/templates/channel.html index efa65944..c29a5ea5 100644 --- a/gui/templates/channel.html +++ b/gui/templates/channel.html @@ -376,13 +376,13 @@

Last 5 Failed HTLCs

- - + + - + {% endfor %}
Target Amt Max Cost % oTarget%iTarget%iTarget% AR 7-Day Rate Active{{ failed_htlc.timestamp|naturaltime }} {{ failed_htlc.chan_id_in }} {{ failed_htlc.chan_id_out }}{% if failed_htlc.chan_in_alias == '' %}---{% else %}{{ failed_htlc.chan_in_alias }}{% endif %}{% if failed_htlc.chan_out_alias == '' %}---{% else %}{{ failed_htlc.chan_out_alias }}{% endif %}{% if failed_htlc.chan_in_alias == '' %}---{% else %}{{ failed_htlc.chan_in_alias }}{% endif %}{% if failed_htlc.chan_out_alias == '' %}---{% else %}{{ failed_htlc.chan_out_alias }}{% endif %} {{ failed_htlc.amount|intcomma }} {{ failed_htlc.chan_out_liq|intcomma }} ({{ failed_htlc.chan_out_pending|intcomma }}) {{ failed_htlc.missed_fee|intcomma }} {% if failed_htlc.wire_failure == 15 %}Temporary Channel Failure{% elif failed_htlc.wire_failure == 18 %}Unknown Next Peer{% elif failed_htlc.wire_failure == 12 %}Fee Insufficient{% else %}{{ failed_htlc.wire_failure }}{% endif %}{% if failed_htlc.failure_detail == 1 %}---{% elif failed_htlc.failure_detail == 5 %}HTLC Exceeds Max{% elif failed_htlc.failure_detail == 6 %}Insufficient Balance{% elif failed_htlc.failure_detail == 20 %}Invalid Keysend{% elif failed_htlc.failure_detail == 22 %}Circular Route{% else %}{{ failed_htlc.failure_detail }}{% endif %}{% if failed_htlc.failure_detail == 1 %}---{% elif failed_htlc.failure_detail == 5 %}HTLC Exceeds Max{% elif failed_htlc.failure_detail == 6 %}Insufficient Balance{% elif failed_htlc.failure_detail == 13 %}Invoice Not Open{% elif failed_htlc.failure_detail == 20 %}Invalid Keysend{% elif failed_htlc.failure_detail == 22 %}Circular Route{% else %}{{ failed_htlc.failure_detail }}{% endif %}
diff --git a/gui/templates/home.html b/gui/templates/home.html index ba6fa3bd..d8a1c57b 100644 --- a/gui/templates/home.html +++ b/gui/templates/home.html @@ -10,7 +10,7 @@ document.getElementById("datetime").innerHTML = dt.toLocaleTimeString();

{{ node_info.alias }} | {{ node_info.identity_pubkey }}

-

Public Capacity: {{ total_capacity|intcomma }} | Active Channels: {{ node_info.num_active_channels }} / {{ total_channels }} | Peers: {{ node_info.num_peers }} | DB Size: {% if db_size > 0 %}{{ db_size }} GB{% else %}---{% endif %} | Total States Updates: {% if num_updates > 0 %}{{ num_updates|intcomma }} {% else %}---{% endif %}

+

Public Capacity: {{ total_capacity|intcomma }} | Active Channels: {{ active_count }} / {{ total_channels }} | Peers: {{ node_info.num_peers }} | DB Size: {% if db_size > 0 %}{{ db_size }} GB{% else %}---{% endif %} | Total States Updates: {% if num_updates > 0 %}{{ num_updates|intcomma }} {% else %}---{% endif %}

{% if total_private > 0 %}

Private Capacity: {{ private_capacity|intcomma }} | Locked Liquidity: {{ private_outbound|intcomma }} | Active Private Channels: {{ active_private }} / {{ total_private }}

{% endif %}

Public Address: {% for info in node_info.uris %}{{ info }} | {% endfor %}

Lnd sync: {{ node_info.synced_to_graph }} | chain sync: {{ node_info.synced_to_chain }} | {% for info in node_info.chains %}{{ info }}{% endfor %} | {{ node_info.block_height }} | {{ node_info.block_hash }}

diff --git a/gui/views.py b/gui/views.py index b9a3efb6..1daa2219 100644 --- a/gui/views.py +++ b/gui/views.py @@ -242,6 +242,7 @@ def home(request): total_costs_1day = total_1day_fees + onchain_costs_1day #Get list of recent rebalance requests rebalances = Rebalancer.objects.all().annotate(ppm=Round((Sum('fee_limit')*1000000)/Sum('value'), output_field=IntegerField())).order_by('-id') + active_count = node_info.num_active_channels - active_private total_channels = node_info.num_active_channels + node_info.num_inactive_channels - private_count local_settings = LocalSettings.objects.filter(key__contains='AR-').order_by('key') try: @@ -251,6 +252,7 @@ def home(request): #Build context for front-end and render page context = { 'node_info': node_info, + 'active_count': active_count, 'total_channels': total_channels, 'balances': balances, 'total_balance': balances.total_balance + sum_outbound + pending_open_balance + limbo_balance + private_outbound, @@ -1303,7 +1305,7 @@ def channel(request): channels_df['cv_1day'] = round((channels_df['revenue_1day']*36500)/(channels_df['capacity']*outbound_ratio) + channels_df['assisted_apy_1day'], 2) autofees_df = DataFrame.from_records(Autofees.objects.filter(chan_id=chan_id).filter(timestamp__gte=filter_30day).order_by('-id').values()) if autofees_df.shape[0]> 0: - autofees_df['change'] = autofees_df.apply(lambda row: 0 if row.old_value == 0 else (row.new_value-row.old_value)*100/row.old_value, axis=1) + autofees_df['change'] = autofees_df.apply(lambda row: 0 if row.old_value == 0 else round((row.new_value-row.old_value)*100/row.old_value, 1), axis=1) else: channels_df = DataFrame() forwards_df = DataFrame() @@ -1747,7 +1749,7 @@ def autofees(request): filter_7d = datetime.now() - timedelta(days=7) autofees_df = DataFrame.from_records(Autofees.objects.filter(timestamp__gte=filter_7d).order_by('-id').values() if chan_id == "" else Autofees.objects.filter(chan_id=chan_id).filter(timestamp__gte=filter_7d).order_by('-id').values()) if autofees_df.shape[0]> 0: - autofees_df['change'] = autofees_df.apply(lambda row: 0 if row.old_value == 0 else (row.new_value-row.old_value)*100/row.old_value, axis=1) + autofees_df['change'] = autofees_df.apply(lambda row: 0 if row.old_value == 0 else round((row.new_value-row.old_value)*100/row.old_value, 1), axis=1) #print (f"{datetime.now().strftime('%c')} : {chan_id=} {autofees=}") try: context = { From 1ec2f4c81d770a8b20d6d9823e7e50d52c443770 Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Sun, 13 Nov 2022 08:34:59 -0500 Subject: [PATCH 82/87] Outgoing htlc hash link on channel page --- gui/templates/channel.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gui/templates/channel.html b/gui/templates/channel.html index c29a5ea5..b8e672e3 100644 --- a/gui/templates/channel.html +++ b/gui/templates/channel.html @@ -167,7 +167,7 @@

Outgoing HTLCs

{% if htlc.forwarding_alias == '' %}---{% else %}{{ htlc.forwarding_alias }}{% endif %} {{ htlc.amount|intcomma }} {{ htlc.expiration_height|intcomma }} - {{ htlc.hash_lock }} + {{ htlc.hash_lock }} {% endfor %} From 99213d39a5fe19b5ed58b0fab095a2882271e8b7 Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Sun, 13 Nov 2022 09:24:54 -0500 Subject: [PATCH 83/87] Fix issue with AF updates not applying to pending channels --- jobs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jobs.py b/jobs.py index 68c9de1f..861526b1 100644 --- a/jobs.py +++ b/jobs.py @@ -333,7 +333,7 @@ def update_channels(stub): db_channel.local_fee_rate = fee_rate db_channel.local_cltv = cltv db_channel.fees_updated = datetime.now() - if pending_channel.auto_rebalance: + if pending_channel.auto_rebalance is not None: db_channel.auto_rebalance = pending_channel.auto_rebalance if pending_channel.ar_amt_target: db_channel.ar_amt_target = pending_channel.ar_amt_target @@ -343,7 +343,7 @@ def update_channels(stub): db_channel.ar_out_target = pending_channel.ar_out_target if pending_channel.ar_max_cost: db_channel.ar_max_cost = pending_channel.ar_max_cost - if pending_channel.auto_fees: + if pending_channel.auto_fees is not None: db_channel.auto_fees = pending_channel.auto_fees pending_channel.delete() db_channel.save() From 09b7d7ca79cbd632b275703b29cb894577878e02 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Tue, 15 Nov 2022 12:47:51 +0000 Subject: [PATCH 84/87] Rapidfire up/down + prioritise remote balance for rebalance --- jobs.py | 16 ++++++++++++---- rebalancer.py | 32 ++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/jobs.py b/jobs.py index 861526b1..77b7ec88 100644 --- a/jobs.py +++ b/jobs.py @@ -85,7 +85,10 @@ def update_payment(stub, payment, self_pubkey): if hop_count == total_hops and hop.pub_key == self_pubkey and db_payment.rebal_chan is None: db_payment.rebal_chan = hop.chan_id db_payment.save() - adjust_ar_amt( payment, db_payment.rebal_chan ) + try: + adjust_ar_amt( payment, db_payment.rebal_chan ) + except Exception as e: + print (f"{datetime.now().strftime('%c')} : Error adjusting AR Amount {payment=} {db_payment.rebal_chan=} : {str(e)=}") def adjust_ar_amt( payment, chan_id ): if payment.status not in (2,3): @@ -118,6 +121,7 @@ def adjust_ar_amt( payment, chan_id ): if payment.status == 3: estimated_liquidity = 0 + attempt = None for attempt in payment.htlcs: total_hops=len(attempt.route.hops) #Failure Codes https://github.com/lightningnetwork/lnd/blob/9f013f5058a7780075bca393acfa97aa0daec6a0/lnrpc/lightning.proto#L4200 @@ -128,9 +132,13 @@ def adjust_ar_amt( payment, chan_id ): print (f"{datetime.now().strftime('%c')} : Liquidity Estimation {attempt.attempt_id=} {attempt.status=} {attempt.failure.code=} {chan_id=} {attempt.route.total_amt=} {payment.value_msat/1000=} {estimated_liquidity=} {payment.payment_hash=}") if estimated_liquidity == 0: - #Could not estimate liquidity, reduce by half - estimated_liquidity = db_channel.ar_amt_target/2 if db_channel is not None else 0 - print (f"{datetime.now().strftime('%c')} : Liquidity Estimation not possible, halving {attempt.attempt_id=} {attempt.status=} {attempt.failure.code=} {chan_id=} {attempt.route.total_amt=} {payment.value_msat/1000=} {estimated_liquidity=} {payment.payment_hash=}") + if attempt is not None: + #Could not estimate liquidity for valid attempts, reduce by half + estimated_liquidity = db_channel.ar_amt_target/2 if db_channel is not None else 0 + print (f"{datetime.now().strftime('%c')} : Liquidity Estimation not possible, halving {attempt.attempt_id=} {attempt.status=} {attempt.failure.code=} {chan_id=} {attempt.route.total_amt=} {payment.value_msat/1000=} {estimated_liquidity=} {payment.payment_hash=}") + else: + #Mostly a case of NO ROUTE + print (f"{datetime.now().strftime('%c')} : Liquidity Estimation not performed {payment.payment_hash=} {payment.status=} {chan_id=} {estimated_liquidity=} {attempt=}") if payment.value_msat/1000 >= lower_limit and estimated_liquidity <= payment.value_msat/1000 and estimated_liquidity > 0: #Change AR amount. Ignore zero liquidity case which implies breakout from rapid fire AR diff --git a/rebalancer.py b/rebalancer.py index 1ca29377..bff5e142 100644 --- a/rebalancer.py +++ b/rebalancer.py @@ -77,14 +77,34 @@ def run_rebalancer(rebalance): finally: rebalance.stop = datetime.now() rebalance.save() - if rebalance.status == 2: + original_alias = rebalance.target_alias + inc=1.21 + dec=2 + + if rebalance.status ==2: update_channels(stub, rebalance.last_hop_pubkey, successful_out) - auto_rebalance_channels = Channels.objects.filter(is_active=True, is_open=True, private=False).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).annotate(inbound_can=(((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity'))/Sum('ar_in_target')) - inbound_cans = auto_rebalance_channels.filter(remote_pubkey=rebalance.last_hop_pubkey).filter(auto_rebalance=True, inbound_can__gte=1) - outbound_cans = list(auto_rebalance_channels.filter(auto_rebalance=False, percent_outbound__gte=F('ar_out_target')).values_list('chan_id', flat=True)) + + auto_rebalance_channels = Channels.objects.filter(is_active=True, is_open=True, private=False).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).annotate(inbound_can=(((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity'))/Sum('ar_in_target')) + inbound_cans = auto_rebalance_channels.filter(remote_pubkey=rebalance.last_hop_pubkey).filter(auto_rebalance=True, inbound_can__gte=1) + outbound_cans = list(auto_rebalance_channels.filter(auto_rebalance=False, percent_outbound__gte=F('ar_out_target')).values_list('chan_id', flat=True)) + + if rebalance.status ==2: + + rebalance.target_alias += ' ==> (' + str(int(payment_response.fee_msat/payment_response.value_msat*1000000)) + ')' + + if len(inbound_cans) > 0 and len(outbound_cans) > 0: + next_rebalance = Rebalancer(value=int(rebalance.value*inc), fee_limit=int(rebalance.fee_limit*inc), outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=original_alias, duration=1) + next_rebalance.save() + print (f"{datetime.now().strftime('%c')} : RapidFire up {next_rebalance.target_alias=} {next_rebalance.value=} {rebalance.value=}") + + else: + next_rebalance = None + elif rebalance.status > 2 and rebalance.duration <= 1 and rebalance.value > 69420: + #Previous Rapidfire with increased value failed, try with lower value up to 69420. if len(inbound_cans) > 0 and len(outbound_cans) > 0: - next_rebalance = Rebalancer(value=rebalance.value, fee_limit=rebalance.fee_limit, outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=rebalance.target_alias, duration=1) + next_rebalance = Rebalancer(value=int(rebalance.value/dec), fee_limit=int(rebalance.fee_limit/dec), outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=original_alias, duration=1) next_rebalance.save() + print (f"{datetime.now().strftime('%c')} : RapidFire Down {next_rebalance.target_alias=} {next_rebalance.value=} {rebalance.value=}") else: next_rebalance = None else: @@ -120,7 +140,7 @@ def auto_schedule(): if not LocalSettings.objects.filter(key='AR-Inbound%').exists(): LocalSettings(key='AR-Inbound%', value='100').save() outbound_cans = list(auto_rebalance_channels.filter(auto_rebalance=False, percent_outbound__gte=F('ar_out_target')).values_list('chan_id', flat=True)) - inbound_cans = auto_rebalance_channels.filter(auto_rebalance=True, inbound_can__gte=1) + inbound_cans = auto_rebalance_channels.filter(auto_rebalance=True, inbound_can__gte=1).order_by('-remote_balance') if len(inbound_cans) > 0 and len(outbound_cans) > 0: if LocalSettings.objects.filter(key='AR-MaxFeeRate').exists(): max_fee_rate = int(LocalSettings.objects.filter(key='AR-MaxFeeRate')[0].value) From 77a48330961a326584f86357b5cc6c7fb26dc39f Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Tue, 15 Nov 2022 14:29:14 +0000 Subject: [PATCH 85/87] Remove Alias overwrite --- rebalancer.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rebalancer.py b/rebalancer.py index bff5e142..8d45557a 100644 --- a/rebalancer.py +++ b/rebalancer.py @@ -76,7 +76,7 @@ def run_rebalancer(rebalance): print(error) finally: rebalance.stop = datetime.now() - rebalance.save() + original_alias = rebalance.target_alias inc=1.21 dec=2 @@ -90,7 +90,7 @@ def run_rebalancer(rebalance): if rebalance.status ==2: - rebalance.target_alias += ' ==> (' + str(int(payment_response.fee_msat/payment_response.value_msat*1000000)) + ')' + #rebalance.target_alias += ' ==> (' + str(int(payment_response.fee_msat/payment_response.value_msat*1000000)) + ')' if len(inbound_cans) > 0 and len(outbound_cans) > 0: next_rebalance = Rebalancer(value=int(rebalance.value*inc), fee_limit=int(rebalance.fee_limit*inc), outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=original_alias, duration=1) @@ -109,6 +109,9 @@ def run_rebalancer(rebalance): next_rebalance = None else: next_rebalance = None + + rebalance.save() + return next_rebalance def update_channels(stub, incoming_channel, outgoing_channel): From 124ee536c13b4e17fc9579aa9d6d4fb5789faa41 Mon Sep 17 00:00:00 2001 From: BhaagBoseDK Date: Tue, 15 Nov 2022 16:27:21 +0000 Subject: [PATCH 86/87] iteration 2 corrections --- rebalancer.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/rebalancer.py b/rebalancer.py index 8d45557a..ba30d1cd 100644 --- a/rebalancer.py +++ b/rebalancer.py @@ -76,21 +76,16 @@ def run_rebalancer(rebalance): print(error) finally: rebalance.stop = datetime.now() - + rebalance.save() original_alias = rebalance.target_alias inc=1.21 dec=2 if rebalance.status ==2: update_channels(stub, rebalance.last_hop_pubkey, successful_out) - - auto_rebalance_channels = Channels.objects.filter(is_active=True, is_open=True, private=False).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).annotate(inbound_can=(((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity'))/Sum('ar_in_target')) - inbound_cans = auto_rebalance_channels.filter(remote_pubkey=rebalance.last_hop_pubkey).filter(auto_rebalance=True, inbound_can__gte=1) - outbound_cans = list(auto_rebalance_channels.filter(auto_rebalance=False, percent_outbound__gte=F('ar_out_target')).values_list('chan_id', flat=True)) - - if rebalance.status ==2: - - #rebalance.target_alias += ' ==> (' + str(int(payment_response.fee_msat/payment_response.value_msat*1000000)) + ')' + auto_rebalance_channels = Channels.objects.filter(is_active=True, is_open=True, private=False).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).annotate(inbound_can=(((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity'))/Sum('ar_in_target')) + inbound_cans = auto_rebalance_channels.filter(remote_pubkey=rebalance.last_hop_pubkey).filter(auto_rebalance=True, inbound_can__gte=1) + outbound_cans = list(auto_rebalance_channels.filter(auto_rebalance=False, percent_outbound__gte=F('ar_out_target')).exclude(remote_pubkey=rebalance.last_hop_pubkey).values_list('chan_id', flat=True)) if len(inbound_cans) > 0 and len(outbound_cans) > 0: next_rebalance = Rebalancer(value=int(rebalance.value*inc), fee_limit=int(rebalance.fee_limit*inc), outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=original_alias, duration=1) @@ -101,6 +96,7 @@ def run_rebalancer(rebalance): next_rebalance = None elif rebalance.status > 2 and rebalance.duration <= 1 and rebalance.value > 69420: #Previous Rapidfire with increased value failed, try with lower value up to 69420. + inbound_cans = auto_rebalance_channels.filter(remote_pubkey=rebalance.last_hop_pubkey).filter(auto_rebalance=True, inbound_can__gte=1) if len(inbound_cans) > 0 and len(outbound_cans) > 0: next_rebalance = Rebalancer(value=int(rebalance.value/dec), fee_limit=int(rebalance.fee_limit/dec), outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=original_alias, duration=1) next_rebalance.save() @@ -110,8 +106,6 @@ def run_rebalancer(rebalance): else: next_rebalance = None - rebalance.save() - return next_rebalance def update_channels(stub, incoming_channel, outgoing_channel): From e6c67e9a3705366cabf0e547ef769174973668ed Mon Sep 17 00:00:00 2001 From: cryptosharks131 Date: Sun, 20 Nov 2022 12:03:56 -0500 Subject: [PATCH 87/87] Rapid fire fee adjust as float --- rebalancer.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rebalancer.py b/rebalancer.py index ba30d1cd..1da49980 100644 --- a/rebalancer.py +++ b/rebalancer.py @@ -80,32 +80,28 @@ def run_rebalancer(rebalance): original_alias = rebalance.target_alias inc=1.21 dec=2 - if rebalance.status ==2: update_channels(stub, rebalance.last_hop_pubkey, successful_out) auto_rebalance_channels = Channels.objects.filter(is_active=True, is_open=True, private=False).annotate(percent_outbound=((Sum('local_balance')+Sum('pending_outbound'))*100)/Sum('capacity')).annotate(inbound_can=(((Sum('remote_balance')+Sum('pending_inbound'))*100)/Sum('capacity'))/Sum('ar_in_target')) inbound_cans = auto_rebalance_channels.filter(remote_pubkey=rebalance.last_hop_pubkey).filter(auto_rebalance=True, inbound_can__gte=1) outbound_cans = list(auto_rebalance_channels.filter(auto_rebalance=False, percent_outbound__gte=F('ar_out_target')).exclude(remote_pubkey=rebalance.last_hop_pubkey).values_list('chan_id', flat=True)) - if len(inbound_cans) > 0 and len(outbound_cans) > 0: - next_rebalance = Rebalancer(value=int(rebalance.value*inc), fee_limit=int(rebalance.fee_limit*inc), outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=original_alias, duration=1) + next_rebalance = Rebalancer(value=int(rebalance.value*inc), fee_limit=round(rebalance.fee_limit*inc, 3), outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=original_alias, duration=1) next_rebalance.save() print (f"{datetime.now().strftime('%c')} : RapidFire up {next_rebalance.target_alias=} {next_rebalance.value=} {rebalance.value=}") - else: next_rebalance = None elif rebalance.status > 2 and rebalance.duration <= 1 and rebalance.value > 69420: #Previous Rapidfire with increased value failed, try with lower value up to 69420. inbound_cans = auto_rebalance_channels.filter(remote_pubkey=rebalance.last_hop_pubkey).filter(auto_rebalance=True, inbound_can__gte=1) if len(inbound_cans) > 0 and len(outbound_cans) > 0: - next_rebalance = Rebalancer(value=int(rebalance.value/dec), fee_limit=int(rebalance.fee_limit/dec), outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=original_alias, duration=1) + next_rebalance = Rebalancer(value=int(rebalance.value/dec), fee_limit=round(rebalance.fee_limit/dec, 3), outgoing_chan_ids=str(outbound_cans).replace('\'', ''), last_hop_pubkey=rebalance.last_hop_pubkey, target_alias=original_alias, duration=1) next_rebalance.save() print (f"{datetime.now().strftime('%c')} : RapidFire Down {next_rebalance.target_alias=} {next_rebalance.value=} {rebalance.value=}") else: next_rebalance = None else: next_rebalance = None - return next_rebalance def update_channels(stub, incoming_channel, outgoing_channel):