Ejemplo n.º 1
0
    def __init__(self,
                 lightning_dir,
                 lightning_port,
                 btc,
                 executor=None,
                 node_id=0):
        self.bitcoin = btc
        self.executor = executor
        self.daemon = LightningD(lightning_dir,
                                 self.bitcoin,
                                 port=lightning_port)
        socket_path = os.path.join(lightning_dir,
                                   "lightning-rpc").format(node_id)
        self.invoice_count = 0
        self.logger = logging.getLogger(
            'lightning-node({})'.format(lightning_port))

        self.rpc = LightningRpc(socket_path, self.executor)

        orig_call = self.rpc._call

        def rpc_call(method, args):
            self.logger.debug("Calling {} with arguments {}".format(
                method, json.dumps(args, indent=4, sort_keys=True)))
            r = orig_call(method, args)
            self.logger.debug("Call returned {}".format(
                json.dumps(r, indent=4, sort_keys=True)))
            return r

        self.rpc._call = rpc_call
        self.myid = None
Ejemplo n.º 2
0
class CLightningWallet(Wallet):

    def __init__(self):
        if LightningRpc is None:  # pragma: nocover
            raise ImportError("The `pylightning` library must be installed to use `CLightningWallet`.")

        self.l1 = LightningRpc(getenv("CLIGHTNING_RPC"))

    def create_invoice(self, amount: int, memo: str = "") -> InvoiceResponse:
        label = "lbl{}".format(random.random())
        r = self.l1.invoice(amount*1000, label, memo, exposeprivatechannels=True)
        ok, checking_id, payment_request, error_message = True, r["payment_hash"], r["bolt11"], None
        return InvoiceResponse(ok, checking_id, payment_request, error_message)

    def pay_invoice(self, bolt11: str) -> PaymentResponse:
        r = self.l1.pay(bolt11)
        ok, checking_id, fee_msat, error_message = True, None, 0, None
        return PaymentResponse(ok, checking_id, fee_msat, error_message)

    def get_invoice_status(self, checking_id: str) -> PaymentStatus:
        r = self.l1.listinvoices(checking_id)
        if r['invoices'][0]['status'] == 'unpaid':
            return PaymentStatus(False)
        return PaymentStatus(True)

    def get_payment_status(self, checking_id: str) -> PaymentStatus:
        r = self.l1.listsendpays(checking_id)
        if not r.ok:
            return PaymentStatus(None)
        payments = [p for p in r.json()["payments"] if p["payment_hash"] == checking_id]
        payment = payments[0] if payments else None
        statuses = {"UNKNOWN": None, "IN_FLIGHT": None, "SUCCEEDED": True, "FAILED": False}
        return PaymentStatus(statuses[payment["status"]] if payment else None)
Ejemplo n.º 3
0
def init(options, configuration, plugin):
    global rpc, our_nodeid
    plugin.log("feereport init")
    path = join(configuration["lightning-dir"], configuration["rpc-file"])
    rpc = LightningRpc(path)
    info = rpc.getinfo()
    our_nodeid = info["id"]
Ejemplo n.º 4
0
    def __init__(self):
        if LightningRpc is None:  # pragma: nocover
            raise ImportError(
                "The `pylightning` library must be installed to use `CLightningWallet`."
            )

        self.rpc = getenv("CLIGHTNING_RPC")
        self.ln = LightningRpc(self.rpc)

        # check description_hash support (could be provided by a plugin)
        self.supports_description_hash = False
        try:
            answer = self.ln.help("invoicewithdescriptionhash")
            if answer["help"][0]["command"].startswith(
                    "invoicewithdescriptionhash msatoshi label description_hash",
            ):
                self.supports_description_hash = True
        except:
            pass

        # check last payindex so we can listen from that point on
        self.last_pay_index = 0
        invoices = self.ln.listinvoices()
        for inv in invoices["invoices"][::-1]:
            if "pay_index" in inv:
                self.last_pay_index = inv["pay_index"]
                break
Ejemplo n.º 5
0
	def __init__(self, network):

		self.__network = network

		if self.__network == "mainnet":
			self.rpc_interface = LightningRpc(expanduser("~")+"/.mainnet/lightning-rpc")


			self.rpc_interface.connect("02f6725f9c1c40333b67faea92fd211c183050f28df32cac3f9d69685fe9665432@104.198.32.198:9735")
			#self.rpc_interface.connect("030fe6f75d41d7112afee0f6f0e230095d9036abf19c7f88f416cc7b9ab9e9ef3e@203.206.164.188:9735")
			#self.rpc_interface.connect("03abf6f44c355dec0d5aa155bdbdd6e0c8fefe318eff402de65c6eb2e1be55dc3e@52.15.79.245:9735")
			#self.rpc_interface.connect("03cb7983dc247f9f81a0fa2dfa3ce1c255365f7279c8dd143e086ca333df10e278@46.28.204.21:9735")
			#self.rpc_interface.connect("03e50492eab4107a773141bb419e107bda3de3d55652e6e1a41225f06a0bbf2d56@35.172.33.197:9735")

		else:
			self.rpc_interface = LightningRpc(expanduser("~")+"/.lightning/lightning-rpc")

			self.rpc_interface.connect("03236a685d30096b26692dce0cf0fa7c8528bdf61dbf5363a3ef6d5c92733a3016@50.116.3.223:9734")
			#self.rpc_interface.connect("03782bb858e1ec9c0a4a5ac665ed658c97ced02e723eafc3c56137ab4e2e3caebf@52.8.119.71:9736")
			#self.rpc_interface.connect("02ec66fb12dd5d4943d63e7a1a35d063aec015e1c8b89cee6c9f2db3faf0f6687f@3.93.159.131:19735")
			#self.rpc_interface.connect("0218b92d19de937ef740154d20d3a6f37c44e6381ca72b95789295073664cfdd36@5.95.80.47:9735")

		print(type(self.rpc_interface.getinfo()))

		print(self.rpc_interface.listpeers())
Ejemplo n.º 6
0
    def __init__(self):
        if LightningRpc is None:  # pragma: nocover
            raise ImportError(
                "The `pylightning` library must be installed to use `CLightningWallet`."
            )

        self.l1 = LightningRpc(getenv("CLIGHTNING_RPC"))
Ejemplo n.º 7
0
def get_total_balance(n: LightningRpc) -> float:
    """return the total balance of this node in BTC, both in UTXOs and channels"""

    total_sat = (
        sum(map(lambda entry: entry["value"],
                n.listfunds()["outputs"])) +
        sum(map(lambda entry: entry["channel_sat"],
                n.listfunds()["channels"])))
    return total_sat / (10**8)  # convert to BTC
Ejemplo n.º 8
0
def index(request):
    # Bitcoin RPC Credentials (you need to change these)
    rpc_port = "8332"
    rpc_user = "******"
    rpc_password = "******"

    # LIGHTNING NETWORK

    # Lightning Network Socket file (you might need to change this)
    ln = LightningRpc("/home/pi/.lightning/lightning-rpc")

    try:
        l_info = ln.getinfo()
        l = LightningViewData(True)
        l.block_height = l_info["blockheight"]
        l.version = l_info["version"]
        l.version = l.version.replace("v", "")

        l_peers = ln.listpeers()
        l.peer_count = len(l_peers["peers"])

        l_funds = ln.listfunds()
        l.channel_count = len(l_funds["channels"])
    except:
        l = LightningViewData(False)

# BITCOIN

    b = BitcoinViewData(True)

    try:
        rpc_connection = AuthServiceProxy("http://%s:%[email protected]:%s" %
                                          (rpc_user, rpc_password, rpc_port))
        b_conn_count = rpc_connection.getconnectioncount()
        if b_conn_count > 0:
            b.online = True
    except Exception as e:
        b.running = False

    if b.running == True:
        try:
            b.block_height = rpc_connection.getblockcount()
            b_network_info = rpc_connection.getnetworkinfo()
            b.peer_count = b_network_info["connections"]
            b.version = b_network_info["subversion"]
            b.version = b.version.replace("/", "")
            b.version = b.version.replace("Satoshi:", "")
        except Exception as e:
            b.message = str(e)


# RETURN VIEW DATA

    return render(request, 'dashboard/index.html', {
        'lightning': l,
        'bitcoin': b
    })
Ejemplo n.º 9
0
def wait_to_route(src: LightningRpc, dest: LightningRpc,
                  msatoshi: int) -> None:
    """wait until src knows a route to dest with an amount of msatoshi"""
    found = False
    while not found:
        try:
            src.getroute(node_id=get_id(dest), msatoshi=msatoshi, riskfactor=1)
            found = True
        except RpcError as e:
            assert e.error["message"] == "Could not find a route", e
            time.sleep(2)
Ejemplo n.º 10
0
class CLightningWallet(Wallet):
    def __init__(self):
        if LightningRpc is None:  # pragma: nocover
            raise ImportError(
                "The `pylightning` library must be installed to use `CLightningWallet`."
            )

        self.l1 = LightningRpc(getenv("CLIGHTNING_RPC"))

    def create_invoice(self,
                       amount: int,
                       memo: str = "",
                       description_hash: bytes = b"") -> InvoiceResponse:
        if description_hash:
            raise Unsupported("description_hash")

        label = "lbl{}".format(random.random())
        r = self.l1.invoice(amount * 1000,
                            label,
                            memo,
                            exposeprivatechannels=True)
        ok, checking_id, payment_request, error_message = True, r[
            "payment_hash"], r["bolt11"], None
        return InvoiceResponse(ok, checking_id, payment_request, error_message)

    def pay_invoice(self, bolt11: str) -> PaymentResponse:
        r = self.l1.pay(bolt11)
        ok, checking_id, fee_msat, error_message = True, r[
            "payment_hash"], r["msatoshi_sent"] - r["msatoshi"], None
        return PaymentResponse(ok, checking_id, fee_msat, error_message)

    def get_invoice_status(self, checking_id: str) -> PaymentStatus:
        r = self.l1.listinvoices(checking_id)
        if not r["invoices"]:
            return PaymentStatus(False)
        if r["invoices"][0]["label"] == checking_id:
            return PaymentStatus(r["pays"][0]["status"] == "paid")
        raise KeyError("supplied an invalid checking_id")

    def get_payment_status(self, checking_id: str) -> PaymentStatus:
        r = self.l1.listpays(payment_hash=checking_id)
        if not r["pays"]:
            return PaymentStatus(False)
        if r["pays"][0]["payment_hash"] == checking_id:
            status = r["pays"][0]["status"]
            if status == "complete":
                return PaymentStatus(True)
            elif status == "failed":
                return PaymentStatus(False)
            return PaymentStatus(None)
        raise KeyError("supplied an invalid checking_id")
Ejemplo n.º 11
0
    def get_node(self, legacy=True):
        node_id = self.next_id
        self.next_id += 1

        lightning_dir = os.path.join(TEST_DIR, self.func._testMethodName,
                                     "lightning-{}/".format(node_id))

        socket_path = os.path.join(lightning_dir,
                                   "lightning-rpc").format(node_id)
        port = 16330 + node_id
        if legacy:
            daemon = utils.LegacyLightningD(lightning_dir,
                                            bitcoind.bitcoin_dir,
                                            port=port)
            rpc = LegacyLightningRpc(socket_path, self.executor)
        else:
            daemon = utils.LightningD(lightning_dir,
                                      bitcoind.bitcoin_dir,
                                      port=port)
            rpc = LightningRpc(socket_path, self.executor)

        node = utils.LightningNode(daemon, rpc, bitcoind, self.executor)
        self.nodes.append(node)
        if VALGRIND:
            node.daemon.cmd_line = [
                'valgrind', '-q', '--error-exitcode=7',
                '--log-file={}/valgrind-errors'.format(
                    node.daemon.lightning_dir)
            ] + node.daemon.cmd_line

        node.daemon.start()
        # Cache `getinfo`, we'll be using it a lot
        node.info = node.rpc.getinfo()
        return node
def init(options, configuration, plugin):
    global rpc_interface

    # connect to the rpc interface
    rpc_interface = LightningRpc(
        join(configuration['lightning-dir'], configuration['rpc-file']))
    plugin.log("Plugin csvexportpays.py initialized")
Ejemplo n.º 13
0
    def get_node(self, disconnect=None):
        node_id = self.next_id
        self.next_id += 1

        lightning_dir = os.path.join(TEST_DIR, self.func._testMethodName,
                                     "lightning-{}/".format(node_id))

        socket_path = os.path.join(lightning_dir,
                                   "lightning-rpc").format(node_id)
        port = 16330 + node_id
        daemon = utils.LightningD(lightning_dir,
                                  bitcoind.bitcoin_dir,
                                  port=port)
        # If we have a disconnect string, dump it to a file for daemon.
        if disconnect:
            with open(os.path.join(lightning_dir, "dev_disconnect"), "w") as f:
                f.write("\n".join(disconnect))
            daemon.cmd_line.append("--dev-disconnect=dev_disconnect")
        rpc = LightningRpc(socket_path, self.executor)

        node = utils.LightningNode(daemon, rpc, bitcoind, self.executor)
        self.nodes.append(node)
        if VALGRIND:
            node.daemon.cmd_line = [
                'valgrind', '-q', '--trace-children=yes',
                '--trace-children-skip=*bitcoin-cli*', '--error-exitcode=7',
                '--log-file={}/valgrind-errors.%p'.format(
                    node.daemon.lightning_dir)
            ] + node.daemon.cmd_line

        node.daemon.start()
        # Cache `getinfo`, we'll be using it a lot
        node.info = node.rpc.getinfo()
        return node
Ejemplo n.º 14
0
 def __init__(self,
              lightning_dir,
              lightning_port,
              btc,
              executor=None,
              node_id=0):
     self.bitcoin = btc
     self.executor = executor
     self.daemon = LightningD(lightning_dir,
                              btc.bitcoin_dir,
                              port=lightning_port)
     socket_path = os.path.join(lightning_dir,
                                "lightning-rpc").format(node_id)
     self.invoice_count = 0
     self.rpc = LightningRpc(socket_path, self.executor)
     self.logger = logging.getLogger(
         'lightning-node({})'.format(lightning_port))
Ejemplo n.º 15
0
    def get_node(self,
                 name=None,
                 disconnect=None,
                 options=None,
                 may_fail=False,
                 may_reconnect=False,
                 random_hsm=False,
                 feerates=(15000, 7500, 3750),
                 start=True,
                 log_all_io=False):
        with self.lock:
            node_id = self.next_id
            self.next_id += 1

        if not name:
            name = "node-{}".format(node_id)

        port = self.get_next_port()

        lightning_dir = os.path.join(self.directory,
                                     "lightning-{}/".format(node_id))

        if os.path.exists(lightning_dir):
            shutil.rmtree(lightning_dir)

        socket_path = os.path.join(lightning_dir,
                                   "lightning-rpc").format(node_id)
        daemon = LightningD(lightning_dir,
                            self.bitcoind,
                            port=port,
                            random_hsm=random_hsm,
                            node_id=node_id)
        # If we have a disconnect string, dump it to a file for daemon.
        if options is not None:
            daemon.opts.update(options)
        daemon.opts['alias'] = name

        rpc = LightningRpc(socket_path, self.executor)

        node = LightningNode(daemon,
                             rpc,
                             self.bitcoind,
                             self.executor,
                             may_fail=may_fail,
                             may_reconnect=may_reconnect)

        node.name = name
        self.nodes.append(node)
        if start:
            try:
                node.start()
            except Exception:
                node.daemon.stop()
                raise
        return node
Ejemplo n.º 16
0
    def _init(self, options, configuration, request):
        self.rpc_filename = configuration['rpc-file']
        self.lightning_dir = configuration['lightning-dir']
        path = os.path.join(self.lightning_dir, self.rpc_filename)
        self.rpc = LightningRpc(path)
        for name, value in options.items():
            self.options[name]['value'] = value

        # Dispatch the plugin's init handler if any
        if self.child_init:
            return self._exec_func(self.child_init, request)
        return None
Ejemplo n.º 17
0
class LightningDaemon(object):
    def __init__(self, daemon_rpc):
        self.rpc = LightningRpc(daemon_rpc)

    def invoice_c_lightning(self, msatoshi, label, description):
        result = self.rpc.invoice(msatoshi,
                                  label,
                                  description,
                                  expiry=INVOICE_EXPIRY)
        log(json.dumps(result, indent=1, sort_keys=True))
        return result

    def get_c_lightning_invoices(self):
        result = self.rpc.listinvoices()
        #log(json.dumps(result, indent=1, sort_keys=True))
        return result

    def delete(self, label, state="paid"):
        result = self.rpc.delinvoice(label, state)
        #        log(json.dumps(result, indent=1, sort_keys=True))
        return result

    def getinfo(self):
        return self.rpc.getinfo()

    def listfunds(self):
        return self.rpc.listfunds()

    def listnodes(self):
        return self.rpc.listnodes()
Ejemplo n.º 18
0
def init(options, configuration, plugin, **kwargs):
    global lightning_rpc, bitcoin_rpc, rpc_settings
    print(configuration)
    # setup lightning rpc
    lightning_dir, rpc_file = configuration['lightning-dir'], configuration['rpc-file']
    path = Path(f"{lightning_dir}/{rpc_file}")
    lightning_rpc = LightningRpc(str(path))

    # setup bitcoin rpc
    config = lightning_rpc.listconfigs()
    rpc_settings['user'] = config['bitcoin-rpcuser']
    rpc_settings['password'] = config['bitcoin-rpcpassword']
    rpc_settings['port'] = config['bitcoin-rpcport']
    rpc_settings['host'] = config['bitcoin-rpcconnect']
    network = config['network']

    template = "http://{user}:{password}@{host}:{port}"
    uri = template.format(**rpc_settings)
    bitcoin_rpc = AuthServiceProxy(uri)

    # check that it works
    bitcoin_rpc.getblockchaininfo()
Ejemplo n.º 19
0
def make_many_payments(
    sender: LightningRpc,
    receiver: LightningRpc,
    num_payments: int,
    msatoshi_per_payment: int,
) -> None:
    # in case the receiver is evil, the secret will not be returned and the call
    # to LightningRpc.pay will be stuck, waiting for the secret. therefore we
    # use the lower-level 'sendpay' method which doesn't wait for payment completion

    for i in range(num_payments):
        invoice = receiver.invoice(
            msatoshi=msatoshi_per_payment,
            label=f"label_{time.time()}",  # a unique label is needed
            description="",
        )
        route = sender.getroute(
            node_id=get_id(receiver),
            msatoshi=msatoshi_per_payment,
            riskfactor=1,
        )["route"]

        sender.sendpay(route=route, payment_hash=invoice["payment_hash"])
Ejemplo n.º 20
0
    def _init(self, options, configuration, request):
        self.rpc_filename = configuration['rpc-file']
        self.lightning_dir = configuration['lightning-dir']
        path = os.path.join(self.lightning_dir, self.rpc_filename)
        self.rpc = LightningRpc(path)
        for name, value in options.items():
            self.options[name]['value'] = value

        # Swap the registered `init` method handler back in and
        # re-dispatch
        if self.init:
            self.methods['init'], _ = self.init
            self.init = None
            return self._exec_func(self.methods['init'], request)
        return None
Ejemplo n.º 21
0
    def current_status(self):
        if self.status == "unpaid":
            try:
                inv = LightningRpc(settings.LIGHTNING_RPC).listinvoices(self.label)

                inv_ln = inv['invoices'][0]
                if inv_ln['status'] == "expired":
                    self.status = inv_ln['status']
                if inv_ln['status'] == "paid":
                    self.status = inv_ln['status']
                    self.paid_at = datetime.fromtimestamp(inv_ln['paid_at'], timezone.utc)
                    self.pay_index = inv_ln['pay_index']
                self.save()
                return self.status
            except:
                return '-'
        else:
            return self.status
Ejemplo n.º 22
0
def fund_channel(
    funder: LightningRpc,
    fundee: LightningRpc,
    num_satoshi: int,
    blocks_to_mine=6,
) -> TXID:
    """
    fund a channel between the two nodes with initial num_satoshi satoshis, and
    mine blocks_to_mine blocks.
    blocks_to_mine should be the minimum number of blocks required for this channel
    to be considered valid.
    funder and fundee should be already connected
    
    If all went well, the funding txid is returned
    """
    funding_txid = funder.fundchannel(node_id=get_id(fundee),
                                      satoshi=num_satoshi)['txid']
    mine(blocks_to_mine)
    return funding_txid
Ejemplo n.º 23
0
    def get_node(self, legacy=True):
        node_id = self.next_id
        self.next_id += 1

        lightning_dir = os.path.join(TEST_DIR, self.func._testMethodName,
                                     "lightning-{}/".format(node_id))

        socket_path = os.path.join(lightning_dir,
                                   "lightning-rpc").format(node_id)
        port = 16330 + node_id
        if legacy:
            daemon = utils.LegacyLightningD(lightning_dir,
                                            bitcoind.bitcoin_dir,
                                            port=port)
            rpc = LegacyLightningRpc(socket_path, self.executor)
        else:
            daemon = utils.LightningD(lightning_dir,
                                      bitcoind.bitcoin_dir,
                                      port=port)
            # TODO(cdecker) Move into LIGHTNINGD_CONFIG once legacy daemon was removed
            daemon.cmd_line.append("--dev-broadcast-interval=1000")
            rpc = LightningRpc(socket_path, self.executor)

        node = utils.LightningNode(daemon, rpc, bitcoind, self.executor)
        self.nodes.append(node)
        if VALGRIND:
            node.daemon.cmd_line = [
                'valgrind', '-q', '--trace-children=yes',
                '--trace-children-skip=*bitcoin-cli*', '--error-exitcode=7',
                '--log-file={}/valgrind-errors'.format(
                    node.daemon.lightning_dir)
            ] + node.daemon.cmd_line

        node.daemon.start()
        # Cache `getinfo`, we'll be using it a lot
        node.info = node.rpc.getinfo()
        return node
Ejemplo n.º 24
0
    def get_node(self,
                 disconnect=None,
                 options=None,
                 may_fail=False,
                 may_reconnect=False,
                 random_hsm=False,
                 feerates=(15000, 7500, 3750),
                 start=True,
                 log_all_io=False,
                 dbfile=None,
                 node_id=None):
        if not node_id:
            node_id = self.get_node_id()

        port = self.get_next_port()

        lightning_dir = os.path.join(self.directory,
                                     "lightning-{}/".format(node_id))

        if os.path.exists(lightning_dir):
            shutil.rmtree(lightning_dir)

        socket_path = os.path.join(lightning_dir,
                                   "lightning-rpc").format(node_id)
        daemon = LightningD(lightning_dir,
                            bitcoindproxy=self.bitcoind.get_proxy(),
                            port=port,
                            random_hsm=random_hsm,
                            node_id=node_id)
        # If we have a disconnect string, dump it to a file for daemon.
        if disconnect:
            daemon.disconnect_file = os.path.join(lightning_dir,
                                                  "dev_disconnect")
            with open(daemon.disconnect_file, "w") as f:
                f.write("\n".join(disconnect))
            daemon.opts["dev-disconnect"] = "dev_disconnect"
        if log_all_io:
            assert DEVELOPER
            daemon.env["LIGHTNINGD_DEV_LOG_IO"] = "1"
            daemon.opts["log-level"] = "io"
        if DEVELOPER:
            daemon.opts["dev-fail-on-subdaemon-fail"] = None
            daemon.env["LIGHTNINGD_DEV_MEMLEAK"] = "1"
            if os.getenv("DEBUG_SUBD"):
                daemon.opts["dev-debugger"] = os.getenv("DEBUG_SUBD")
            if VALGRIND:
                daemon.env["LIGHTNINGD_DEV_NO_BACKTRACE"] = "1"
            if not may_reconnect:
                daemon.opts["dev-no-reconnect"] = None

        if options is not None:
            daemon.opts.update(options)

        rpc = LightningRpc(socket_path, self.executor)

        node = LightningNode(daemon,
                             rpc,
                             self.bitcoind,
                             self.executor,
                             may_fail=may_fail,
                             may_reconnect=may_reconnect)

        # Regtest estimatefee are unusable, so override.
        node.set_feerates(feerates, False)

        self.nodes.append(node)
        if VALGRIND:
            node.daemon.cmd_prefix = [
                'valgrind', '-q', '--trace-children=yes',
                '--trace-children-skip=*python*,*bitcoin-cli*',
                '--error-exitcode=7',
                '--log-file={}/valgrind-errors.%p'.format(
                    node.daemon.lightning_dir)
            ]

        if dbfile:
            out = open(
                os.path.join(node.daemon.lightning_dir, 'lightningd.sqlite3'),
                'xb')
            with lzma.open(os.path.join('tests/data', dbfile), 'rb') as f:
                out.write(f.read())

        if start:
            try:
                node.start()
            except Exception:
                node.daemon.stop()
                raise
        return node
Ejemplo n.º 25
0
    def get_node(self,
                 disconnect=None,
                 options=None,
                 may_fail=False,
                 may_reconnect=False,
                 random_hsm=False,
                 feerates=(15000, 7500, 3750),
                 start=True,
                 fake_bitcoin_cli=False,
                 log_all_io=False):
        with self.lock:
            node_id = self.next_id
            self.next_id += 1
        port = self.get_next_port()

        lightning_dir = os.path.join(self.directory,
                                     "lightning-{}/".format(node_id))

        if os.path.exists(lightning_dir):
            shutil.rmtree(lightning_dir)

        socket_path = os.path.join(lightning_dir,
                                   "lightning-rpc").format(node_id)
        daemon = LightningD(lightning_dir,
                            self.bitcoind.bitcoin_dir,
                            port=port,
                            random_hsm=random_hsm,
                            node_id=node_id)
        # If we have a disconnect string, dump it to a file for daemon.
        if disconnect:
            daemon.disconnect_file = os.path.join(lightning_dir,
                                                  "dev_disconnect")
            with open(daemon.disconnect_file, "w") as f:
                f.write("\n".join(disconnect))
            daemon.opts["dev-disconnect"] = "dev_disconnect"
        if log_all_io:
            assert DEVELOPER
            daemon.env["LIGHTNINGD_DEV_LOG_IO"] = "1"
            daemon.opts["log-level"] = "io"
        if DEVELOPER:
            daemon.opts["dev-fail-on-subdaemon-fail"] = None
            daemon.env["LIGHTNINGD_DEV_MEMLEAK"] = "1"
            if VALGRIND:
                daemon.env["LIGHTNINGD_DEV_NO_BACKTRACE"] = "1"
            if not may_reconnect:
                daemon.opts["dev-no-reconnect"] = None

        cli = os.path.join(lightning_dir, "fake-bitcoin-cli")
        with open(cli, "w") as text_file:
            text_file.write(
                '#! /bin/sh\n'
                '! [ -x bitcoin-cli-fail ] || exec ./bitcoin-cli-fail "$@"\n'
                'for a in "$@"; do\n'
                '\t! [ -x bitcoin-cli-fail-"$a" ] || exec ./bitcoin-cli-fail-"$a" "$@"\n'
                'done\n'
                'exec bitcoin-cli "$@"\n')
        os.chmod(cli, os.stat(cli).st_mode | stat.S_IEXEC)
        daemon.opts['bitcoin-cli'] = cli

        if options is not None:
            daemon.opts.update(options)

        rpc = LightningRpc(socket_path, self.executor)

        node = LightningNode(daemon,
                             rpc,
                             self.bitcoind,
                             self.executor,
                             may_fail=may_fail,
                             may_reconnect=may_reconnect)

        # Regtest estimatefee are unusable, so override.
        node.set_feerates(feerates, False)

        self.nodes.append(node)
        if VALGRIND:
            node.daemon.cmd_prefix = [
                'valgrind', '-q', '--trace-children=yes',
                '--trace-children-skip=*bitcoin-cli*', '--error-exitcode=7',
                '--log-file={}/valgrind-errors.%p'.format(
                    node.daemon.lightning_dir)
            ]

        if start:
            try:
                node.start()
            except Exception:
                node.daemon.stop()
                raise
        return node
Ejemplo n.º 26
0
class LightningNode(object):

    displayName = 'lightning'

    def __init__(self,
                 lightning_dir,
                 lightning_port,
                 btc,
                 executor=None,
                 node_id=0):
        self.bitcoin = btc
        self.executor = executor
        self.daemon = LightningD(lightning_dir,
                                 self.bitcoin,
                                 port=lightning_port)
        socket_path = os.path.join(lightning_dir,
                                   "lightning-rpc").format(node_id)
        self.invoice_count = 0
        self.logger = logging.getLogger(
            'lightning-node({})'.format(lightning_port))

        self.rpc = LightningRpc(socket_path, self.executor)

        orig_call = self.rpc._call

        def rpc_call(method, args):
            self.logger.debug("Calling {} with arguments {}".format(
                method, json.dumps(args, indent=4, sort_keys=True)))
            r = orig_call(method, args)
            self.logger.debug("Call returned {}".format(
                json.dumps(r, indent=4, sort_keys=True)))
            return r

        self.rpc._call = rpc_call
        self.myid = None

    def peers(self):
        return [p['id'] for p in self.rpc.listpeers()['peers']]

    def getinfo(self):
        if not self.info:
            self.info = self.rpc.getinfo()
        return self.info

    def id(self):
        if not self.myid:
            self.myid = self.rpc.getinfo()['id']
        return self.myid

    def openchannel(self, node_id, host, port, satoshis):
        # Make sure we have a connection already
        if node_id not in self.peers():
            raise ValueError("Must connect to node before opening a channel")
        return self.rpc.fundchannel(node_id, satoshis)

    def getaddress(self):
        return self.rpc.newaddr()['address']

    def addfunds(self, bitcoind, satoshis):
        addr = self.getaddress()
        txid = bitcoind.rpc.sendtoaddress(addr, float(satoshis) / 10**8)
        bitcoind.rpc.getrawtransaction(txid)
        while len(self.rpc.listfunds()['outputs']) == 0:
            time.sleep(1)
            bitcoind.rpc.generate(1)

    def ping(self):
        """ Simple liveness test to see if the node is up and running

        Returns true if the node is reachable via RPC, false otherwise.
        """
        try:
            self.rpc.help()
            return True
        except:
            return False

    def check_channel(self, remote, require_both=False):
        """Make sure that we have an active channel with remote

        `require_both` must be False unless the other side supports
        sending a `channel_announcement` and `channel_update` on
        `funding_locked`. This doesn't work for eclair for example.

        """
        remote_id = remote.id()
        self_id = self.id()
        peer = None
        for p in self.rpc.listpeers()['peers']:
            if remote.id() == p['id']:
                peer = p
                break
        if not peer:
            self.logger.debug('Peer {} not found in listpeers'.format(remote))
            return False

        if len(peer['channels']) < 1:
            self.logger.debug(
                'Peer {} has no channel open with us'.format(remote))
            return False

        state = p['channels'][0]['state']
        self.logger.debug("Channel {} -> {} state: {}".format(
            self_id, remote_id, state))

        if state != 'CHANNELD_NORMAL' or not p['connected']:
            self.logger.debug(
                'Channel with peer {} is not in state normal ({}) or peer is not connected ({})'
                .format(remote_id, state, p['connected']))
            return False

        # Make sure that gossipd sees a local channel_update for routing
        scid = p['channels'][0]['short_channel_id']

        channels = self.rpc.listchannels(scid)['channels']

        if not require_both and len(channels) >= 1:
            return channels[0]['active']

        if len(channels) != 2:
            self.logger.debug(
                'Waiting for both channel directions to be announced: 2 != {}'.
                format(len(channels)))
            return False

        return channels[0]['active'] and channels[1]['active']

    def getchannels(self):
        result = []
        for c in self.rpc.listchannels()['channels']:
            result.append((c['source'], c['destination']))
        return set(result)

    def getnodes(self):
        return set([n['nodeid'] for n in self.rpc.listnodes()['nodes']])

    def invoice(self, amount):
        invoice = self.rpc.invoice(amount, "invoice%d" % (self.invoice_count),
                                   "description")
        self.invoice_count += 1
        return invoice['bolt11']

    def send(self, req):
        result = self.rpc.pay(req)
        return result['payment_preimage']

    def connect(self, host, port, node_id):
        return self.rpc.connect(node_id, host, port)

    def info(self):
        r = self.rpc.getinfo()
        return {
            'id': r['id'],
            'blockheight': r['blockheight'],
        }

    def block_sync(self, blockhash):
        time.sleep(1)

    def restart(self):
        self.daemon.stop()
        time.sleep(5)
        self.daemon.start()
        time.sleep(1)

    def stop(self):
        self.daemon.stop()

    def start(self):
        self.daemon.start()

    def check_route(self, node_id, amount):
        try:
            r = self.rpc.getroute(node_id, amount, 1.0)
        except ValueError as e:
            if (str(e).find("Could not find a route") > 0):
                return False
            raise
        return True
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)))
Ejemplo n.º 28
0
def generate_invoice():
    # Generate the invoice
    l1 = LightningRpc("/home/admin/.lightning/lightning-rpc")
    invoice = l1.invoice(10000,"1n1{}".format(random.random()),"static-discharge")
    return invoice['bolt11']
Ejemplo n.º 29
0
from lightning import LightningRpc
from flask import Flask, request, render_template
import random
import qrcode
import json
import re
import ast
app = Flask(__name__)

# Connect to local LN node
ln = LightningRpc("/tmp/lightning-rpc")

@app.route("/")
def fulmo():
	return render_template('index.html')

@app.route("/newaddr/")
def new_address():
	addr_type = request.args.get('type')
	make_qr = request.args.get('qr')

	try:
		addr = ln.newaddr(addr_type)
		result = {}
		result["address"] = addr["address"]

		if make_qr is not None:
			result["qr"] = qr(addr['address'])

	except ValueError, e:
		result = parse_exception(e)
Ejemplo n.º 30
0
auth = HTTPBasicAuth()
app = Flask(__name__)
api = Api(app)

USER_DATA = {"bAxX0zoh8ObADbAD0": "bAxX0zoh8ObADbAD0"}

telegram_bot_token = '60423423281:Ac2lUjuOPX0NAc2lUjuOPHxpbADxhxyQc'
atomic_tipbot = '8834534558:AAc2lUt7BoPi7P3t7BoPi7P3t7BoPi7PurwOP0zEw'
telegram_bot = telegram.Bot(telegram_bot_token)
userbot = telegram.Bot(atomic_tipbot)

dbclient = pymongo.MongoClient('192.168.0.43')
mongo_db = "tipdb"
mongo = dbclient[mongo_db]

lnltc = LightningRpc("/home/ltc/.lightning/lightning-rpc")
lnbtc = LightningRpc("/home/payer/.lightning/lightning-rpc")


def sendTele(msg):
    telegram_bot.send_message(chat_id='admin_user_id',
                              text="paylightning.py:\n " + msg)


def sendNBpic(userid, msg):
    userbot.send_animation(userid,
                           animation="https://i.imgur.com/UY8I7ow.gif",
                           caption=msg)


def notifyUser(userid, msg):