donations: Fixed up the README a bit

This commit is contained in:
Christian Decker
2019-03-28 16:07:51 +01:00
parent 638c24cb41
commit 92d2bbe262
3 changed files with 25 additions and 167 deletions

View File

@@ -61,159 +61,6 @@ from lib_autopilot import Strategy
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__':
parser = argparse.ArgumentParser()
parser.add_argument("-b", "--balance",
@@ -262,8 +109,8 @@ if __name__ == '__main__':
dont_store = args.dont_store)
candidates = autopilot.find_candidates(num_channels,
strategy = args.strategy,
strategy = args.strategy,
percentile = percentile)
autopilot.connect(candidates, balance)
print("Autopilot finished. We hope it did a good job for you (and the lightning network). Thanks for using it.")