use onchain fee estimate of lnd instead of electrum

We are using the onchain fee estimator of lnd now. Internally, lnd uses
either bitcoind or a fee url for the estimation.
This commit is contained in:
feelancer21 2024-05-25 14:15:30 +02:00
parent a73ea6c80e
commit 481ccf5282
No known key found for this signature in database
GPG key ID: 1F7071EE8449729C
5 changed files with 11 additions and 52 deletions

View file

@ -11,8 +11,7 @@ See [INSTALL.md](/INSTALL.md)
charge-lnd takes only a minimal set of parameters:
```
usage: charge-lnd [-h] [--lnddir LNDDIR] [--grpc GRPC] [--electrum-server ELECTRUM_SERVER]
[--dry-run] [--check] [-v] -c CONFIG
usage: charge-lnd [-h] [--lnddir LNDDIR] [--grpc GRPC] [--dry-run] [--check] [-v] -c CONFIG
optional arguments:
-h, --help show this help message and exit
@ -22,9 +21,6 @@ optional arguments:
--macaroon MACAROON_PATH
(default [lnddir]/data/chain/bitcoin/mainnet/charge-lnd.macaroon) path to lnd auth macaroons
--grpc GRPC (default localhost:10009) lnd gRPC endpoint
--electrum-server ELECTRUM_SERVER
(optional, no default) electrum server host:port . Needed for
onchain_fee.
--dry-run Do not perform actions (for testing), print what we would do to
stdout
--check Do not perform actions, only check config file for valid syntax
@ -206,7 +202,7 @@ Available strategies:
|**static** | sets fixed base fee and fee rate values for the outbound and inbound side.| **fee_ppm**<br>**base_fee_msat**<br>**inbound_fee_ppm**<br>**inbound_base_fee_msat**|
|**match_peer** | sets the same base fee and fee rate values as the peer for the outbound and inbound side.|if **base_fee_msat**, **fee_ppm**, **inbound_base_fee_msat** or **inbound_fee_ppm** are set the override the peer values|
|**cost** | calculate cost for opening channel, and set ppm to cover cost when channel depletes.|**cost_factor**|
|**onchain_fee** | sets the fees to a % equivalent of a standard onchain payment (Requires --electrum-server to be specified.)| **onchain_fee_btc** BTC<br>within **onchain_fee_numblocks** blocks.|
|**onchain_fee** | sets the fees to a % equivalent of a standard onchain payment. We use lnd's internal fee estimate, which is usually based on bitcoind's fee estimate.| **onchain_fee_btc** BTC<br>within **onchain_fee_numblocks** blocks.|
|**proportional** | sets outbound fee ppm according to balancedness. Inbound fee ppm keeps unchanged.|**min_fee_ppm**<br>**max_fee_ppm**<br>**sum_peer_chans** consider all channels with peer for balance calculations|
|**disable** | disables the channel in the outgoing direction. Channel will be re-enabled again if it matches another policy (except when that policy uses an 'ignore' strategy).||
|**use_config** | process channel according to rules defined in another config file.|**config_file**|

View file

@ -11,7 +11,6 @@ from .lnd import Lnd
from .policy import Policies
from .strategy import is_defined
from .config import Config
from .electrum import Electrum
import charge_lnd.fmt as fmt
def debug(message):
@ -21,9 +20,6 @@ def main():
argument_parser = get_argument_parser()
arguments = argument_parser.parse_args()
if arguments.electrum_server:
Electrum.set_server(arguments.electrum_server)
if not os.path.exists(arguments.config):
debug("Config file not found")
return False
@ -166,9 +162,6 @@ def get_argument_parser():
default="localhost:10009",
dest="grpc",
help="(default localhost:10009) lnd gRPC endpoint")
parser.add_argument("--electrum-server",
dest="electrum_server",
help="(optional, no default) electrum server host:port[:s]. Needed for onchain_fee. Append ':s' for SSL connection")
parser.add_argument("--dry-run",
dest="dry_run",
action="store_true",

View file

@ -1,34 +0,0 @@
import asyncio
import aiorpcx
class Electrum:
host = None
port = None
ssl = False
# cache
estimates = {}
@staticmethod
def set_server(server):
if server is not None:
split = server.split(':')
Electrum.host = split[0]
Electrum.port = int(split[1])
if len(split) > 2:
Electrum.ssl = split[2] == 's'
@staticmethod
async def _request_fee_estimate(numblocks):
async with aiorpcx.connect_rs(Electrum.host, Electrum.port, ssl=Electrum.ssl) as session:
result = await session.send_request('blockchain.estimatefee', [numblocks])
# convert from btc/kbyte
sat_per_byte = int(result * (100_000_000/1000))
Electrum.estimates[numblocks] = sat_per_byte
@staticmethod
def get_fee_estimate(numblocks):
if not numblocks in Electrum.estimates:
asyncio.get_event_loop().run_until_complete(Electrum._request_fee_estimate(numblocks))
if not numblocks in Electrum.estimates:
return 0
return Electrum.estimates[numblocks]

View file

@ -8,6 +8,7 @@ import time
from .grpc_generated import lightning_pb2_grpc as lnrpc, lightning_pb2 as ln
from .grpc_generated import router_pb2_grpc as routerrpc, router_pb2 as router
from .grpc_generated import walletkit_pb2_grpc as walletkitrpc, walletkit_pb2 as walletkit
from .strategy import ChanParams, is_defined
@ -30,6 +31,7 @@ class Lnd:
grpc_channel = grpc.secure_channel(server, combined_credentials, channel_options)
self.lnstub = lnrpc.LightningStub(grpc_channel)
self.routerstub = routerrpc.RouterStub(grpc_channel)
self.walletstub = walletkitrpc.WalletKitStub(grpc_channel)
self.graph = None
self.info = None
self.version = None
@ -235,6 +237,11 @@ class Lnd:
chan_point=channel_point,
action=action
))
# returns the onchain fee in sat per vbyte for a given confirmation target
def get_fee_estimate(self, numblocks):
# numblocks less than 2 are rejected by walletrpc
return self.walletstub.EstimateFee(walletkit.EstimateFeeRequest(conf_target=max(numblocks,2))).sat_per_kw * 4 / 1000
@staticmethod
def hex_string_to_bytes(hex_string):

View file

@ -6,7 +6,6 @@ from types import SimpleNamespace
from . import fmt
from .config import Config
from .electrum import Electrum
def debug(message):
sys.stderr.write(message + "\n")
@ -193,14 +192,12 @@ def strategy_cost(channel, policy, **kwargs):
@strategy(name = 'onchain_fee')
def strategy_onchain_fee(channel, policy, **kwargs):
if not Electrum.host or not Electrum.port:
raise Exception("No electrum server specified, cannot use strategy 'onchain_fee'")
lnd = kwargs['lnd']
if policy.getint('min_fee_ppm_delta',-1) < 0:
policy.set('min_fee_ppm_delta', 10) # set delta to 10 if not defined
numblocks = policy.getint('onchain_fee_numblocks', 6)
sat_per_byte = Electrum.get_fee_estimate(numblocks)
sat_per_byte = lnd.get_fee_estimate(numblocks)
if sat_per_byte < 1:
return (None, None, None, None, None)
reference_payment = policy.getfloat('onchain_fee_btc', 0.1)