I'm trying to understand how Lightning works by running tests using Bitcoin Core on my local machine in REGTEST mode together with running two LND Lightning nodes (let's call them the classic Bob & Alice) on separate localhost ports too. I'm using bitcoin-cli
and lncli
to interface with the nodes.
I made Alice's LN connect to Bob's LN and opened a channel between them with an initial capacity of 10,000,000 sats, funded by Alice's chain wallet, and included a --pushamt
of 35,000 sats to Bob's LN in order to create some inbound liquidity. This all seemed to have worked just fine and as expected, and the funding transaction into a 2of2 Multisig covering the channel was added into the blockchain too (6 confirmations).
However, something's nevertheless wrong. Despite Alice having sent out BTC on the channel, Bob cannot send any of that BTC back to Alice! I even had Bob send Alice an invoice for another 5,000 sats, but nothing changed after she paid it (other than an increase in her remote balance to 40,000 sats)---still Bob still cannot send her even 1 sat using the channel's inbound liquidity! I'm just not understanding why that is.
Session status from Alice's perspective (local/remote is reversed for Bob, of course):
$ lncli --lnddir=lnd_alice -n regtest openchannel --connect 127.0.0.1:9736 --node_key 030fb4423c15e3e049dbbdc646d0ef3ab7450a891652bbe0c39a14a8f5b44dc15f --sat_per_vbyte 1 --local_amt 10000000 --push_amt 35000 --block --base_fee_msat 1000 --fee_rate_ppm 10 --min_confs 1
{
"funding_txid": "df79c5246a3f1f8dfd6c983106b743a8220a1f4c819b76aeb41d69ccfc2baf4e"
}
{
"channel_point": "df79c5246a3f1f8dfd6c983106b743a8220a1f4c819b76aeb41d69ccfc2baf4e:0"
}
$ lncli --lnddir=lnd_alice -n regtest listchannels
{
"channels": [
{
"active": true,
"remote_pubkey": "030fb4423c15e3e049dbbdc646d0ef3ab7450a891652bbe0c39a14a8f5b44dc15f",
"channel_point": "df79c5246a3f1f8dfd6c983106b743a8220a1f4c819b76aeb41d69ccfc2baf4e:0",
"chan_id": "513471930236928",
"capacity": "10000000",
"local_balance": "9961530",
"remote_balance": "35000",
"commit_fee": "2810",
"commit_weight": "1116",
"fee_per_kw": "2500",
"unsettled_balance": "0",
"total_satoshis_sent": "0",
"total_satoshis_received": "0",
"num_updates": "0",
"pending_htlcs": [],
"csv_delay": 1201,
"private": false,
"initiator": true,
"chan_status_flags": "ChanStatusDefault",
"local_chan_reserve_sat": "100000",
"remote_chan_reserve_sat": "100000",
"static_remote_key": false,
"commitment_type": "ANCHORS",
"lifetime": "80",
"uptime": "80",
"close_address": "",
"push_amount_sat": "35000",
"thaw_height": 0,
"local_constraints": {
"csv_delay": 1201,
"chan_reserve_sat": "100000",
"dust_limit_sat": "354",
"max_pending_amt_msat": "9900000000",
"min_htlc_msat": "1",
"max_accepted_htlcs": 483
},
"remote_constraints": {
"csv_delay": 1201,
"chan_reserve_sat": "100000",
"dust_limit_sat": "354",
"max_pending_amt_msat": "9900000000",
"min_htlc_msat": "1",
"max_accepted_htlcs": 483
},
"alias_scids": [],
"zero_conf": false,
"zero_conf_confirmed_scid": "0",
"peer_alias": "unable to lookup peer alias: alias for node not found",
"peer_scid_alias": "0",
"memo": ""
}
]
}
$ lncli --lnddir=lnd_alice -n regtest channelbalance
{
"balance": "9961530",
"pending_open_balance": "0",
"local_balance": {
"sat": "9961530",
"msat": "9961530000"
},
"remote_balance": {
"sat": "35000",
"msat": "35000000"
},
"unsettled_local_balance": {
"sat": "0",
"msat": "0"
},
"unsettled_remote_balance": {
"sat": "0",
"msat": "0"
},
"pending_open_local_balance": {
"sat": "0",
"msat": "0"
},
"pending_open_remote_balance": {
"sat": "0",
"msat": "0"
}
}
$ lncli --lnddir=lnd_alice -n regtest getchaninfo --chan_point "df79c5246a3f1f8dfd6c983106b743a8220a1f4c819b76aeb41d69ccfc2baf4e:0"
{
"channel_id": "513471930236928",
"chan_point": "df79c5246a3f1f8dfd6c983106b743a8220a1f4c819b76aeb41d69ccfc2baf4e:0",
"last_update": 1733192887,
"node1_pub": "030fb4423c15e3e049dbbdc646d0ef3ab7450a891652bbe0c39a14a8f5b44dc15f",
"node2_pub": "03f23e9d775b5363a2311742209fc4d50eb47e8c226b78472609356f9d72294729",
"capacity": "10000000",
"node1_policy": {
"time_lock_delta": 80,
"min_htlc": "1000",
"fee_base_msat": "1000",
"fee_rate_milli_msat": "1",
"disabled": false,
"max_htlc_msat": "9900000000",
"last_update": 1733192887,
"custom_records": {},
"inbound_fee_base_msat": 0,
"inbound_fee_rate_milli_msat": 0
},
"node2_policy": {
"time_lock_delta": 80,
"min_htlc": "1000",
"fee_base_msat": "1000",
"fee_rate_milli_msat": "10",
"disabled": false,
"max_htlc_msat": "9900000000",
"last_update": 1733192887,
"custom_records": {},
"inbound_fee_base_msat": 0,
"inbound_fee_rate_milli_msat": 0
},
"custom_records": {}
}
$ lncli --lnddir=data/lnd_alice -n regtest --rpcserver=127.0.0.1:10010 sendpayment --pay_req="lnbcrt1pn5ulwxpp5hleus2vrjx29ercwtxuzgyrpl8ckkexmprlm9eps0nrl4jn30mpsdqqcqzzsxqyz5vqsp55zavqw9rv5xfxnw6vucluqfrspazwfz7hl4hsqhagnhvrkywyuls9p4gqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpqysgqlm77eh73g68dkxy4pjf4stjc3tg6yxf9z6ua5l0axjn4tznw2lpsjcdnu8gvug9r095wmg8v56jhmhqzvgz4ch6lmhgrues2hvqe6rspdmdxd5" --amt=5000
Payment hash: bff3c8298391945c8f0e59b8241061f9f16b64db08ffb2e4307cc7faca717ec3
Description:
Amount (in satoshis): 5000
Fee limit (in satoshis): 250
Destination: 030fb4423c15e3e049dbbdc646d0ef3ab7450a891652bbe0c39a14a8f5b44dc15f
Confirm payment (yes/no): yes
+------------+--------------+--------------+--------------+-----+----------+-----------------+----------------------+
| HTLC_STATE | ATTEMPT_TIME | RESOLVE_TIME | RECEIVER_AMT | FEE | TIMELOCK | CHAN_OUT | ROUTE |
+------------+--------------+--------------+--------------+-----+----------+-----------------+----------------------+
| SUCCEEDED | 0.016 | 0.152 | 5000 | 0 | 555 | 513471930236928 | 030fb4423c15e3e049db |
+------------+--------------+--------------+--------------+-----+----------+-----------------+----------------------+
Amount + fee: 5000 + 0 sat
Payment hash: bff3c8298391945c8f0e59b8241061f9f16b64db08ffb2e4307cc7faca717ec3
Payment status: SUCCEEDED, preimage: 47f028b0b825f07e8325735c3e84541e7f5e982635136cee32dff590a21465eb
$ lncli --lnddir=data/lnd_alice -n regtest --rpcserver=127.0.0.1:10010 channelbalance
{
"balance": "9956530",
"pending_open_balance": "0",
"local_balance": {
"sat": "9956530",
"msat": "9956530000"
},
"remote_balance": {
"sat": "40000",
"msat": "40000000"
},
"unsettled_local_balance": {
"sat": "0",
"msat": "0"
},
"unsettled_remote_balance": {
"sat": "0",
"msat": "0"
},
"pending_open_local_balance": {
"sat": "0",
"msat": "0"
},
"pending_open_remote_balance": {
"sat": "0",
"msat": "0"
}
}
$ lncli --lnddir=data/lnd_alice -n regtest --rpcserver=127.0.0.1:10010 feereport
{
"channel_fees": [
{
"chan_id": "513471930236928",
"channel_point": "df79c5246a3f1f8dfd6c983106b743a8220a1f4c819b76aeb41d69ccfc2baf4e:0",
"base_fee_msat": "1000",
"fee_per_mil": "10",
"fee_rate": 0.00001,
"inbound_base_fee_msat": 0,
"inbound_fee_per_mil": 0
}
],
"day_fee_sum": "0",
"week_fee_sum": "0",
"month_fee_sum": "0"
}
Bob is just trying to pay some of that BTC back to Alice using the same Lightning channel that Alice opened and funded:
$ lncli --lnddir=data/lnd_bob -n regtest --rpcserver=127.0.0.1:10009 sendpayment --pay_req="lnbcrt1pn5u778pp5xe7ey4lxnevntdveqaaxwtjw29j3yqqtrqqgdxqxylckjndsd56qdqqcqzzsxqyz5vqsp574v9pxu5lja7mjn9uv95uu3mep64w7w00gsedjsse94h2t0xq2zq9p4gqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqpqysgqs0z2xmy9a0un69k8xpp7x2nl8z5ryn25n8n8fet78adax327ksvyll4wdk6s2h58yg8gw8mdqre288uc3edagpg8ave4l8rnxz3kz7sqxj2dhu" --amt=2000
Payment hash: 367d9257e69e5935b599077a672e4e516512000b180086980627f1694db06d34
Description:
Amount (in satoshis): 2000
Fee limit (in satoshis): 100
Destination: 03f23e9d775b5363a2311742209fc4d50eb47e8c226b78472609356f9d72294729
Confirm payment (yes/no): yes
+------------+--------------+--------------+--------------+-----+----------+----------+-------+
| HTLC_STATE | ATTEMPT_TIME | RESOLVE_TIME | RECEIVER_AMT | FEE | TIMELOCK | CHAN_OUT | ROUTE |
+------------+--------------+--------------+--------------+-----+----------+----------+-------+
+------------+--------------+--------------+--------------+-----+----------+----------+-------+
Amount + fee: 0 + 0 sat
Payment hash: 367d9257e69e5935b599077a672e4e516512000b180086980627f1694db06d34
Payment status: FAILED, reason: FAILURE_REASON_INSUFFICIENT_BALANCE
[lncli] FAILED
$ lncli --lnddir=lnd_bob -n regtest --rpcserver=127.0.0.1:10010 channelbalance
{
"balance": "40000",
"pending_open_balance": "0",
"local_balance": {
"sat": "40000",
"msat": "40000000"
},
"remote_balance": {
"sat": "9956530",
"msat": "9956530000"
},
"unsettled_local_balance": {
"sat": "0",
"msat": "0"
},
"unsettled_remote_balance": {
"sat": "0",
"msat": "0"
},
"pending_open_local_balance": {
"sat": "0",
"msat": "0"
},
"pending_open_remote_balance": {
"sat": "0",
"msat": "0"
}
}
$ lncli --lnddir=lnd_bob -n regtest --rpcserver=127.0.0.1:10010 listpeers
{
"peers": [
{
"pub_key": "03f23e9d775b5363a2311742209fc4d50eb47e8c226b78472609356f9d72294729",
"address": "127.0.0.1:60194",
"bytes_sent": "92017",
"bytes_recv": "82927",
"sat_sent": "0",
"sat_recv": "5000",
"inbound": true,
"ping_time": "974",
"sync_type": "ACTIVE_SYNC",
"features": {
"0": {
"name": "data-loss-protect",
"is_required": true,
"is_known": true
},
"5": {
"name": "upfront-shutdown-script",
"is_required": false,
"is_known": true
},
"7": {
"name": "gossip-queries",
"is_required": false,
"is_known": true
},
"8": {
"name": "tlv-onion",
"is_required": true,
"is_known": true
},
"12": {
"name": "static-remote-key",
"is_required": true,
"is_known": true
},
"14": {
"name": "payment-addr",
"is_required": true,
"is_known": true
},
"17": {
"name": "multi-path-payments",
"is_required": false,
"is_known": true
},
"23": {
"name": "anchors-zero-fee-htlc-tx",
"is_required": false,
"is_known": true
},
"25": {
"name": "route-blinding",
"is_required": false,
"is_known": true
},
"27": {
"name": "shutdown-any-segwit",
"is_required": false,
"is_known": true
},
"31": {
"name": "amp",
"is_required": false,
"is_known": true
},
"45": {
"name": "explicit-commitment-type",
"is_required": false,
"is_known": true
},
"2023": {
"name": "script-enforced-lease",
"is_required": false,
"is_known": true
}
},
"errors": [],
"flap_count": 7,
"last_flap_ns": "1733192845755233591",
"last_ping_payload": "00000020d22b2aa43b49ef1fd79d668a09a6562f0e40ffe75eeda662d978cb3d5454290af3b209f13de7fec7f63fc2f4c361db7bb10606af6622289890316905c5da663db6884e67ffff7f2001000000"
}
]
}
$ lncli --lnddir=lnd_bob -n regtest --rpcserver=127.0.0.1:10010 queryroutes --dest 03f23e9d775b5363a2311742209fc4d50eb47e8c226b78472609356f9d72294729 --amt 2000
[lncli] rpc error: code = Unknown desc = insufficient local balance
The only way for Bob to send funds back to Alice seems to be for Bob to open his own separate channel and send the payment through that (i.e. outbound liquidity). I do not understand why inbound liquidity on Alice's channel isn't working.
Comments, suggestions, further questions would be appreciated!