LNDでCPFPして実効feerateを上げる

uenohiro4
Nayuta エンジニアブログ
7 min readMar 21, 2023

Lightning Network を主に扱っていますが、Bitcoin の上に存在するものなのでブロックチェーンの状況にしばしば影響を受けます。

この記事を書いているのは2023年3月半ばですが、Bitcoin の feerate が高めです。

ある日のmempool.spaceより

チャネルをオープンする際には funding transaction というトランザクションをブロックチェーンに展開するので、feerate の影響を受けます。

zero-conf チャネルでない通常の場合はトランザクションが承認されて数ブロック経たないと始まりませんし、zero-conf チャネルであっても安心できません。どちらも展開した時点から 2,016ブロック程度の時間経っても承認されないようであればチャネルとして取り消される可能性があります(BOLT#02 を “2016”で検索すると見つかります)。

トランザクションを承認してもらいやすくするには手数料を上げるのが一番ですが、ブロックチェーンに展開したトランザクションに対してはRBFかCPFPかのどちらかを行うことで手数料が上がったような効果を出すことができます。Lightning Network では funding transaction のお釣りOUTPUT や クローズする anchor OUTPUT を使って CPFPすることになるでしょう。

LNDでのCPFP

LND の場合は lncli wallet bumpfee というコマンドでCPFPします。クローズするトランザクションの場合には別のコマンドがありますが、今回はやりません。

私の場合は funding transaction に対して CPFP することが多いので、それを例に取ります。

まず、対象とする funding transaction の channel point を探します。channel point というのは funding transaction の TXID と、その OUTPUT のうちでチャネルとして使われるインデックスをセットにしたものです。 lncli openchannel を使う場合はほぼ OUTPUT が2つあって、片方が channel point、もう片方がお釣りです。ただお釣りが小さくなりすぎるとお釣りの OUTPUT をなくして手数料にしてしまう場合もあるようでした(体験談)。ちなみにこの挙動は funding transaction については記載されていませんが、クローズについては Trimmed Outputs という章があるので同じような対応になっているのだと思います。

CPFP はウォレットから送金できる UTXO を使って feerate 高めのトランザクションを展開することです。feerate 高めのトランザクションが子供のようなもので、元となるトランザクション(こちらが親)と一緒にすると手数料として悪くないと判断してもらって、子供トランザクションを承認する=親トランザクションも承認する、という流れです。

CPFPのイメージ

話を戻しますと、 LND ではこういったコマンドで CPFP します。channel point ではなくお釣りの方の OUTPUT を指定します(channel point の方を指定してもエラーになるだけでしたが)。

lncli wallet bumpfee --sat_per_vbyte=<XXX> <channel_pointの反対側>

--sat_per_vbyte で指定するのが子供トランザクションの feerate です。親トランザクションのサイズと現在の feerate を考慮しながら値を決めることになるでしょう。

LND では INPUT が1つの funding transaction ならサイズが 154 vbyte 程度、子トランザクションが 111 vbyte 程度でした。この場合だと、例えば親トランザクションが 1 sats/vbyte、子トランザクションを 8 sats/vbyte にすると、実効 feerate は 4 sats/vbyte を下回るくらいの値になります。

CPFP するためだけにトランザクションを展開するのはけっこう無駄な行為です。できるなら最初からほどよい feerate のトランザクションを展開するべきでしょう。まあ、それが難しいのですが。

LND でもそれを考慮して、 bumpfee コマンドを実行したからといってすぐ CPFP のトランザクションが展開されるとは限りません。ある程度まとめて展開しようとします( lncli wallet pendingsweeps などで待ち状態になっているトランザクションがわかります)。
そのため、特定の親トランザクションのことを考えて feerate を決めて bumpfee コマンドを実行したとしても、ちょうどまとめられてしまって想定していたよりも実効 feerate が下がってしまった、ということがありえます(体験談)。
これでトランザクションが承認されれば問題ないのですが、これをさらに CPFP したいとなると feerate の計算が難しくなります。

LNDがどれをまとめるかわからない

そういう事態に陥りたくない場合は、おそらくですが bumpfee のオプション --force を指定するとまとめたりせずに CPFP のトランザクションを展開してくれるものと思われます(「思われます」と曖昧なのは、LND がどう判定するかよくわからないためです)。

似たようなパターンで、すぐに CPFP してほしいけれども LND が pending にして待ち状態になる、ということもありました。お釣りの額が小さいなどで、なるべく無駄にならないように他のトランザクションを待っているのだと思います。
そういう場合も --force を付けると CPFP するトランザクションを展開してくれるようでした。

zero-confチャネルの場合

通常のチャネルであれば lncli pendingchannels でオープン待ち中の channel point を探すことができますが、zero-conf チャネルの場合は先にチャネルになるため pending には出てきません。

私はあきらめて、 lncli listchannels の出力から channel point の一覧を作っていちいち確認しています。 zero_conf_confirmed_scid が “0” ならまだ承認されていないのだと思いますが、念のためというところです。

おわりに

LND で CPFP するコマンドについて説明しました。

株式会社Nayuta

--

--