How to balance your c-lightning channels

Aug 8, 2019

This is a guide for "rebalancing" in the sense of moving satoshis from one channel to another, not in the sense (sometimes used) of pushing sats out of a channel and receiving them on-chain.

Where to install plugins

Basically, if you managed to get c-lightning running you should be able to easily install plugins by just copying them to your /plugins directory. That directory is in the midst of c-lightning's source code:

/path/to/lightning/plugins/

Or, if you installed your daemon with sudo make install:

/usr/local/libexec/c-lightning/plugins/

Alternatively, in your data dir:

~/.lightning/plugins/

Installing the plugins rebalance and jqmethods

Ok, go to one of these directories and run

$ ln -s ../contrib/pylightning/ lightning

To have the c-lightning Python module on hand, then install the rebalance plugin with

$ wget https://github.com/lightningd/plugins/raw/master/rebalance/rebalance.py
$ chmod +x rebalance.py

Now install the jqmethods plugin with

$ wget https://github.com/fiatjaf/lightningd-gjson-rpc/releases/download/p3/jqmethods_linux_amd64 -O jqmethods
$ chmod +x jqmethods

If don't have it already you'll also have to install jq, which should probably already be in your default package manager, so sudo apt-get install jq or brew install jq or similar command.

After all that you'll have to restart lightningd so it will pick up the new plugins and make the new methods jq and rebalance available.

How to use

$ lightning-cli jq channel_balance_status

Should give you an array of all channels that have balance on both sides (i.e., channels not unused). The keys "us" and "them" (in satoshi, not msatoshi) should make it clear how much is on your side and how much on their side.

[
  {
     "short_channel_id" : "558165x797x0",
     "us" : 779.195,
     "them" : 299220.805,
     "status" : [
        "CHANNELD_NORMAL:Reconnected, and reestablished.",
        "CHANNELD_NORMAL:Funding transaction locked. Waiting for their announcement signatures."
     ],
     "balance" : "low here"
  },
  {
     "short_channel_id" : "585539x1882x1",
     "us" : 450000,
     "them" : 50000,
     "status" : [
        "CHANNELD_NORMAL:Reconnected, and reestablished.",
        "CHANNELD_NORMAL:Funding transaction locked. Channel announced."
     ],
     "balance" : "low there"
  }
]

Now you have to decide how much and from which channel you will send from and to. The channels are ordered from the one with a lowest local balance to the one with higher local balance, so generally you want to send from the last to the first:

# not necessary, but this will show just the first and last in the list, which may help
$ lightning-cli jq channel_balance_status | jq '.[0], .[1]'

In our example, our outgoing channel has much more balance than needed to fill the incoming channel, so we will send just 200000 sat to keep numbers simple.

$ lightning-cli rebalance 585539x1882x1 558165x797x0 200000000 # the rebalance plugin expects msat
"200074681 msat sent over 6 hops to rebalance 200000000 msat"

That means it's done! And you have paid 74.681 satoshis for rebalancing your channels. If you like to know what happened behind the scenes your lightningd logs should show something like the following:

INFO plugin-rebalance.py Outgoing node: 0390b5d4492dc2f5318e5233ab2cebf6d48914881a33ef6a9c6bcdbb433ad986d0, channel: 585539x1882x1
INFO plugin-rebalance.py Incoming node: 02529db69fd2ebd3126fb66fafa234fc3544477a23d509fe93ed229bb0e92e4fb8, channel: 558165x797x0
INFO plugin-rebalance.py Invoice payment\_hash: 4200e4854f1d3bc5f427907d45c5b751503d59e40344b1c0d92da7f4cb3fbfb2
INFO plugin-rebalance.py Sending 200074681msat over 6 hops to rebalance 200000000msat
INFO plugin-rebalance.py     - 0390b5d4492dc2f5318e5233ab2cebf6d48914881a33ef6a9c6bcdbb433ad986d0   585539x1882x1  200074681msat
INFO plugin-rebalance.py     - 03d37fca0656558de4fd86bbe490a38d84a46228e7ec1361801f54f9437a18d618   574084x2085x1  200074681msat
INFO plugin-rebalance.py     - 020f0d93c700cf5cf556e61828fab473a5c30ee6eb927ae36a130cc1c57326d21a   587931x1716x0  200074681msat
INFO plugin-rebalance.py     - 02a04446caa81636d60d63b066f2814cbd3a6b5c258e3172cbdded7a16e2cfff4c   579091x1637x0  200073641msat
INFO plugin-rebalance.py     - 02529db69fd2ebd3126fb66fafa234fc3544477a23d509fe93ed229bb0e92e4fb8    576490x957x0  200073601msat
INFO plugin-rebalance.py     - 02c16cca44562b590dd279c942200bdccfd4f990c3a69fad620c10ef2f8228eaff    558165x797x0  200000000msat
INFO lightningd(6908): Sending 200074681msat over 6 hops to deliver 20000000msat
INFO lightningd(6908): Resolved invoice 'Rebalance-78aeb4e1-47de-4467-8b1d-9dd75ecea277' with amount 200000000msat

So basically it was a payment passing through multiple hops and reaching your own node again.

Now you must repeat the process for the other channels that are still unbalanced.

It could be good if someone automated this process, but on the other hand it would take all the fun out of it -- also it's not that trivial because each person likes their balancing done in a peculiar way, and it's sometimes good to have some control over what payments you are sending.