mirror of
https://github.com/aljazceru/plugins.git
synced 2025-12-20 22:54:19 +01:00
donations: Fixed up the README a bit
This commit is contained in:
@@ -61,159 +61,6 @@ from lib_autopilot import Strategy
|
|||||||
import networkx as nx
|
import networkx as nx
|
||||||
|
|
||||||
|
|
||||||
class CLightning_autopilot(Autopilot):
|
|
||||||
|
|
||||||
def __init__(self, path, input=None, dont_store=None):
|
|
||||||
self.__add_clogger()
|
|
||||||
|
|
||||||
self.__rpc_interface = LightningRpc(path)
|
|
||||||
self.__clogger.info("connection to RPC interface successful")
|
|
||||||
|
|
||||||
G = None
|
|
||||||
if input:
|
|
||||||
try:
|
|
||||||
self.__clogger.info(
|
|
||||||
"Try to load graph from file system at:" + input)
|
|
||||||
with open(input, "rb") as infile:
|
|
||||||
G = pickle.load(infile)
|
|
||||||
self.__clogger.info(
|
|
||||||
"Successfully restored the lightning network graph from data/networkx_graph")
|
|
||||||
except FileNotFoundError:
|
|
||||||
self.__clogger.info(
|
|
||||||
"input file not found. Load the graph from the peers of the lightning network")
|
|
||||||
G = self.__download_graph()
|
|
||||||
else:
|
|
||||||
self.__clogger.info(
|
|
||||||
"no input specified download graph from peers")
|
|
||||||
G = self.__download_graph()
|
|
||||||
|
|
||||||
if dont_store is None:
|
|
||||||
with open("lightning_networkx_graph.pickle", "wb") as outfile:
|
|
||||||
pickle.dump(G, outfile, pickle.HIGHEST_PROTOCOL)
|
|
||||||
|
|
||||||
Autopilot.__init__(self,G)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def __add_clogger(self):
|
|
||||||
""" initiates the logging service for this class """
|
|
||||||
# FIXME: adapt to the settings that are proper for you
|
|
||||||
self.__clogger = logging.getLogger('clightning-autopilot')
|
|
||||||
self.__clogger.setLevel(logging.INFO)
|
|
||||||
ch = logging.StreamHandler()
|
|
||||||
ch.setLevel(logging.INFO)
|
|
||||||
formatter = logging.Formatter(
|
|
||||||
'%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
|
||||||
ch.setFormatter(formatter)
|
|
||||||
self.__clogger.addHandler(ch)
|
|
||||||
self.__clogger.info("set up logging infrastructure")
|
|
||||||
|
|
||||||
def __get_seed_keys(self):
|
|
||||||
"""
|
|
||||||
retrieve the nodeids of the ln seed nodes from lseed.bitcoinstats.com
|
|
||||||
"""
|
|
||||||
domain = "lseed.bitcoinstats.com"
|
|
||||||
srv_records = dns.resolver.query(domain,"SRV")
|
|
||||||
res = []
|
|
||||||
for srv in srv_records:
|
|
||||||
bech32 = str(srv.target).rstrip(".").split(".")[0]
|
|
||||||
data = bech32_decode(bech32)[1]
|
|
||||||
decoded = convertbits(data, 5, 4)
|
|
||||||
res.append("".join(
|
|
||||||
['{:1x}'.format(integer) for integer in decoded])[:-1])
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
def __connect_to_seeds(self):
|
|
||||||
"""
|
|
||||||
sets up peering connection to seed nodes of the lightning network
|
|
||||||
|
|
||||||
This is necessary in case the node operating the autopilot has never
|
|
||||||
been connected to the lightning network.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
for nodeid in random.shuffle(self.__get_seed_keys()):
|
|
||||||
self.__clogger.info("peering with node: " + nodeid)
|
|
||||||
self.__rpc_interface.connect(nodeid)
|
|
||||||
# FIXME: better strategy than sleep(2) for building up
|
|
||||||
time.sleep(2)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __download_graph(self):
|
|
||||||
"""
|
|
||||||
Downloads a local copy of the nodes view of the lightning network
|
|
||||||
|
|
||||||
This copy is retrieved by listnodes and listedges RPC calls and will
|
|
||||||
thus be incomplete as peering might not be ready yet.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# FIXME: it is a real problem that we don't know how many nodes there
|
|
||||||
# could be. In particular billion nodes networks will outgrow memory
|
|
||||||
G = nx.Graph()
|
|
||||||
self.__clogger.info("Instantiated networkx graph to store the lightning network")
|
|
||||||
|
|
||||||
nodes = []
|
|
||||||
try:
|
|
||||||
self.__clogger.info(
|
|
||||||
"Attempt RPC-call to download nodes from the lightning network")
|
|
||||||
while len(nodes) == 0:
|
|
||||||
peers = self.__rpc_interface.listpeers()["peers"]
|
|
||||||
if len(peers) < 1:
|
|
||||||
self.__connect_to_seeds()
|
|
||||||
nodes = self.__rpc_interface.listnodes()["nodes"]
|
|
||||||
except ValueError as e:
|
|
||||||
self.__clogger.info(
|
|
||||||
"Node list could not be retrieved from the peers of the lightning network")
|
|
||||||
self.__clogger.debug("RPC error: " + str(e))
|
|
||||||
raise e
|
|
||||||
|
|
||||||
for node in nodes:
|
|
||||||
G.add_node(node["nodeid"], **node)
|
|
||||||
|
|
||||||
self.__clogger.info(
|
|
||||||
"Number of nodes found and added to the local networkx graph: {}".format(len(nodes)))
|
|
||||||
|
|
||||||
|
|
||||||
channels = {}
|
|
||||||
try:
|
|
||||||
self.__clogger.info(
|
|
||||||
"Attempt RPC-call to download channels from the lightning network")
|
|
||||||
channels = self.__rpc_interface.listchannels()["channels"]
|
|
||||||
self.__clogger.info(
|
|
||||||
"Number of retrieved channels: {}".format(
|
|
||||||
len(channels)))
|
|
||||||
except ValueError as e:
|
|
||||||
self.__clogger.info(
|
|
||||||
"Channel list could not be retrieved from the peers of the lightning network")
|
|
||||||
self.__clogger.debug("RPC error: " + str(e))
|
|
||||||
return False
|
|
||||||
|
|
||||||
for channel in channels:
|
|
||||||
G.add_edge(
|
|
||||||
channel["source"],
|
|
||||||
channel["destination"],
|
|
||||||
**channel)
|
|
||||||
|
|
||||||
return G
|
|
||||||
|
|
||||||
def connect(self, candidates, balance=1000000):
|
|
||||||
pdf = self.calculate_statistics(candidates)
|
|
||||||
connection_dict = self.calculate_proposed_channel_capacities(
|
|
||||||
pdf, balance)
|
|
||||||
for nodeid, fraction in connection_dict.items():
|
|
||||||
try:
|
|
||||||
satoshis = math.ceil(balance * fraction)
|
|
||||||
self.__clogger.info(
|
|
||||||
"Try to open channel with a capacity of {} to node {}".format(
|
|
||||||
satoshis, nodeid))
|
|
||||||
self.__rpc_interface.fundchannel(nodeid, satoshis)
|
|
||||||
except ValueError as e:
|
|
||||||
self.__clogger.info(
|
|
||||||
"Could not open a channel to {} with capacity of {}. Error: {}".format(
|
|
||||||
nodeid, satoshis, str(e)))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("-b", "--balance",
|
parser.add_argument("-b", "--balance",
|
||||||
@@ -262,8 +109,8 @@ if __name__ == '__main__':
|
|||||||
dont_store = args.dont_store)
|
dont_store = args.dont_store)
|
||||||
|
|
||||||
candidates = autopilot.find_candidates(num_channels,
|
candidates = autopilot.find_candidates(num_channels,
|
||||||
strategy = args.strategy,
|
strategy = args.strategy,
|
||||||
percentile = percentile)
|
percentile = percentile)
|
||||||
|
|
||||||
autopilot.connect(candidates, balance)
|
autopilot.connect(candidates, balance)
|
||||||
print("Autopilot finished. We hope it did a good job for you (and the lightning network). Thanks for using it.")
|
print("Autopilot finished. We hope it did a good job for you (and the lightning network). Thanks for using it.")
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class Strategy:
|
|||||||
|
|
||||||
class Autopilot():
|
class Autopilot():
|
||||||
|
|
||||||
def __init__(self,G):
|
def __init__(self, G):
|
||||||
self.__add_logger()
|
self.__add_logger()
|
||||||
self.G = G
|
self.G = G
|
||||||
|
|
||||||
|
|||||||
@@ -4,23 +4,34 @@ This plugin enables c-lightning nodes to start one or several small webserver
|
|||||||
via the command line on specified port. The webserver is based on flask and
|
via the command line on specified port. The webserver is based on flask and
|
||||||
exposes the invoice API call.
|
exposes the invoice API call.
|
||||||
|
|
||||||
Therefor people can query for an invoice which they can use to pay.
|
Therefor people can query for an invoice which they can use to pay. The plugin
|
||||||
|
can be started with `lightningd` by adding the following `--plugin` option
|
||||||
Run the plugin with:
|
(adjusting the path to wherever the plugins are actually stored):
|
||||||
|
|
||||||
```
|
```
|
||||||
lightningd --plugin=/path/to/lightning/contrib/plugins/donations/donations.py
|
lightningd --plugin=/path/to/plugins/donations.py
|
||||||
```
|
```
|
||||||
|
|
||||||
Once the plugin is active you can run `lightning-cli help donationserver`
|
By default the plugin will automatically start a webserver serving the donations page on port `33506`.
|
||||||
to learn about the command line API:
|
|
||||||
|
|
||||||
Controls a donationserver with `start`/`stop`/`restart`/`list` on `port`
|
|
||||||
|
|
||||||
A Simple HTTP Server is created that can serve a donation webpage and allow to issue invoices.
|
The following command line options are registered by the plugin and can be used to customize its behavior:
|
||||||
The plugin takes one of the following three commands {start/stop/restart} as the first agument
|
|
||||||
By default the plugin starts the server on port 8088. This can however be changed with the
|
| Command line option | Description |
|
||||||
port argument.
|
|------------------------|---------------------------------------------------------------------|
|
||||||
|
| `--donation-autostart` | Should the donation server start automatically? (default: `true`) |
|
||||||
|
| `--donation-web-port` | Which port should the donation server listen to? (default: `33506`) |
|
||||||
|
|
||||||
|
|
||||||
|
Once the plugin is active you can run `lightning-cli help donationserver` to
|
||||||
|
learn about the command line API:
|
||||||
|
|
||||||
|
Controls a donationserver with `start`/`stop`/`restart`/`list` on `port`.
|
||||||
|
|
||||||
|
A Simple HTTP Server is created that can serve a donation webpage and allow to
|
||||||
|
issue invoices. The plugin takes one of the following three commands
|
||||||
|
{start/stop/restart} as the first agument By default the plugin starts the
|
||||||
|
server on port 8088. This can however be changed with the port argument.
|
||||||
|
|
||||||
This means after starting `lightningd` together with the plugin you can run:
|
This means after starting `lightningd` together with the plugin you can run:
|
||||||
`lightning-cli donationserver start` and access the server at
|
`lightning-cli donationserver start` and access the server at
|
||||||
|
|||||||
Reference in New Issue
Block a user