A Guide to Channel Funding and Splicing in the Lightning Network

When opening a channel, both nodes can contribute any amount to fund its liquidity. However, once this channel is confirmed, increasing or reducing the funds locked in is impossible. Thus, any required changes require closing the channel and opening a new one with the desired funds. Well, this was the case until channel splicing was introduced.

Channel splicing involves taking funds out of a channel's liquidity or putting in more funds on the fly, retrospectively resizing the channel's capacity. This is done without having to close the channel, thus improving the flexibility and efficiency of the lightning network.

In this article, you will learn how to add funds (splice in) and remove funds(splice out) from a payment channel.

Channel Splicing on Core Lightning

Before proceeding, please make sure you have the following setup:

You are going to use Bitcoin on the regtest network. Run your Bitcoin core node before proceeding.

CLN provides a quick test script(contrib/startup_regtest.sh) to spin up multiple LN nodes for you. In the CLN root folder, run the following command:

source contrib/startup_regtest.sh

Then, use the command start_ln 3 to run 3 LN nodes simultaneously. This command also loads the Bitcoin wallet, default which holds your Bitcoin balance.

The startup script also provides a simple command to connect your desired nodes. Run the command connect 1 2 to link the first and second nodes.

To check information on any of the three nodes, you can run the commands: l1-cli getinfo,l2-cli getinfoandl3-cli getinfo.

Opening and Funding a Channel

Opening a channel in LN involves committing sats in the blockchain. This implies you need funds in your wallet. To check the balance of the default wallet that was loaded, run the command below:
bitcoin-cli -regtest -rpcwallet=default getbalance

To add more funds to the wallet, you can create a new address for the wallet:
bitcoin-cli -regtest -rpcwallet=default getnewaddress
and then mine some blocks. The reward for mining the new blocks will be awarded to the Bitcoin address:
bitcoin-cli -regtest generatetoaddress 100 bitcoin-address-generated-above

Next, you need to fund the internal wallet of the LN node. To do this, you will create a bech32 address to be used by the node's wallet and then send 10 bitcoins from the default bitcoin wallet:
l1-cli newaddr
bitcoin-cli -regtest -rpcwallet=default sendtoaddress node-wallet-address 10

The above bitcoins sent to the LN address will not reflect yet. You need to mine a few blocks to confirm the transaction:
bitcoin-cli -regtest generatetoaddress 10 bitcoin-address-generated-above

After mining blocks, you can check the balance using the command: l1-cli listfunds .

To open a channel between nodes 1 and 2, you are going to use the fundchannel RPC command. The command opens a payment channel with peers by committing a funding transaction to the blockchain. You will need the node 2 ID, which you can get by executing the command: l2-cli getinfo . Afterwards, you can open and fund a channel with 1000000sats as follows:
l1-cli fundchannel node-l2-id 1000000

Checking the channel status l1-cli listfunds , it will be unconfirmed. Mine some more blocks to confirm the transaction and change the channel status to normal.

Splicing the Channel

A splicing operation involves a few steps which are performed in order. They include:

1. Create a Partially Signed Bitcoin Transaction(PSBT)

You will use the fundpsbt command to initialize a PSBT transaction.

l1-cli fundpsbt satoshi=100000 feerate=urgent startweight=166 excess_as_change=true

The above command creates a PSBT transaction:
- satoshi: Amount of satoshis 100,000sats
- feerate: Setting the fee rate as urgent to hasten the transaction.
- startweight: A rough estimate of the total weight of the transaction without any inputs.
- excess_as_change: Returns any remaining sats when the transaction is confirmed to the source address.

Once executed, the command will return some data, including the generated psbt, which will be used in the next section.

2. Initiate a Channel Splice

CLN provides an RPC command, splice_init, to initialize a splicing action on a given channel.

l1-cli splice_init channel_id=channel_id relative_amount=150000 initialpsbt=previous_psbt force_feerate=true

- channel_id: This is the reference id for the channel.
- relative_amount: The amount you intend to splice in or out of the channel. A positive amount will add funds, while a negative amount will subtract funds from the channel.
- initialpsbt: This is the initial psbt transaction created earlier.
- force_feerate: By default, splices will fail if the fee provided looks too high, which protects against accidentally setting your fee higher than intended

3. Update Channel Splice

After initializing a splice, you must update it with the other node using the splice_update command.
This command should return a response containing the value commitments_secured:true. If it's not present, you need to rerun the command with the updated psbt until the value is true.

l1-cli splice_update channel_id=channel_id psbt=previous_psbt

- channel_id: This is the reference id for the channel.
- psbt: The most recent psbt generated from a previous command.

4. Sign the PSBT

When the commitments_secured value is true, you can sign the psbt transaction: sign_psbt. This command returns the signed post, which you will use to finalize the transaction.

l1-cli sign_psbt psbt=previous_psbt

- psbt: The most recent psbt generated from the previous command.

5. Sign and Finalize Splice

To finalize and finish the splice, you will sign the splice transaction with the command: splice_signed.
The transaction is published on successful signing, and an object with the transaction ID and hex is returned.

l1-cli splice_signed channel_id=channel_id psbt=signed_psbt

- channel_id: This is the reference id for the channel.
- psbt: Provide the signed psbt.

At this point, check the channel's status: l1-cli listfunds should be CHANNELD_AWAITING_SPLICE. To finalize it, you must mine some blocks as you did when creating the channel.

Resources