mirror of
https://github.com/cryptosharks131/lndg.git
synced 2026-08-13 12:33:04 +02:00
inbound fees (#391)
This commit is contained in:
parent
9c8838b8d8
commit
b1f1419e45
10 changed files with 872 additions and 2280 deletions
|
|
@ -84,6 +84,8 @@ updates_channel_codes = [
|
|||
(9, 'cltv'),
|
||||
(10, 'min_htlc'),
|
||||
(11, 'max_htlc'),
|
||||
(12, 'inbound_base_fee'),
|
||||
(13, 'inbound_fee_rate'),
|
||||
]
|
||||
|
||||
class UpdateChannel(forms.Form):
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -112,6 +112,11 @@ class LightningStub(object):
|
|||
request_serializer=lightning__pb2.GetInfoRequest.SerializeToString,
|
||||
response_deserializer=lightning__pb2.GetInfoResponse.FromString,
|
||||
)
|
||||
self.GetDebugInfo = channel.unary_unary(
|
||||
'/lnrpc.Lightning/GetDebugInfo',
|
||||
request_serializer=lightning__pb2.GetDebugInfoRequest.SerializeToString,
|
||||
response_deserializer=lightning__pb2.GetDebugInfoResponse.FromString,
|
||||
)
|
||||
self.GetRecoveryInfo = channel.unary_unary(
|
||||
'/lnrpc.Lightning/GetRecoveryInfo',
|
||||
request_serializer=lightning__pb2.GetRecoveryInfoRequest.SerializeToString,
|
||||
|
|
@ -357,6 +362,16 @@ class LightningStub(object):
|
|||
request_serializer=lightning__pb2.SubscribeCustomMessagesRequest.SerializeToString,
|
||||
response_deserializer=lightning__pb2.CustomMessage.FromString,
|
||||
)
|
||||
self.ListAliases = channel.unary_unary(
|
||||
'/lnrpc.Lightning/ListAliases',
|
||||
request_serializer=lightning__pb2.ListAliasesRequest.SerializeToString,
|
||||
response_deserializer=lightning__pb2.ListAliasesResponse.FromString,
|
||||
)
|
||||
self.LookupHtlcResolution = channel.unary_unary(
|
||||
'/lnrpc.Lightning/LookupHtlcResolution',
|
||||
request_serializer=lightning__pb2.LookupHtlcResolutionRequest.SerializeToString,
|
||||
response_deserializer=lightning__pb2.LookupHtlcResolutionResponse.FromString,
|
||||
)
|
||||
|
||||
|
||||
class LightningServicer(object):
|
||||
|
|
@ -487,8 +502,10 @@ class LightningServicer(object):
|
|||
|
||||
def VerifyMessage(self, request, context):
|
||||
"""lncli: `verifymessage`
|
||||
VerifyMessage verifies a signature over a msg. The signature must be
|
||||
zbase32 encoded and signed by an active node in the resident node's
|
||||
VerifyMessage verifies a signature over a message and recovers the signer's
|
||||
public key. The signature is only deemed valid if the recovered public key
|
||||
corresponds to a node key in the public Lightning network. The signature
|
||||
must be zbase32 encoded and signed by an active node in the resident node's
|
||||
channel database. In addition to returning the validity of the signature,
|
||||
VerifyMessage also returns the recovered pubkey from the signature.
|
||||
"""
|
||||
|
|
@ -544,6 +561,16 @@ class LightningServicer(object):
|
|||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def GetDebugInfo(self, request, context):
|
||||
"""lncli: 'getdebuginfo'
|
||||
GetDebugInfo returns debug information concerning the state of the daemon
|
||||
and its subsystems. This includes the full configuration and the latest log
|
||||
entries from the log file.
|
||||
"""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def GetRecoveryInfo(self, request, context):
|
||||
"""* lncli: `getrecoveryinfo`
|
||||
GetRecoveryInfo returns information concerning the recovery mode including
|
||||
|
|
@ -773,7 +800,7 @@ class LightningServicer(object):
|
|||
optionally specify the add_index and/or the settle_index. If the add_index
|
||||
is specified, then we'll first start by sending add invoice events for all
|
||||
invoices with an add_index greater than the specified value. If the
|
||||
settle_index is specified, the next, we'll send out all settle events for
|
||||
settle_index is specified, then next, we'll send out all settle events for
|
||||
invoices with a settle_index greater than the specified value. One or both
|
||||
of these fields can be set. If no fields are set, then we'll only send out
|
||||
the latest add/settle events.
|
||||
|
|
@ -801,7 +828,7 @@ class LightningServicer(object):
|
|||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def DeletePayment(self, request, context):
|
||||
"""
|
||||
"""lncli: `deletepayments`
|
||||
DeletePayment deletes an outgoing payment from DB. Note that it will not
|
||||
attempt to delete an In-Flight payment, since that would be unsafe.
|
||||
"""
|
||||
|
|
@ -810,7 +837,7 @@ class LightningServicer(object):
|
|||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def DeleteAllPayments(self, request, context):
|
||||
"""
|
||||
"""lncli: `deletepayments --all`
|
||||
DeleteAllPayments deletes all outgoing payments from DB. Note that it will
|
||||
not attempt to delete In-Flight payments, since that would be unsafe.
|
||||
"""
|
||||
|
|
@ -981,7 +1008,7 @@ class LightningServicer(object):
|
|||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def VerifyChanBackup(self, request, context):
|
||||
"""
|
||||
"""lncli: `verifychanbackup`
|
||||
VerifyChanBackup allows a caller to verify the integrity of a channel backup
|
||||
snapshot. This method will accept either a packed Single or a packed Multi.
|
||||
Specifying both will result in an error.
|
||||
|
|
@ -1092,6 +1119,30 @@ class LightningServicer(object):
|
|||
"""lncli: `subscribecustom`
|
||||
SubscribeCustomMessages subscribes to a stream of incoming custom peer
|
||||
messages.
|
||||
|
||||
To include messages with type outside of the custom range (>= 32768) lnd
|
||||
needs to be compiled with the `dev` build tag, and the message type to
|
||||
override should be specified in lnd's experimental protocol configuration.
|
||||
"""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def ListAliases(self, request, context):
|
||||
"""lncli: `listaliases`
|
||||
ListAliases returns the set of all aliases that have ever existed with
|
||||
their confirmed SCID (if it exists) and/or the base SCID (in the case of
|
||||
zero conf).
|
||||
"""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def LookupHtlcResolution(self, request, context):
|
||||
"""
|
||||
LookupHtlcResolution retrieves a final htlc resolution from the database.
|
||||
If the htlc has no final resolution yet, a NotFound grpc status code is
|
||||
returned.
|
||||
"""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
|
|
@ -1180,6 +1231,11 @@ def add_LightningServicer_to_server(servicer, server):
|
|||
request_deserializer=lightning__pb2.GetInfoRequest.FromString,
|
||||
response_serializer=lightning__pb2.GetInfoResponse.SerializeToString,
|
||||
),
|
||||
'GetDebugInfo': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.GetDebugInfo,
|
||||
request_deserializer=lightning__pb2.GetDebugInfoRequest.FromString,
|
||||
response_serializer=lightning__pb2.GetDebugInfoResponse.SerializeToString,
|
||||
),
|
||||
'GetRecoveryInfo': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.GetRecoveryInfo,
|
||||
request_deserializer=lightning__pb2.GetRecoveryInfoRequest.FromString,
|
||||
|
|
@ -1425,6 +1481,16 @@ def add_LightningServicer_to_server(servicer, server):
|
|||
request_deserializer=lightning__pb2.SubscribeCustomMessagesRequest.FromString,
|
||||
response_serializer=lightning__pb2.CustomMessage.SerializeToString,
|
||||
),
|
||||
'ListAliases': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.ListAliases,
|
||||
request_deserializer=lightning__pb2.ListAliasesRequest.FromString,
|
||||
response_serializer=lightning__pb2.ListAliasesResponse.SerializeToString,
|
||||
),
|
||||
'LookupHtlcResolution': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.LookupHtlcResolution,
|
||||
request_deserializer=lightning__pb2.LookupHtlcResolutionRequest.FromString,
|
||||
response_serializer=lightning__pb2.LookupHtlcResolutionResponse.SerializeToString,
|
||||
),
|
||||
}
|
||||
generic_handler = grpc.method_handlers_generic_handler(
|
||||
'lnrpc.Lightning', rpc_method_handlers)
|
||||
|
|
@ -1725,6 +1791,23 @@ class Lightning(object):
|
|||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
|
||||
@staticmethod
|
||||
def GetDebugInfo(request,
|
||||
target,
|
||||
options=(),
|
||||
channel_credentials=None,
|
||||
call_credentials=None,
|
||||
insecure=False,
|
||||
compression=None,
|
||||
wait_for_ready=None,
|
||||
timeout=None,
|
||||
metadata=None):
|
||||
return grpc.experimental.unary_unary(request, target, '/lnrpc.Lightning/GetDebugInfo',
|
||||
lightning__pb2.GetDebugInfoRequest.SerializeToString,
|
||||
lightning__pb2.GetDebugInfoResponse.FromString,
|
||||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
|
||||
@staticmethod
|
||||
def GetRecoveryInfo(request,
|
||||
target,
|
||||
|
|
@ -2557,3 +2640,37 @@ class Lightning(object):
|
|||
lightning__pb2.CustomMessage.FromString,
|
||||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
|
||||
@staticmethod
|
||||
def ListAliases(request,
|
||||
target,
|
||||
options=(),
|
||||
channel_credentials=None,
|
||||
call_credentials=None,
|
||||
insecure=False,
|
||||
compression=None,
|
||||
wait_for_ready=None,
|
||||
timeout=None,
|
||||
metadata=None):
|
||||
return grpc.experimental.unary_unary(request, target, '/lnrpc.Lightning/ListAliases',
|
||||
lightning__pb2.ListAliasesRequest.SerializeToString,
|
||||
lightning__pb2.ListAliasesResponse.FromString,
|
||||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
|
||||
@staticmethod
|
||||
def LookupHtlcResolution(request,
|
||||
target,
|
||||
options=(),
|
||||
channel_credentials=None,
|
||||
call_credentials=None,
|
||||
insecure=False,
|
||||
compression=None,
|
||||
wait_for_ready=None,
|
||||
timeout=None,
|
||||
metadata=None):
|
||||
return grpc.experimental.unary_unary(request, target, '/lnrpc.Lightning/LookupHtlcResolution',
|
||||
lightning__pb2.LookupHtlcResolutionRequest.SerializeToString,
|
||||
lightning__pb2.LookupHtlcResolutionResponse.FromString,
|
||||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
# Generated by Django 5.0.2 on 2024-05-08 22:27
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gui', '0037_tradesales'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='channels',
|
||||
name='local_inbound_base_fee',
|
||||
field=models.IntegerField(default=0),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='channels',
|
||||
name='local_inbound_fee_rate',
|
||||
field=models.IntegerField(default=0),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='channels',
|
||||
name='remote_inbound_base_fee',
|
||||
field=models.IntegerField(default=0),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='channels',
|
||||
name='remote_inbound_fee_rate',
|
||||
field=models.IntegerField(default=0),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='forwards',
|
||||
name='inbound_fee',
|
||||
field=models.FloatField(default=0),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
||||
|
|
@ -60,6 +60,7 @@ class Forwards(models.Model):
|
|||
amt_in_msat = models.BigIntegerField()
|
||||
amt_out_msat = models.BigIntegerField()
|
||||
fee = models.FloatField()
|
||||
inbound_fee = models.FloatField()
|
||||
class Meta:
|
||||
app_label = 'gui'
|
||||
|
||||
|
|
@ -86,12 +87,16 @@ class Channels(models.Model):
|
|||
htlc_count = models.IntegerField()
|
||||
local_base_fee = models.IntegerField()
|
||||
local_fee_rate = models.IntegerField()
|
||||
local_inbound_base_fee = models.IntegerField()
|
||||
local_inbound_fee_rate = models.IntegerField()
|
||||
local_disabled = models.BooleanField()
|
||||
local_cltv = models.IntegerField()
|
||||
local_min_htlc_msat = models.BigIntegerField()
|
||||
local_max_htlc_msat = models.BigIntegerField()
|
||||
remote_base_fee = models.IntegerField()
|
||||
remote_fee_rate = models.IntegerField()
|
||||
remote_inbound_base_fee = models.IntegerField()
|
||||
remote_inbound_fee_rate = models.IntegerField()
|
||||
remote_disabled = models.BooleanField()
|
||||
remote_cltv = models.IntegerField()
|
||||
remote_min_htlc_msat = models.BigIntegerField()
|
||||
|
|
|
|||
|
|
@ -155,6 +155,8 @@ class UpdateChanPolicy(serializers.Serializer):
|
|||
chan_id = serializers.CharField(max_length=20)
|
||||
base_fee = serializers.IntegerField(required=False, default=None)
|
||||
fee_rate = serializers.IntegerField(required=False, default=None)
|
||||
inbound_base_fee = serializers.IntegerField(required=False, default=None)
|
||||
inbound_fee_rate = serializers.IntegerField(required=False, default=None)
|
||||
disabled = serializers.IntegerField(required=False, default=None)
|
||||
cltv = serializers.IntegerField(required=False, default=None)
|
||||
min_htlc = serializers.FloatField(required=False, default=None)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,20 @@
|
|||
<input type="hidden" name="key" value="ALL-oBase">
|
||||
</form>
|
||||
</td>
|
||||
<td title="Update all channel inbound fee rates">
|
||||
<form action="/update_setting/" method="post">
|
||||
{% csrf_token %}
|
||||
<input data-tag="inbound" style="text-align:center" id="value" type="number" min="-100000" max="0" name="value" value="">
|
||||
<input type="hidden" name="key" value="ALL-iRate">
|
||||
</form>
|
||||
</td>
|
||||
<td title="Update all channel inbound base fees">
|
||||
<form action="/update_setting/" method="post">
|
||||
{% csrf_token %}
|
||||
<input data-tag="inbound" style="text-align:center" id="value" type="number" min="-100000000" max="0" name="value" value="">
|
||||
<input type="hidden" name="key" value="ALL-iBase">
|
||||
</form>
|
||||
</td>
|
||||
<td title="Update all channel CLTVs">
|
||||
<form action="/update_setting/" method="post">
|
||||
{% csrf_token %}
|
||||
|
|
@ -37,7 +51,7 @@
|
|||
<input type="hidden" name="key" value="ALL-minHTLC">
|
||||
</form>
|
||||
</td>
|
||||
<th colspan="3"></th>
|
||||
<th colspan="5"></th>
|
||||
<td title="Update all channel AR amount amounts">
|
||||
<form action="/update_setting/" method="post">
|
||||
{% csrf_token %}
|
||||
|
|
@ -83,17 +97,21 @@
|
|||
<th>Channel State</th>
|
||||
<th>oRate</th>
|
||||
<th>oBase</th>
|
||||
<th>iRate</th>
|
||||
<th>iBase</th>
|
||||
<th>oCLTV</th>
|
||||
<th>minHTLC</th>
|
||||
<th>maxHTLC</th>
|
||||
<th onclick="sortTable(event.target, 11, 'int', 1)">iRate</th>
|
||||
<th onclick="sortTable(event.target, 12, 'int', 1)">iBase</th>
|
||||
<th onclick="sortTable(event.target, 13, 'int', 1)">Peer iRate</th>
|
||||
<th onclick="sortTable(event.target, 14, 'int', 1)">Peer iBase</th>
|
||||
<th onclick="sortTable(event.target, 15, 'int', 1)">Peer oRate</th>
|
||||
<th onclick="sortTable(event.target, 16, 'int', 1)">Peer oBase</th>
|
||||
<th title="When AR is ENABLED for the channel, the size of the rebalance attempts that should be tried during attempts to refill the channel.">Target Amt</th>
|
||||
<th title="When AR is ENABLED, the maximum percentage amount of the local fee rate that can be used for the max rebalancing cost.">Max Cost %</th>
|
||||
<th title="When AR is NOT ENABLED for the channel, keep pushing OUT the channel until its outbound liquidity falls below the oTarget%.">oTarget%</th>
|
||||
<th title="When AR is ENABLED for the channel, keep pulling IN to the channel until its inbound liquidity falls below the iTarget%.">iTarget%</th>
|
||||
<th title="When AR is ENABLED it will refill the channel with outbound liquidity.">AR</th>
|
||||
<th onclick="sortTable(event.target, 18, 'String', 1)">Active</th>
|
||||
<th onclick="sortTable(event.target, 22, 'String', 1)">Active</th>
|
||||
</tr>
|
||||
{% for channel in channels %}
|
||||
<tr>
|
||||
|
|
@ -136,6 +154,22 @@
|
|||
<input type="hidden" name="update_target" value="0">
|
||||
</form>
|
||||
</td>
|
||||
<td {% if channel.local_disabled == True %}style="background-color: rgba(248,81,73,0.15);"{% elif channel.private == True %}style="background-color: rgba(110,118,129,0.4)"{% endif %}>
|
||||
<form action="/update_channel/" method="post">
|
||||
{% csrf_token %}
|
||||
<input data-tag="inbound" style="text-align:center" id="target" type="number" min="-100000" max="0" name="target" value="{{ channel.local_inbound_fee_rate }}">
|
||||
<input type="hidden" name="chan_id" value="{{ channel.chan_id }}">
|
||||
<input type="hidden" name="update_target" value="13">
|
||||
</form>
|
||||
</td>
|
||||
<td {% if channel.local_disabled == True %}style="background-color: rgba(248,81,73,0.15);"{% elif channel.private == True %}style="background-color: rgba(110,118,129,0.4)"{% endif %}>
|
||||
<form action="/update_channel/" method="post">
|
||||
{% csrf_token %}
|
||||
<input data-tag="inbound" style="text-align:center" id="target" type="number" min="-100000000" max="0" name="target" value="{{ channel.local_inbound_base_fee }}">
|
||||
<input type="hidden" name="chan_id" value="{{ channel.chan_id }}">
|
||||
<input type="hidden" name="update_target" value="12">
|
||||
</form>
|
||||
</td>
|
||||
<td {% if channel.local_disabled == True %}style="background-color: rgba(248,81,73,0.15);"{% elif channel.private == True %}style="background-color: rgba(110,118,129,0.4)"{% endif %}>
|
||||
<form action="/update_channel/" method="post">
|
||||
{% csrf_token %}
|
||||
|
|
@ -160,6 +194,8 @@
|
|||
<input type="hidden" name="update_target" value="11">
|
||||
</form>
|
||||
</td>
|
||||
<td {% if channel.remote_disabled == True %}style="background-color: rgba(248,81,73,0.15);"{% endif %}>{{ channel.remote_inbound_fee_rate|intcomma }}</td>
|
||||
<td {% if channel.remote_disabled == True %}style="background-color: rgba(248,81,73,0.15);"{% endif %}>{{ channel.remote_inbound_base_fee|intcomma }}</td>
|
||||
<td title="Fee Ratio: {{ channel.fee_ratio }}%" {% if channel.remote_disabled == True %}style="background-color: rgba(248,81,73,0.15);"{% endif %}>{{ channel.remote_fee_rate|intcomma }}</td>
|
||||
<td {% if channel.remote_disabled == True %}style="background-color: rgba(248,81,73,0.15);"{% endif %}>{{ channel.remote_base_fee|intcomma }}</td>
|
||||
<td>
|
||||
|
|
@ -218,4 +254,15 @@
|
|||
{% if local_settings %}
|
||||
{% include 'local_settings.html' with settings=local_settings title='Update Local' %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const node_info = await GET('node_info', {data: {limit:1}})
|
||||
if (parseFloat(node_info.version.substring(0, 4)) <= 0.17){
|
||||
let inputs = document.querySelectorAll('input[data-tag="inbound"]')
|
||||
inputs.forEach(function(input) {
|
||||
input.disabled = true
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -27,8 +27,8 @@
|
|||
"amt_out": f => ({innerHTML: (f.amt_out > 1000 ? f.amt_out.intcomma() : f.amt_out) + ` <small class="w3-round w3-border-small w3-border-grey w3-tiny">+${f.fee.intcomma().toLocaleString()}</small>`, style: {paddingLeft: "0px", width: "160px"} }),
|
||||
"chan_out_alias": f => ({innerHTML: f.chan_out_alias || f.chan_id_out}),
|
||||
"chan_id_out": f => ({innerHTML: `<a href="/channel?=${f.chan_id_out}" target="_blank">${(BigInt(f.chan_id_out)>>40n)+'x'+(BigInt(f.chan_id_out)>>16n & BigInt('0xFFFFFF'))+'x'+(BigInt(f.chan_id_out) & BigInt('0xFFFF'))}</a>`}),
|
||||
"fee": f => ({innerHTML: parseFloat(f.fee.toFixed(3)).toLocaleString()}),
|
||||
"ppm": f => ({innerHTML: parseInt(f.ppm.toFixed(0)).toLocaleString()}),
|
||||
"fee": f => ({innerHTML: parseFloat(f.fee.toFixed(3)).toLocaleString() + (f.inbound_fee > 0 ? ` <small class="w3-round w3-border-small w3-border-grey w3-tiny">-${f.inbound_fee.toLocaleString()}</small>` : ``)}),
|
||||
"ppm": f => ({innerHTML: parseInt(f.ppm.toFixed(0)).toLocaleString() + (f.inbound_fee > 0 ? ` <small class="w3-round w3-border-small w3-border-grey w3-tiny">-${((f.inbound_fee/(f.inbound_fee+f.fee))*100).intcomma().toLocaleString()}%</small>` : ``)}),
|
||||
}
|
||||
let {fee, ppm} = routed_template
|
||||
const payments_template = Object.assign({}, {
|
||||
|
|
|
|||
76
gui/views.py
76
gui/views.py
|
|
@ -1770,6 +1770,30 @@ def update_channel(request):
|
|||
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 == 12:
|
||||
stub = lnrpc.LightningStub(lnd_connect())
|
||||
version = stub.GetInfo(ln.GetInfoRequest()).version
|
||||
if float(version[:4]) >= 0.18:
|
||||
channel_point = point(db_channel)
|
||||
inbound_fee_rate = db_channel.local_inbound_fee_rate if db_channel.local_inbound_fee_rate else 0
|
||||
stub.UpdateChannelPolicy(ln.PolicyUpdateRequest(chan_point=channel_point, base_fee_msat=db_channel.local_base_fee, fee_rate=(db_channel.local_fee_rate/1000000), time_lock_delta=db_channel.local_cltv, inbound_fee=ln.InboundFee(base_fee_msat=target, fee_rate_ppm=inbound_fee_rate)))
|
||||
db_channel.local_inbound_base_fee = target
|
||||
db_channel.save()
|
||||
messages.success(request, 'Inbound base fee for channel ' + str(db_channel.alias) + ' (' + str(db_channel.chan_id) + ') updated to a value of: ' + str(target))
|
||||
else:
|
||||
messages.error(request, f'LND version too low to set inbound fees, update to v0.18+')
|
||||
elif update_target == 13:
|
||||
stub = lnrpc.LightningStub(lnd_connect())
|
||||
version = stub.GetInfo(ln.GetInfoRequest()).version
|
||||
if float(version[:4]) >= 0.18:
|
||||
channel_point = point(db_channel)
|
||||
inbound_base_fee = db_channel.local_inbound_base_fee if db_channel.local_inbound_base_fee else 0
|
||||
stub.UpdateChannelPolicy(ln.PolicyUpdateRequest(chan_point=channel_point, base_fee_msat=db_channel.local_base_fee, fee_rate=(db_channel.local_fee_rate/1000000), time_lock_delta=db_channel.local_cltv, inbound_fee=ln.InboundFee(base_fee_msat=inbound_base_fee, fee_rate_ppm=target)))
|
||||
db_channel.local_inbound_fee_rate = target
|
||||
db_channel.save()
|
||||
messages.success(request, 'Inbound fee rate for channel ' + str(db_channel.alias) + ' (' + str(db_channel.chan_id) + ') updated to a value of: ' + str(target))
|
||||
else:
|
||||
messages.error(request, f'LND version too low to set inbound fees, update to v0.18+')
|
||||
elif update_target == 2:
|
||||
db_channel.ar_amt_target = target
|
||||
db_channel.save()
|
||||
|
|
@ -1924,6 +1948,36 @@ def update_setting(request):
|
|||
db_channel.local_base_fee = target
|
||||
db_channel.save()
|
||||
messages.success(request, 'Base fee for all channels updated to a value of: ' + str(target))
|
||||
elif key == 'ALL-iRate':
|
||||
target = int(value)
|
||||
stub = lnrpc.LightningStub(lnd_connect())
|
||||
version = stub.GetInfo(ln.GetInfoRequest()).version
|
||||
if float(version[:4]) >= 0.18:
|
||||
channels = Channels.objects.filter(is_open=True)
|
||||
for db_channel in channels:
|
||||
channel_point = point(db_channel)
|
||||
inbound_base_fee = db_channel.local_inbound_base_fee if db_channel.local_inbound_base_fee else 0
|
||||
stub.UpdateChannelPolicy(ln.PolicyUpdateRequest(chan_point=channel_point, base_fee_msat=db_channel.local_base_fee, fee_rate=(db_channel.local_fee_rate/1000000), time_lock_delta=db_channel.local_cltv, inbound_fee=ln.InboundFee(base_fee_msat=inbound_base_fee, fee_rate_ppm=target)))
|
||||
db_channel.local_inbound_fee_rate = target
|
||||
db_channel.save()
|
||||
messages.success(request, 'Inbound fee rate for all open channels updated to a value of: ' + str(target))
|
||||
else:
|
||||
messages.error(request, f'LND version too low to set inbound fees, update to v0.18+')
|
||||
elif key == 'ALL-iBase':
|
||||
target = int(value)
|
||||
stub = lnrpc.LightningStub(lnd_connect())
|
||||
version = stub.GetInfo(ln.GetInfoRequest()).version
|
||||
if float(version[:4]) >= 0.18:
|
||||
channels = Channels.objects.filter(is_open=True)
|
||||
for db_channel in channels:
|
||||
channel_point = point(db_channel)
|
||||
inbound_fee_rate = db_channel.local_inbound_fee_rate if db_channel.local_inbound_fee_rate else 0
|
||||
stub.UpdateChannelPolicy(ln.PolicyUpdateRequest(chan_point=channel_point, base_fee_msat=db_channel.local_base_fee, fee_rate=(db_channel.local_fee_rate/1000000), time_lock_delta=db_channel.local_cltv, inbound_fee=ln.InboundFee(base_fee_msat=target, fee_rate_ppm=inbound_fee_rate)))
|
||||
db_channel.local_inbound_base_fee = target
|
||||
db_channel.save()
|
||||
messages.success(request, 'Inbound base fee for all channels updated to a value of: ' + str(target))
|
||||
else:
|
||||
messages.error(request, f'LND version too low to set inbound fees, update to v0.18+')
|
||||
elif key == 'ALL-CLTV':
|
||||
target = int(value)
|
||||
stub = lnrpc.LightningStub(lnd_connect())
|
||||
|
|
@ -2385,6 +2439,7 @@ def node_info(request):
|
|||
except:
|
||||
db_size = 0
|
||||
return Response({
|
||||
'version': node_info.version,
|
||||
'num_peers': node_info.num_peers,
|
||||
'synced_to_graph': node_info.synced_to_graph,
|
||||
'synced_to_chain': node_info.synced_to_chain,
|
||||
|
|
@ -2818,14 +2873,23 @@ def chan_policy(request):
|
|||
channel_point = point(db_channel)
|
||||
return_response = {}
|
||||
try:
|
||||
if serializer.validated_data['base_fee'] is not None or serializer.validated_data['fee_rate'] is not None or serializer.validated_data['cltv'] is not None or serializer.validated_data['min_htlc'] is not None or serializer.validated_data['max_htlc'] is not None:
|
||||
if serializer.validated_data['base_fee'] is not None or serializer.validated_data['fee_rate'] is not None or serializer.validated_data['cltv'] is not None or serializer.validated_data['min_htlc'] is not None or serializer.validated_data['max_htlc'] is not None or serializer.validated_data['inbound_base_fee'] is not None or serializer.validated_data['inbound_fee_rate'] is not None:
|
||||
base_fee_msat = serializer.validated_data['base_fee'] if serializer.validated_data['base_fee'] is not None else db_channel.local_base_fee
|
||||
fee_rate = (serializer.validated_data['fee_rate']/1000000) if serializer.validated_data['fee_rate'] is not None else (db_channel.local_fee_rate/1000000)
|
||||
inbound_base_fee_msat = serializer.validated_data['inbound_base_fee'] if serializer.validated_data['inbound_base_fee'] is not None else db_channel.local_inbound_base_fee
|
||||
inbound_fee_rate = serializer.validated_data['inbound_fee_rate'] if serializer.validated_data['inbound_fee_rate'] is not None else db_channel.local_inbound_fee_rate
|
||||
time_lock_delta = serializer.validated_data['cltv'] if serializer.validated_data['cltv'] is not None else db_channel.local_cltv
|
||||
min_htlc_msat = int(serializer.validated_data['min_htlc']*1000) if serializer.validated_data['min_htlc'] is not None else db_channel.local_min_htlc_msat
|
||||
max_htlc_msat = int(serializer.validated_data['max_htlc']*1000) if serializer.validated_data['max_htlc'] is not None else db_channel.local_max_htlc_msat
|
||||
stub = lnrpc.LightningStub(lnd_connect())
|
||||
stub.UpdateChannelPolicy(ln.PolicyUpdateRequest(chan_point=channel_point, base_fee_msat=base_fee_msat, fee_rate=fee_rate, time_lock_delta=time_lock_delta, min_htlc_msat_specified=True, min_htlc_msat=min_htlc_msat, max_htlc_msat=max_htlc_msat))
|
||||
version = stub.GetInfo(ln.GetInfoRequest()).version
|
||||
kwargs = {'chan_point':channel_point, 'base_fee_msat':base_fee_msat, 'fee_rate':fee_rate, 'time_lock_delta':time_lock_delta, 'min_htlc_msat_specified':True, 'min_htlc_msat':min_htlc_msat, 'max_htlc_msat':max_htlc_msat}
|
||||
if serializer.validated_data['inbound_base_fee'] or serializer.validated_data['inbound_fee_rate']:
|
||||
if float(version[:4]) >= 0.18:
|
||||
kwargs['inbound_fee'] = ln.InboundFee(base_fee_msat = inbound_base_fee_msat if inbound_base_fee_msat else 0, fee_rate_ppm = inbound_fee_rate if inbound_fee_rate else 0)
|
||||
else:
|
||||
return Response({'error': f'LND version too low to set inbound fees, update to v0.18+'})
|
||||
stub.UpdateChannelPolicy(ln.PolicyUpdateRequest(**kwargs))
|
||||
if serializer.validated_data['base_fee'] is not None:
|
||||
db_channel.local_base_fee = serializer.validated_data['base_fee']
|
||||
db_channel.save()
|
||||
|
|
@ -2837,6 +2901,14 @@ def chan_policy(request):
|
|||
db_channel.save()
|
||||
return_response['fee_rate'] = serializer.validated_data['fee_rate']
|
||||
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()
|
||||
if serializer.validated_data['inbound_base_fee'] is not None:
|
||||
db_channel.local_inbound_base_fee = serializer.validated_data['inbound_base_fee']
|
||||
db_channel.save()
|
||||
return_response['inbound_base_fee'] = serializer.validated_data['inbound_base_fee']
|
||||
if serializer.validated_data['inbound_fee_rate'] is not None:
|
||||
db_channel.local_inbound_fee_rate = serializer.validated_data['inbound_fee_rate']
|
||||
db_channel.save()
|
||||
return_response['inbound_fee_rate'] = serializer.validated_data['inbound_fee_rate']
|
||||
if serializer.validated_data['cltv'] is not None:
|
||||
db_channel.local_cltv = serializer.validated_data['cltv']
|
||||
db_channel.save()
|
||||
|
|
|
|||
60
jobs.py
60
jobs.py
|
|
@ -149,11 +149,19 @@ def update_forwards(stub):
|
|||
records = Forwards.objects.count()
|
||||
forwards = stub.ForwardingHistory(ln.ForwardingHistoryRequest(start_time=1420070400, index_offset=records, num_max_events=100)).forwarding_events
|
||||
for forward in forwards:
|
||||
incoming_peer_alias = Channels.objects.filter(chan_id=forward.chan_id_in)[0].alias if Channels.objects.filter(chan_id=forward.chan_id_in).exists() else None
|
||||
incoming_peer_alias = Channels.objects.filter(chan_id=forward.chan_id_in)[0].remote_pubkey[:12] if incoming_peer_alias == '' else incoming_peer_alias
|
||||
outgoing_peer_alias = Channels.objects.filter(chan_id=forward.chan_id_out)[0].alias if Channels.objects.filter(chan_id=forward.chan_id_out).exists() else None
|
||||
outgoing_peer_alias = Channels.objects.filter(chan_id=forward.chan_id_out)[0].remote_pubkey[:12] if outgoing_peer_alias == '' else outgoing_peer_alias
|
||||
Forwards(forward_date=datetime.fromtimestamp(forward.timestamp), chan_id_in=forward.chan_id_in, chan_id_out=forward.chan_id_out, chan_in_alias=incoming_peer_alias, chan_out_alias=outgoing_peer_alias, amt_in_msat=forward.amt_in_msat, amt_out_msat=forward.amt_out_msat, fee=round(forward.fee_msat/1000, 3)).save()
|
||||
inbound_channel = Channels.objects.get(chan_id=forward.chan_id_in) if Channels.objects.filter(chan_id=forward.chan_id_in).exists() else None
|
||||
outbound_channel = Channels.objects.get(chan_id=forward.chan_id_out) if Channels.objects.filter(chan_id=forward.chan_id_out).exists() else None
|
||||
forward_datetime = datetime.fromtimestamp(forward.timestamp)
|
||||
amt_in_msat = forward.amt_in_msat
|
||||
amt_out_msat = forward.amt_out_msat
|
||||
in_fee_msat = 0
|
||||
if outbound_channel and outbound_channel.fees_updated < forward_datetime:
|
||||
out_fee_msat = int((amt_out_msat * (outbound_channel.local_fee_rate/1000000)) + outbound_channel.local_base_fee)
|
||||
if forward.fee_msat < out_fee_msat:
|
||||
in_fee_msat = out_fee_msat - forward.fee_msat
|
||||
incoming_peer_alias = (inbound_channel.remote_pubkey[:12] if inbound_channel.alias == '' else inbound_channel.alias) if inbound_channel else forward.peer_alias_in
|
||||
outgoing_peer_alias = (outbound_channel.remote_pubkey[:12] if outbound_channel.alias == '' else outbound_channel.alias) if outbound_channel else forward.peer_alias_out
|
||||
Forwards(forward_date=forward_datetime, chan_id_in=forward.chan_id_in, chan_id_out=forward.chan_id_out, chan_in_alias=incoming_peer_alias, chan_out_alias=outgoing_peer_alias, amt_in_msat=amt_in_msat, amt_out_msat=amt_out_msat, fee=round(forward.fee_msat/1000, 3), inbound_fee=round(in_fee_msat/1000, 3)).save()
|
||||
|
||||
def disconnectpeer(stub, peer):
|
||||
try:
|
||||
|
|
@ -169,7 +177,9 @@ def update_channels(stub):
|
|||
chan_list = []
|
||||
channels = stub.ListChannels(ln.ListChannelsRequest()).channels
|
||||
PendingHTLCs.objects.all().delete()
|
||||
block_height = stub.GetInfo(ln.GetInfoRequest()).block_height
|
||||
get_info = stub.GetInfo(ln.GetInfoRequest())
|
||||
block_height = get_info.block_height
|
||||
version = get_info.version
|
||||
for channel in channels:
|
||||
if Channels.objects.filter(chan_id=channel.chan_id).exists():
|
||||
#Update the channel record with the most current data
|
||||
|
|
@ -265,6 +275,16 @@ def update_channels(stub):
|
|||
db_channel.local_disabled = local_policy.disabled
|
||||
db_channel.local_min_htlc_msat = local_policy.min_htlc
|
||||
db_channel.local_max_htlc_msat = local_policy.max_htlc_msat
|
||||
if float(version[:4]) >= 0.18:
|
||||
try:
|
||||
db_channel.local_inbound_base_fee = local_policy.inbound_fee_base_msat
|
||||
db_channel.local_inbound_fee_rate = local_policy.inbound_fee_rate_milli_msat
|
||||
except:
|
||||
db_channel.local_inbound_base_fee = 0
|
||||
db_channel.local_inbound_fee_rate = 0
|
||||
else:
|
||||
db_channel.local_inbound_base_fee = 0
|
||||
db_channel.local_inbound_fee_rate = 0
|
||||
if db_channel.remote_cltv == -1:
|
||||
PeerEvents(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, event='BaseFee', old_value=None, new_value=remote_policy.fee_base_msat, out_liq=(db_channel.local_balance + db_channel.pending_outbound)).save()
|
||||
db_channel.remote_base_fee = remote_policy.fee_base_msat
|
||||
|
|
@ -281,6 +301,18 @@ def update_channels(stub):
|
|||
db_channel.remote_min_htlc_msat = remote_policy.min_htlc
|
||||
PeerEvents(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, event='MaxHTLC', old_value=None, new_value=remote_policy.max_htlc_msat, out_liq=(db_channel.local_balance + db_channel.pending_outbound)).save()
|
||||
db_channel.remote_max_htlc_msat = remote_policy.max_htlc_msat
|
||||
if float(version[:4]) >= 0.18:
|
||||
try:
|
||||
PeerEvents(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, event='IncomingBaseFee', old_value=None, new_value=remote_policy.inbound_fee_base_msat, out_liq=(db_channel.local_balance + db_channel.pending_outbound)).save()
|
||||
db_channel.remote_inbound_base_fee = remote_policy.inbound_fee_base_msat
|
||||
PeerEvents(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, event='IncomingFeeRate', old_value=None, new_value=remote_policy.inbound_fee_rate_milli_msat, out_liq=(db_channel.local_balance + db_channel.pending_outbound)).save()
|
||||
db_channel.remote_inbound_fee_rate = remote_policy.inbound_fee_rate_milli_msat
|
||||
except:
|
||||
db_channel.remote_inbound_base_fee = 0
|
||||
db_channel.remote_inbound_fee_rate = 0
|
||||
else:
|
||||
db_channel.remote_inbound_base_fee = 0
|
||||
db_channel.remote_inbound_fee_rate = 0
|
||||
else:
|
||||
if db_channel.remote_base_fee != remote_policy.fee_base_msat:
|
||||
PeerEvents(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, event='BaseFee', old_value=db_channel.remote_base_fee, new_value=remote_policy.fee_base_msat, out_liq=(db_channel.local_balance + db_channel.pending_outbound)).save()
|
||||
|
|
@ -305,6 +337,22 @@ def update_channels(stub):
|
|||
if db_channel.remote_max_htlc_msat != remote_policy.max_htlc_msat:
|
||||
PeerEvents(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, event='MaxHTLC', old_value=db_channel.remote_max_htlc_msat, new_value=remote_policy.max_htlc_msat, out_liq=(db_channel.local_balance + db_channel.pending_outbound)).save()
|
||||
db_channel.remote_max_htlc_msat = remote_policy.max_htlc_msat
|
||||
if float(version[:4]) >= 0.18:
|
||||
if db_channel.remote_inbound_base_fee != remote_policy.inbound_fee_base_msat:
|
||||
try:
|
||||
PeerEvents(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, event='IncomingBaseFee', old_value=db_channel.remote_inbound_base_fee, new_value=remote_policy.inbound_fee_base_msat, out_liq=(db_channel.local_balance + db_channel.pending_outbound)).save()
|
||||
db_channel.remote_inbound_base_fee = remote_policy.inbound_fee_base_msat
|
||||
except:
|
||||
db_channel.remote_inbound_base_fee = 0
|
||||
if db_channel.remote_inbound_fee_rate != remote_policy.inbound_fee_rate_milli_msat:
|
||||
try:
|
||||
PeerEvents(chan_id=db_channel.chan_id, peer_alias=db_channel.alias, event='IncomingFeeRate', old_value=db_channel.remote_inbound_fee_rate, new_value=remote_policy.inbound_fee_rate_milli_msat, out_liq=(db_channel.local_balance + db_channel.pending_outbound)).save()
|
||||
db_channel.remote_inbound_fee_rate = remote_policy.inbound_fee_rate_milli_msat
|
||||
except:
|
||||
db_channel.remote_inbound_fee_rate = 0
|
||||
else:
|
||||
db_channel.remote_inbound_base_fee = 0
|
||||
db_channel.remote_inbound_fee_rate = 0
|
||||
except Exception as e: # LND has not found the channel on the graph
|
||||
print(f"{datetime.now().strftime('%c')} : [Data] : Error getting graph data for channel {db_channel.chan_id}: {str(e)}")
|
||||
if pending_channel: # skip adding new channel to the list, LND may not have added to the graph yet
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue