2019-06-15 23:02:44 +00:00
import copy
import requests
import subprocess
import os
import time
import re
2021-03-25 03:44:03 +00:00
import datetime
2021-04-30 05:43:24 +00:00
import urllib
2022-01-07 03:57:00 +00:00
import random
2022-03-14 03:52:26 +00:00
import base64
2022-01-07 03:57:00 +00:00
from device_info import *
2019-06-15 23:02:44 +00:00
from threading import Timer
2021-03-13 21:57:23 +00:00
from utilities import *
2019-06-15 23:02:44 +00:00
from bitcoin_info import *
2020-10-08 02:59:44 +00:00
from systemctl_info import *
2019-06-15 23:02:44 +00:00
# Variables
lightning_info = None
lnd_ready = False
2019-08-01 04:27:16 +00:00
lnd_version = None
2021-01-16 18:15:52 +00:00
loop_version = None
pool_version = None
2021-03-31 03:09:55 +00:00
lit_version = None
2020-01-30 03:00:02 +00:00
lightning_peers = None
2021-03-09 03:55:39 +00:00
lightning_peer_aliases = { }
2020-01-30 03:00:02 +00:00
lightning_channels = None
lightning_channel_balance = None
lightning_wallet_balance = None
2021-04-30 05:43:24 +00:00
lightning_transactions = None
lightning_payments = None
lightning_invoices = None
2022-03-14 03:52:26 +00:00
lightning_watchtower_server_info = { }
lightning_watchtower_client_towers = { }
lightning_watchtower_client_stats = { }
lightning_watchtower_client_policy = { }
2020-05-19 02:43:43 +00:00
lightning_desync_count = 0
2021-05-01 04:39:58 +00:00
lightning_update_count = 0
2019-06-15 23:02:44 +00:00
2022-03-07 04:02:30 +00:00
LIGHTNING_CACHE_FILE = " /tmp/lightning_info.json "
2019-06-15 23:02:44 +00:00
LND_FOLDER = " /mnt/hdd/mynode/lnd/ "
TLS_CERT_FILE = " /mnt/hdd/mynode/lnd/tls.cert "
LND_REST_PORT = " 10080 "
# Functions
2022-03-14 03:52:26 +00:00
def run_lncli_command ( cmd ) :
try :
base = " lncli "
base + = " --lnddir=/mnt/hdd/mynode/lnd "
if is_testnet_enabled ( ) :
base + = " --network=testnet "
cmd = cmd . replace ( " lncli " , base )
output = subprocess . check_output ( cmd , shell = True )
return output
except Exception as e :
log_message ( " ERROR in run_lncli_command: {} " . format ( str ( e ) ) )
return None
2019-06-15 23:02:44 +00:00
def update_lightning_info ( ) :
global lightning_info
2020-01-30 03:00:02 +00:00
global lightning_peers
global lightning_channels
global lightning_channel_balance
global lightning_wallet_balance
2021-04-30 05:43:24 +00:00
global lightning_transactions
global lightning_payments
global lightning_invoices
2021-04-02 01:58:19 +00:00
global lightning_watchtower_server_info
2022-03-14 03:52:26 +00:00
global lightning_watchtower_client_towers
global lightning_watchtower_client_stats
global lightning_watchtower_client_policy
2020-05-19 02:43:43 +00:00
global lightning_desync_count
2021-05-01 04:39:58 +00:00
global lightning_update_count
2019-06-15 23:02:44 +00:00
global lnd_ready
2021-05-01 04:39:58 +00:00
# Check logged in
#while not is_lnd_logged_in():
# lnd_ready = False
# time.sleep(10)
2019-06-15 23:02:44 +00:00
# Get latest LN info
lightning_info = lnd_get ( " /getinfo " )
2021-05-01 04:39:58 +00:00
lightning_update_count = lightning_update_count + 1
2019-06-15 23:02:44 +00:00
# Set is LND ready
if lightning_info != None and " synced_to_chain " in lightning_info and lightning_info [ ' synced_to_chain ' ] :
lnd_ready = True
# Check for LND de-sync (this can happen unfortunately)
# See https://github.com/lightningnetwork/lnd/issues/1909
# See https://github.com/bitcoin/bitcoin/pull/14687
# Hopefully patch comes soon to enable TCP keepalive to prevent this from happening
if lnd_ready and lightning_info != None and " synced_to_chain " in lightning_info and not lightning_info [ ' synced_to_chain ' ] :
2020-05-19 02:43:43 +00:00
lightning_desync_count + = 1
os . system ( " printf \" %s | LND De-sync!!! Count: {} \\ n \" \" $(date) \" >> /tmp/lnd_failures " . format ( lightning_desync_count ) )
if lightning_desync_count > = 8 :
os . system ( " printf \" %s | De-sync count too high! Retarting LND... \\ n \" \" $(date) \" >> /tmp/lnd_failures " )
restart_lnd ( )
lightning_desync_count = 0
2020-01-30 03:00:02 +00:00
return True
if lnd_ready :
2022-03-21 03:22:08 +00:00
log_message ( " update_lightning_info - LND READY " )
2020-05-19 02:43:43 +00:00
if lightning_desync_count > 0 :
os . system ( " printf \" %s | De-sync greater than 0 (was {} ), but now synced! Setting to 0. \\ n \" \" $(date) \" >> /tmp/lnd_failures " . format ( lightning_desync_count ) )
lightning_desync_count = 0
2022-03-21 03:22:08 +00:00
log_message ( " update_lightning_info - GET PEERS, CHANNELS, BALANCE, WALLET " )
2020-01-30 03:00:02 +00:00
lightning_peers = lnd_get ( " /peers " )
lightning_channels = lnd_get ( " /channels " )
lightning_channel_balance = lnd_get ( " /balance/channels " )
lightning_wallet_balance = lnd_get ( " /balance/blockchain " )
2022-03-21 03:22:08 +00:00
log_message ( " update_lightning_info - GET WATCHTOWER " )
2022-03-24 03:23:08 +00:00
if is_watchtower_server_enabled ( ) :
2021-09-06 19:01:32 +00:00
lightning_watchtower_server_info = lnd_get_v2 ( " /watchtower/server " )
2022-03-14 03:52:26 +00:00
towers = lnd_get_v2 ( " /watchtower/client?include_sessions=1 " )
2022-03-21 03:22:08 +00:00
log_message ( " update_lightning_info - TOWER DETAILS " )
2022-03-14 03:52:26 +00:00
tower_details = [ ]
if towers != None and " towers " in towers :
for tower in towers [ " towers " ] :
if " pubkey " in tower and tower [ " active_session_candidate " ] :
pubkey_decoded = base64 . b64decode ( tower [ ' pubkey ' ] )
pubkey_b16 = to_string ( base64 . b16encode ( pubkey_decoded ) ) . lower ( )
tower [ " pubkey_b16 " ] = pubkey_b16
tower_details . append ( tower )
lightning_watchtower_client_towers = tower_details
2022-03-21 03:22:08 +00:00
log_message ( " update_lightning_info - GET CLIENT STATS, POLICY " )
2022-03-14 03:52:26 +00:00
lightning_watchtower_client_stats = lnd_get_v2 ( " /watchtower/client/stats " )
lightning_watchtower_client_policy = lnd_get_v2 ( " /watchtower/client/policy " )
2019-06-15 23:02:44 +00:00
2021-05-03 03:28:02 +00:00
# Poll slower (make sure we gather data early)
if lightning_update_count < 30 or lightning_update_count % 2 == 0 :
2022-03-21 03:22:08 +00:00
log_message ( " update_lightning_info - GET TX INFO " )
2021-05-01 04:39:58 +00:00
update_lightning_tx_info ( )
2022-03-07 04:02:30 +00:00
update_lightning_json_cache ( )
2019-06-15 23:02:44 +00:00
return True
2021-04-30 05:43:24 +00:00
def update_lightning_tx_info ( ) :
global lightning_transactions
global lightning_payments
global lightning_invoices
if is_lnd_ready ( ) :
tx_cache_limit = 50
lightning_transactions = lnd_get ( " /transactions " )
lightning_payments = lnd_get ( " /payments " , params = { " reversed " : " true " , " index_offset " : " 0 " , " max_payments " : tx_cache_limit } )
lightning_invoices = lnd_get ( " /invoices " , params = { " reversed " : " true " , " index_offset " : " 0 " , " num_max_invoices " : tx_cache_limit } )
2019-06-15 23:02:44 +00:00
2021-03-17 04:31:46 +00:00
def get_lnd_deposit_address ( ) :
2021-03-13 21:57:23 +00:00
if os . path . isfile ( " /tmp/lnd_deposit_address " ) :
2021-11-07 04:40:57 +00:00
addr = get_file_contents ( " /tmp/lnd_deposit_address " )
else :
addr = get_new_lnd_deposit_address ( )
return to_string ( addr )
2021-03-13 21:57:23 +00:00
2021-03-17 04:31:46 +00:00
def get_new_lnd_deposit_address ( ) :
2020-01-30 03:00:02 +00:00
address = " NEW_ADDR "
try :
addressdata = lnd_get ( " /newaddress " )
address = addressdata [ " address " ]
2021-03-13 21:57:23 +00:00
set_file_contents ( " /tmp/lnd_deposit_address " , address )
2020-01-30 03:00:02 +00:00
except :
address = " ERROR "
return address
2019-06-15 23:02:44 +00:00
def get_lightning_info ( ) :
global lightning_info
return copy . deepcopy ( lightning_info )
2020-01-30 03:00:02 +00:00
def get_lightning_peers ( ) :
global lightning_peers
2021-03-17 04:31:46 +00:00
peerdata = copy . deepcopy ( lightning_peers )
peers = [ ]
if peerdata != None and " peers " in peerdata :
for p in peerdata [ " peers " ] :
peer = p
if " bytes_recv " in p :
peer [ " bytes_recv " ] = " {:.2f} " . format ( float ( p [ " bytes_recv " ] ) / 1000 / 1000 )
else :
peer [ " bytes_recv " ] = " N/A "
if " bytes_sent " in p :
peer [ " bytes_sent " ] = " {:.2f} " . format ( float ( p [ " bytes_sent " ] ) / 1000 / 1000 )
else :
peer [ " bytes_sent " ] = " N/A "
if " sat_sent " in p :
peer [ " sat_sent " ] = format_sat_amount ( peer [ " sat_sent " ] )
if " sat_recv " in p :
peer [ " sat_recv " ] = format_sat_amount ( peer [ " sat_recv " ] )
if " ping_time " not in p :
peer [ " ping_time " ] = " N/A "
if " pub_key " in p :
peer [ " alias " ] = get_lightning_peer_alias ( p [ " pub_key " ] )
else :
peer [ " alias " ] = " Unknown "
peers . append ( peer )
return peers
2020-01-30 03:00:02 +00:00
2021-03-09 03:55:39 +00:00
def get_lightning_node_info ( pubkey ) :
nodeinfo = lnd_get ( " /graph/node/ {} " . format ( pubkey ) , timeout = 2 )
return nodeinfo
def get_lightning_peer_alias ( pubkey ) :
global lightning_peer_aliases
if pubkey in lightning_peer_aliases :
return lightning_peer_aliases [ pubkey ]
nodeinfo = get_lightning_node_info ( pubkey )
if nodeinfo != None and " node " in nodeinfo :
if " alias " in nodeinfo [ " node " ] :
lightning_peer_aliases [ pubkey ] = nodeinfo [ " node " ] [ " alias " ]
return nodeinfo [ " node " ] [ " alias " ]
return " UNKNOWN "
2020-10-01 00:55:24 +00:00
def get_lightning_peer_count ( ) :
info = get_lightning_info ( )
num_peers = 0
2020-10-08 02:59:44 +00:00
if info != None and " num_peers " in info :
2020-10-01 00:55:24 +00:00
num_peers = info [ ' num_peers ' ]
return num_peers
2020-01-30 03:00:02 +00:00
def get_lightning_channels ( ) :
global lightning_channels
2021-03-17 04:31:46 +00:00
channeldata = copy . deepcopy ( lightning_channels )
channels = [ ]
if channeldata != None and " channels " in channeldata :
for c in channeldata [ " channels " ] :
channel = c
2021-03-28 02:36:47 +00:00
channel [ " status_color " ] = " gray "
if " active " in channel :
if channel [ " active " ] :
channel [ " status_color " ] = " green "
else :
channel [ " status_color " ] = " yellow "
2021-03-17 04:31:46 +00:00
if " capacity " in channel :
channel [ " capacity " ] = format_sat_amount ( channel [ " capacity " ] )
else :
channel [ " capacity " ] = " N/A "
if " local_balance " in channel and " remote_balance " in channel :
l = float ( channel [ " local_balance " ] )
r = float ( channel [ " remote_balance " ] )
channel [ " chan_percent " ] = ( l / ( l + r ) ) * 100
else :
channel [ " chan_percent " ] = " 0 "
if " local_balance " in channel :
channel [ " local_balance " ] = format_sat_amount ( channel [ " local_balance " ] )
else :
channel [ " local_balance " ] = " 0 "
if " remote_balance " in channel :
channel [ " remote_balance " ] = format_sat_amount ( channel [ " remote_balance " ] )
else :
channel [ " remote_balance " ] = " 0 "
if " remote_pubkey " in channel :
channel [ " remote_alias " ] = get_lightning_peer_alias ( channel [ " remote_pubkey " ] )
else :
channel [ " remote_alias " ] = " Unknown "
2021-03-25 03:44:03 +00:00
if " commit_fee " in channel :
channel [ " commit_fee " ] = format_sat_amount ( channel [ " commit_fee " ] )
else :
channel [ " commit_fee " ] = " 0 "
if " lifetime " in channel :
seconds = int ( channel [ " lifetime " ] )
channel [ " age " ] = " {} " . format ( str ( datetime . timedelta ( seconds = seconds ) ) )
else :
channel [ " age " ] = " N/A "
2021-03-17 04:31:46 +00:00
channels . append ( channel )
return channels
2020-01-30 03:00:02 +00:00
2020-10-01 00:55:24 +00:00
def get_lightning_channel_count ( ) :
2021-03-17 04:31:46 +00:00
channels = get_lightning_channels ( )
return len ( channels )
2020-10-01 00:55:24 +00:00
2020-01-30 03:00:02 +00:00
def get_lightning_channel_balance ( ) :
global lightning_channel_balance
return copy . deepcopy ( lightning_channel_balance )
def get_lightning_wallet_balance ( ) :
global lightning_wallet_balance
return copy . deepcopy ( lightning_wallet_balance )
2020-10-01 00:55:24 +00:00
def get_lightning_balance_info ( ) :
channel_balance_data = get_lightning_channel_balance ( )
wallet_balance_data = get_lightning_wallet_balance ( )
balance_data = { }
balance_data [ " channel_balance " ] = " N/A "
balance_data [ " channel_pending " ] = " N/A "
balance_data [ " wallet_balance " ] = " N/A "
balance_data [ " wallet_pending " ] = " N/A "
2021-05-03 03:28:02 +00:00
balance_data [ " total_balance " ] = " N/A "
channel_num = - 1
wallet_num = - 1
2020-10-01 00:55:24 +00:00
channel_balance_data = get_lightning_channel_balance ( )
if channel_balance_data != None and " balance " in channel_balance_data :
2021-03-15 04:58:40 +00:00
balance_data [ " channel_balance " ] = format_sat_amount ( channel_balance_data [ " balance " ] )
2021-05-03 03:28:02 +00:00
channel_num = int ( channel_balance_data [ " balance " ] )
2020-10-01 00:55:24 +00:00
if channel_balance_data != None and " pending_open_balance " in channel_balance_data :
2021-03-15 04:58:40 +00:00
balance_data [ " channel_pending " ] = format_sat_amount ( channel_balance_data [ " pending_open_balance " ] )
2020-10-01 00:55:24 +00:00
wallet_balance_data = get_lightning_wallet_balance ( )
if wallet_balance_data != None and " confirmed_balance " in wallet_balance_data :
2021-03-15 04:58:40 +00:00
balance_data [ " wallet_balance " ] = format_sat_amount ( wallet_balance_data [ " confirmed_balance " ] )
2021-05-03 03:28:02 +00:00
wallet_num = int ( wallet_balance_data [ " confirmed_balance " ] )
2020-10-01 00:55:24 +00:00
if wallet_balance_data != None and " unconfirmed_balance " in wallet_balance_data :
2021-03-15 04:58:40 +00:00
balance_data [ " wallet_pending " ] = format_sat_amount ( wallet_balance_data [ " unconfirmed_balance " ] )
2020-10-01 00:55:24 +00:00
2021-05-03 03:28:02 +00:00
if channel_num > = 0 and wallet_num > = 0 :
balance_data [ " total_balance " ] = format_sat_amount ( channel_num + wallet_num )
2022-01-07 03:57:00 +00:00
if get_randomize_balances ( ) :
channel_num = random . randint ( 40000 , 1000000 )
wallet_num = random . randint ( 100000 , 1500000 )
balance_data [ " channel_balance " ] = format_sat_amount ( channel_num )
balance_data [ " channel_pending " ] = " 0 "
balance_data [ " wallet_balance " ] = format_sat_amount ( wallet_num )
balance_data [ " wallet_pending " ] = " 0 "
balance_data [ " total_balance " ] = format_sat_amount ( channel_num + wallet_num )
2020-10-01 00:55:24 +00:00
return balance_data
2021-04-30 05:43:24 +00:00
def get_lightning_transactions ( ) :
global lightning_transactions
try :
transactions = [ ]
data = copy . deepcopy ( lightning_transactions )
for tx in data [ " transactions " ] :
2021-05-12 02:29:24 +00:00
tx [ " id " ] = tx [ " tx_hash " ]
2021-04-30 05:43:24 +00:00
tx [ " amount_str " ] = format_sat_amount ( tx [ " amount " ] )
tx [ " date_str " ] = time . strftime ( " % D % H: % M " , time . localtime ( int ( tx [ " time_stamp " ] ) ) )
transactions . append ( tx )
return transactions
except :
return None
def get_lightning_payments ( ) :
global lightning_payments
try :
payments = [ ]
data = copy . deepcopy ( lightning_payments )
for tx in data [ " payments " ] :
2021-05-12 02:29:24 +00:00
tx [ " id " ] = tx [ " payment_hash " ]
2021-05-03 03:28:02 +00:00
tx [ " type " ] = " PAYMENT "
2021-04-30 05:43:24 +00:00
tx [ " value_str " ] = format_sat_amount ( tx [ " value_sat " ] )
tx [ " fee_str " ] = format_sat_amount ( tx [ " fee " ] )
tx [ " date_str " ] = time . strftime ( " % D % H: % M " , time . localtime ( int ( tx [ " creation_date " ] ) ) )
2021-05-03 03:28:02 +00:00
tx [ " memo " ] = " "
2021-04-30 05:43:24 +00:00
payments . append ( tx )
payments . reverse ( )
return payments
except :
2021-05-12 02:29:24 +00:00
return [ ]
2021-04-30 05:43:24 +00:00
def get_lightning_invoices ( ) :
global lightning_invoices
try :
invoices = [ ]
data = copy . deepcopy ( lightning_invoices )
for tx in data [ " invoices " ] :
2021-05-12 02:29:24 +00:00
tx [ " id " ] = tx [ " r_hash " ]
2021-05-03 03:28:02 +00:00
tx [ " type " ] = " INVOICE "
2021-04-30 05:43:24 +00:00
tx [ " value_str " ] = format_sat_amount ( tx [ " value " ] )
tx [ " date_str " ] = time . strftime ( " % D % H: % M " , time . localtime ( int ( tx [ " creation_date " ] ) ) )
2021-11-07 04:40:57 +00:00
tx [ " memo " ] = unquote_plus ( tx [ " memo " ] )
2021-04-30 05:43:24 +00:00
invoices . append ( tx )
invoices . reverse ( )
return invoices
except :
2021-05-12 02:29:24 +00:00
return [ ]
2021-04-30 05:43:24 +00:00
2021-05-03 03:28:02 +00:00
def get_lightning_payments_and_invoices ( ) :
payments = get_lightning_payments ( )
invoices = get_lightning_invoices ( )
txs = [ ]
if payments == None and invoices == None :
2021-05-12 02:29:24 +00:00
return [ ]
2021-05-03 03:28:02 +00:00
elif payments == None and invoices != None :
return invoices
elif payments != None and invoices == None :
return payments
elif len ( payments ) == 0 and len ( invoices ) == 0 :
2021-05-12 02:29:24 +00:00
return [ ]
2021-05-03 03:28:02 +00:00
while len ( payments ) or len ( invoices ) :
if len ( payments ) == 0 :
txs . insert ( 0 , invoices . pop ( ) )
elif len ( invoices ) == 0 :
txs . insert ( 0 , payments . pop ( ) )
else :
# Prepend oldest to list
p = payments [ - 1 ]
i = invoices [ - 1 ]
if int ( p [ " creation_date " ] ) < int ( i [ " creation_date " ] ) :
txs . insert ( 0 , payments . pop ( ) )
else :
txs . insert ( 0 , invoices . pop ( ) )
for tx in txs :
if tx [ " type " ] == " PAYMENT " :
tx [ " value_str " ] = " - " + tx [ " value_str " ]
return txs
2021-04-02 01:58:19 +00:00
def get_lightning_watchtower_server_info ( ) :
global lightning_watchtower_server_info
2022-03-14 03:52:26 +00:00
server_info = copy . deepcopy ( lightning_watchtower_server_info )
server_info [ " watchtower_server_uri " ] = " ... "
if server_info != None :
try :
if " uris " in server_info and len ( server_info [ ' uris ' ] ) > 0 :
first_uri = True
text = " "
for uri in server_info [ ' uris ' ] :
if first_uri :
first_uri = False
else :
text + = " <br/> "
text + = uri
server_info [ " watchtower_server_uri " ] = text
elif " pubkey " in server_info or " listeners " in server_info :
server_info [ " watchtower_server_uri " ] = " "
if " pubkey " in server_info :
server_info [ " watchtower_server_uri " ] + = server_info [ " pubkey " ]
#if "listeners":
# server_info["watchtower_server_uri"] += "listeners: " + watchtower_server_info["listeners"][0]
except :
return server_info
return server_info
def get_lightning_watchtower_client_towers ( ) :
global lightning_watchtower_client_towers
towers = copy . deepcopy ( lightning_watchtower_client_towers )
return towers
def get_lightning_watchtower_client_stats ( ) :
global lightning_watchtower_client_stats
stats = copy . deepcopy ( lightning_watchtower_client_stats )
return stats
def get_lightning_watchtower_client_policy ( ) :
global lightning_watchtower_client_policy
policy = copy . deepcopy ( lightning_watchtower_client_policy )
return policy
2021-04-02 01:58:19 +00:00
2019-06-15 23:02:44 +00:00
def is_lnd_ready ( ) :
global lnd_ready
return lnd_ready
2021-04-30 05:43:24 +00:00
def lnd_get ( path , timeout = 10 , params = { } ) :
2019-06-15 23:02:44 +00:00
try :
macaroon = get_macaroon ( )
headers = { " Grpc-Metadata-macaroon " : macaroon }
2021-04-30 05:43:24 +00:00
r = requests . get ( " https://localhost: " + LND_REST_PORT + " /v1 " + path , verify = TLS_CERT_FILE , headers = headers , params = params , timeout = timeout )
2019-06-15 23:02:44 +00:00
except Exception as e :
2021-12-07 05:26:26 +00:00
log_message ( " ERROR in lnd_get: " + str ( e ) )
2020-11-08 21:13:03 +00:00
return { " error " : str ( e ) }
2019-06-15 23:02:44 +00:00
return r . json ( )
2021-04-02 01:58:19 +00:00
def lnd_get_v2 ( path , timeout = 10 ) :
try :
macaroon = get_macaroon ( )
headers = { ' Grpc-Metadata-macaroon ' : macaroon }
r = requests . get ( " https://localhost: " + LND_REST_PORT + " /v2 " + path , verify = TLS_CERT_FILE , headers = headers , timeout = timeout )
except Exception as e :
2021-12-07 05:26:26 +00:00
log_message ( " ERROR in lnd_get_v2: " + str ( e ) )
2021-04-02 01:58:19 +00:00
return { " error " : str ( e ) }
return r . json ( )
2019-06-15 23:02:44 +00:00
def gen_new_wallet_seed ( ) :
2022-01-30 19:58:00 +00:00
seed = to_string ( subprocess . check_output ( " python3 /usr/bin/gen_seed.py " , shell = True ) )
2019-06-15 23:02:44 +00:00
return seed
2021-03-31 03:09:55 +00:00
def get_lnd_lit_password ( ) :
2021-11-07 04:40:57 +00:00
return to_string ( get_file_contents ( " /mnt/hdd/mynode/settings/.litpw " ) )
2021-03-31 03:09:55 +00:00
2019-06-15 23:02:44 +00:00
def restart_lnd_actual ( ) :
2019-07-03 21:24:01 +00:00
global lnd_ready
lnd_ready = False
2019-06-15 23:02:44 +00:00
os . system ( " systemctl restart lnd " )
2019-11-04 04:50:47 +00:00
os . system ( " systemctl restart lnd_admin " )
2019-06-15 23:02:44 +00:00
def restart_lnd ( ) :
2021-05-01 04:39:58 +00:00
t = Timer ( 0.1 , restart_lnd_actual )
2019-06-15 23:02:44 +00:00
t . start ( )
2021-05-01 04:39:58 +00:00
time . sleep ( 1 )
2021-03-09 03:55:39 +00:00
def get_lightning_wallet_file ( ) :
if is_testnet_enabled ( ) :
return " /mnt/hdd/mynode/lnd/data/chain/bitcoin/testnet/wallet.db "
return " /mnt/hdd/mynode/lnd/data/chain/bitcoin/mainnet/wallet.db "
def get_lightning_macaroon_file ( ) :
if is_testnet_enabled ( ) :
return " /mnt/hdd/mynode/lnd/data/chain/bitcoin/testnet/admin.macaroon "
return " /mnt/hdd/mynode/lnd/data/chain/bitcoin/mainnet/admin.macaroon "
2019-06-15 23:02:44 +00:00
def get_macaroon ( ) :
2022-01-30 19:58:00 +00:00
m = to_string ( subprocess . check_output ( " xxd -ps -u -c 1000 " + get_lightning_macaroon_file ( ) , shell = True ) )
2019-06-15 23:02:44 +00:00
return m . strip ( )
def lnd_wallet_exists ( ) :
2021-03-09 03:55:39 +00:00
return os . path . isfile ( get_lightning_wallet_file ( ) )
2019-06-15 23:02:44 +00:00
def create_wallet ( seed ) :
try :
subprocess . check_call ( " create_lnd_wallet.tcl \" " + seed + " \" " , shell = True )
# Sync FS and sleep so the success redirect understands the wallet was created
os . system ( " sync " )
time . sleep ( 2 )
return True
except :
return False
def is_lnd_logged_in ( ) :
try :
macaroon = get_macaroon ( )
headers = { " Grpc-Metadata-macaroon " : macaroon }
r = requests . get ( " https://localhost: " + LND_REST_PORT + " /v1/getinfo " , verify = TLS_CERT_FILE , headers = headers )
if r . status_code == 200 and r . json ( ) :
return True
return False
except :
return False
2021-03-09 03:55:39 +00:00
def get_lnd_channel_backup_file ( ) :
if is_testnet_enabled ( ) :
return " /home/bitcoin/lnd_backup/channel_testnet.backup "
return " /home/bitcoin/lnd_backup/channel.backup "
2019-06-15 23:02:44 +00:00
def lnd_channel_backup_exists ( ) :
2021-03-09 03:55:39 +00:00
return os . path . isfile ( get_lnd_channel_backup_file ( ) )
2019-06-15 23:02:44 +00:00
2021-07-27 22:09:43 +00:00
def lnd_get_channel_db_size ( ) :
path = " mainnet "
if is_testnet_enabled ( ) :
path = " testnet "
size = " ??? "
try :
2022-01-30 19:58:00 +00:00
size = to_string ( subprocess . check_output ( " ls -lsah /mnt/hdd/mynode/lnd/data/graph/ " + path + " /channel.db | awk ' { print $6} ' " , shell = True ) )
2021-07-27 22:09:43 +00:00
except :
size = " ERR "
return size
2019-06-15 23:02:44 +00:00
def get_lnd_status ( ) :
2021-06-29 04:08:54 +00:00
#if not lnd_wallet_exists():
# return "Please create wallet..."
2019-06-15 23:02:44 +00:00
2021-04-11 00:51:26 +00:00
if not is_bitcoin_synced ( ) :
2020-10-03 04:43:30 +00:00
return " Waiting... "
2019-06-15 23:02:44 +00:00
if is_lnd_ready ( ) :
return " Running "
2019-09-25 01:21:33 +00:00
try :
2020-05-01 17:48:31 +00:00
log = get_journalctl_log ( " lnd " )
2019-09-25 01:21:33 +00:00
lines = log . splitlines ( )
for line in lines :
2021-06-29 04:08:54 +00:00
if " Waiting for wallet encryption password " in line and not lnd_wallet_exists ( ) :
return " Please create wallet... "
elif " Caught up to height " in line :
2019-09-25 01:21:33 +00:00
m = re . search ( " height ([0-9]+) " , line )
height = m . group ( 1 )
percent = 100.0 * ( float ( height ) / bitcoin_block_height )
return " Syncing... {:.2f} % " . format ( percent )
elif " Waiting for chain backend to finish sync " in line :
return " Syncing... "
elif " Started rescan from block " in line :
return " Scanning... "
2020-05-09 03:35:44 +00:00
elif " Version: " in line :
return " Launching... "
elif " Opening the main database " in line :
return " Opening DB... "
elif " Database now open " in line :
return " DB open... "
2021-02-27 17:23:45 +00:00
elif " unable to create server " in line :
return " Network Error "
2020-05-09 03:35:44 +00:00
elif " Waiting for wallet encryption password " in line :
return " Logging in... "
elif " LightningWallet opened " in line :
return " Wallet open... "
2021-06-29 04:08:54 +00:00
elif " wallet unlock password file was specified but wallet does not exist " in line :
return " Config Error "
2020-05-09 03:35:44 +00:00
2021-07-01 04:05:41 +00:00
# Check if no wallet file (log may have been rotated out, so can't get more accurate message)
if not lnd_wallet_exists ( ) :
return " Please create wallet... "
2019-09-25 01:21:33 +00:00
return " Waiting... "
except :
return " Status Error "
2020-10-03 04:43:30 +00:00
def get_lnd_status_color ( ) :
2021-04-11 00:51:26 +00:00
if not is_bitcoin_synced ( ) :
2020-10-03 04:43:30 +00:00
return " yellow "
2021-06-29 04:08:54 +00:00
#if not lnd_wallet_exists():
# # This hides the restart /login attempt LND does from the GUI
# return "green"
2020-10-03 04:43:30 +00:00
lnd_status_code = get_service_status_code ( " lnd " )
if lnd_status_code != 0 :
lnd_status_color = " red "
lnd_status = get_lnd_status ( )
if lnd_status == " Logging in... " :
lnd_status_color = " yellow "
2021-06-29 04:08:54 +00:00
return lnd_status_color
2020-10-03 04:43:30 +00:00
return " green "
2019-06-15 23:02:44 +00:00
2019-08-01 04:27:16 +00:00
def get_lnd_version ( ) :
global lnd_version
if lnd_version == None :
2021-11-07 04:40:57 +00:00
lnd_version = to_string ( subprocess . check_output ( " lnd --version | egrep -o ' [0-9]+ \\ .[0-9]+ \\ .[0-9]+ ' | head -n 1 " , shell = True ) )
2020-10-01 00:55:24 +00:00
return " v {} " . format ( lnd_version )
2019-11-04 04:50:47 +00:00
2021-01-16 18:15:52 +00:00
def get_loop_version ( ) :
global loop_version
if loop_version == None :
2021-11-07 04:40:57 +00:00
loop_version = to_string ( subprocess . check_output ( " loopd --version | egrep -o ' [0-9]+ \\ .[0-9]+ \\ .[0-9]+ ' | head -n 1 " , shell = True ) )
2021-01-16 18:15:52 +00:00
return " v {} " . format ( loop_version )
def get_pool_version ( ) :
global pool_version
if pool_version == None :
2021-11-07 04:40:57 +00:00
pool_version = to_string ( subprocess . check_output ( " poold --version | egrep -o ' [0-9]+ \\ .[0-9]+ \\ .[0-9]+ ' | head -n 1 " , shell = True ) )
2021-01-16 18:15:52 +00:00
return " v {} " . format ( pool_version )
2020-08-21 00:56:31 +00:00
2021-03-31 03:09:55 +00:00
def get_lit_version ( ) :
global lit_version
if lit_version == None :
2021-11-07 04:40:57 +00:00
#lit_version = to_string(subprocess.check_output("litd --version | egrep -o '[0-9]+\\.[0-9]+\\.[0-9]+' | head -n 1", shell=True))
2021-03-31 03:09:55 +00:00
lit_version = " TODO "
return " v {} " . format ( lit_version )
2019-11-04 04:50:47 +00:00
def get_default_lnd_config ( ) :
try :
with open ( " /usr/share/mynode/lnd.conf " ) as f :
return f . read ( )
except :
return " ERROR "
def get_lnd_config ( ) :
try :
with open ( " /mnt/hdd/mynode/lnd/lnd.conf " ) as f :
return f . read ( )
except :
return " ERROR "
2019-11-05 01:34:19 +00:00
def get_lnd_custom_config ( ) :
2019-11-04 04:50:47 +00:00
try :
2019-11-05 01:34:19 +00:00
with open ( " /mnt/hdd/mynode/settings/lnd_custom.conf " ) as f :
2019-11-04 04:50:47 +00:00
return f . read ( )
except :
return " ERROR "
2019-11-05 01:34:19 +00:00
def set_lnd_custom_config ( config ) :
2019-11-04 04:50:47 +00:00
try :
2019-11-05 01:34:19 +00:00
with open ( " /mnt/hdd/mynode/settings/lnd_custom.conf " , " w " ) as f :
2019-11-04 04:50:47 +00:00
f . write ( config )
os . system ( " sync " )
return True
except :
return False
2019-11-05 01:34:19 +00:00
2020-07-14 03:10:06 +00:00
def using_lnd_custom_config ( ) :
return os . path . isfile ( " /mnt/hdd/mynode/settings/lnd_custom.conf " )
2019-11-05 01:34:19 +00:00
def delete_lnd_custom_config ( ) :
2020-05-20 03:01:14 +00:00
os . system ( " rm -f /mnt/hdd/mynode/settings/lnd_custom.conf " )
def get_lnd_alias_file_data ( ) :
try :
with open ( " /mnt/hdd/mynode/settings/.lndalias " , " r " ) as f :
return f . read ( ) . strip ( )
except :
return " ERROR "
2021-04-01 01:41:52 +00:00
return " ERROR "
2022-03-24 03:23:08 +00:00
def is_watchtower_server_enabled ( ) :
2022-03-14 03:52:26 +00:00
return settings_file_exists ( " watchtower_enabled " )
2021-04-01 01:41:52 +00:00
2022-03-24 03:23:08 +00:00
def enable_watchtower_server ( ) :
2022-03-14 03:52:26 +00:00
create_settings_file ( " watchtower_enabled " )
2021-04-01 01:41:52 +00:00
2022-03-24 03:23:08 +00:00
def disable_watchtower_server ( ) :
2022-03-14 03:52:26 +00:00
delete_settings_file ( " watchtower_enabled " )
2022-03-07 04:02:30 +00:00
2022-03-24 03:23:08 +00:00
def is_watchtower_client_enabled ( ) :
return settings_file_exists ( " watchtower_client_enabled " )
def enable_watchtower_client ( ) :
create_settings_file ( " watchtower_client_enabled " )
def disable_watchtower_client ( ) :
delete_settings_file ( " watchtower_client_enabled " )
2022-03-07 04:02:30 +00:00
# Only call from www process which has data
def update_lightning_json_cache ( ) :
global LIGHTNING_CACHE_FILE
lightning_data = { }
lightning_data [ " info " ] = get_lightning_info ( )
lightning_data [ " peers " ] = get_lightning_peers ( )
lightning_data [ " channels " ] = get_lightning_channels ( )
lightning_data [ " balances " ] = get_lightning_balance_info ( )
#lightning_data["transactions"] = lightning_transactions
#lightning_data["payments"] = lightning_payments
#lightning_data["invoices"] = lightning_invoices
#lightning_data["watchtower_server_info"] = lightning_watchtower_server_info
return set_dictionary_file_cache ( lightning_data , LIGHTNING_CACHE_FILE )
# Can call from any process
def get_lightning_json_cache ( ) :
global LIGHTNING_CACHE_FILE
return get_dictionary_file_cache ( LIGHTNING_CACHE_FILE )