c-lightningの主キー制約とリストア

ライトニングネットワークの実装ソフトウェアの1つであるc-lightningのノード運用をこれまでしていたのですが、バージョンアップ(v0.8)を期にエラーがでるようになり、たまにプロセスが落ちるようになりました。

エラー内容は以下のようなSQLの主キー制約エラーなんですが、たぶんバージョンアップをする際に上手くDBが更新されなかったのかな?たちが悪いのがどのブロックのutxoを追加しようとしてるときにエラーとなっているのがわからないことです。

+245.990149661 lightningdBROKEN: Error executing statement: wallet/wallet.c:2923: INSERT INTO utxoset ( txid, outnum, blockheight, spendheight, txindex, scriptpubkey, satoshis) VALUES(?, ?, ?, ?, ?, ?, ?);: UNIQUE constraint failed: utxoset.txid, utxoset.outnum
+246.144652678 lightningdBROKEN: FATAL SIGNAL 6 (version v0.8.0)

Githubでそれっぽいイシューがないか調べてみたら、同じような主キー違反に関するイシューがありました。ただこのイシューではある特定のブロック高でエラーが発生していることなので、自分の現象とは少し違っていそうでした。

そこで、--rescan <blockheight>コマンドでc-lightningが持っているブロック情報をリスキャンしてみました。実際は以下のコマンドを実施。ブロック高を500,000にしているのはLNがローンチしたのがそれ以降だからです。※リスキャン前にすべてのチャネルを閉じて、どのピアとも接続していない状態にしてあります。

lightningd --rescan 500000

これでブロックを最初からリスキャンしだしたのですが、途中でプロセスが停止。お???と思いログを確認したら、以下のように特定ブロック高でエラーになっているのが分かりました。どうやらブロック高481824のあるutxoを保存しようとしてエラーとなっているみたいです。

+6.783965955 lightningdDEBUG: Adding block 481821: 0000000000000000007651ca005cf3c59f4e718cfde2a586268cc7dd13a71ac7
+6.992840665 lightningdDEBUG: Adding block 481822: 0000000000000000003bec88b7ba0bebd8eb3b1c1c599e44a2b270ad3e8203ca
+7.182897289 lightningdDEBUG: Adding block 481823: 000000000000000000cbeff0b533f8e1189cf09dfbebf57a8ebe349362811b80
+7.391582983 lightningdDEBUG: Adding block 481824: 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893
+7.392275350 lightningdBROKEN: Error executing statement: wallet/wallet.c:2885: INSERT INTO utxoset ( txid, outnum, blockheight, spendheight, txindex, scriptpubkey, satoshis) VALUES(?, ?, ?, ?, ?, ?, ?);: UNIQUE constraint failed: utxoset.txid, utxoset.outnum
+7.552624607 lightningdBROKEN: FATAL SIGNAL 6 (version v0.8.0)

これは先ほどみたイシューと同じ現象なので、それをを参考にc-lightningのchaintopology.cファイルを以下のように編集し、ログにどのトランザクションでエラーが発生しているか吐き出すようにしました。

static void topo_add_utxos(struct chain_topology *topo, struct block *b)
{
        for (size_t i = 0; i < tal_count(b->full_txs); i++) {
                const struct bitcoin_tx *tx = b->full_txs[i];
                for (size_t j = 0; j < tx->wtx->num_outputs; j++) {
                        if (tx->wtx->outputs[j].features & WALLY_TX_IS_COINBASE)
                                continue;

                        const u8 *script = bitcoin_tx_output_get_script(tmpctx, tx, j);
                        struct amount_asset amt = bitcoin_tx_output_get_amount(tx, j);

                        if (amount_asset_is_main(&amt) && is_p2wsh(script, NULL)) {
                            //以下の5行を追加した
                            log_debug(topo->log, "j: %u", j);
                            log_debug(topo->log, "height: %i", b->height);
                            log_debug(topo->log, "i: %u", i);
                            log_debug(topo->log, "script: %s", script);
                            //log_debug(topo->log, "amount: %s", amount_asset_to_sat(&amt));

                                wallet_utxoset_add(topo->ld->wallet, tx, j,
                                                   b->height, i, script,
                                                   amount_asset_to_sat(&amt));
                        }
                }
        }
}

実際に吐き出されたログは以下となります。481824:495:0のトランザクションを追加しようとしてエラーになっていることが分かりました。

+5.103369147 lightningdDEBUG: Adding block 481821: 0000000000000000007651ca005cf3c59f4e718cfde2a586268cc7dd13a71ac7
+5.284580110 lightningdDEBUG: Adding block 481822: 0000000000000000003bec88b7ba0bebd8eb3b1c1c599e44a2b270ad3e8203ca
+5.471972098 lightningdDEBUG: Adding block 481823: 000000000000000000cbeff0b533f8e1189cf09dfbebf57a8ebe349362811b80
+5.708419111 lightningdDEBUG: Adding block 481824: 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893
+5.708918349 lightningdDEBUG: j: 0
+5.708919879 lightningdDEBUG: height: 481824
+5.708920737 lightningdDEBUG: i: 495
+5.708921192 lightningdDEBUG: script: 
+5.709035755 lightningdBROKEN: Error executing statement: wallet/wallet.c:2885: INSERT INTO utxoset ( txid, outnum, blockheight, spendheight, txindex, scriptpubkey, satoshis) VALUES(?, ?, ?, ?, ?, ?, ?);: UNIQUE constraint failed: utxoset.txid, utxoset.outnum
+5.912366142 lightningdBROKEN: FATAL SIGNAL 6 (version v0.8.0-modded)

上記の内容をもとにlightningd.sqlite3のutxosetテーブルを検索すると、すでに対象のトランザクションが保存されていました。

>SELECT hex(txid), txindex, satoshis, outnum, blockheight, spendheight FROM utxoset where blockheight = 481824
>D67903B0BE8C6E046EFD98CDA56B11E706AAD75B502C60065CE7A0A04A8A1E46	495	500000	0	481824

これが原因で主キー違反となっていたのですが、そもそも既に保存されているんだから挿入しなければいいのでは?と思いつつも、コードを読み解く力もなく、思い切って対象のトランザクションを削除しました。

Delete from utxoset where blockheight = 481824;

その後、再度デーモンを起動したのですが、またプロセスが停止。ログを見ると、先ほどのブロック高以降でも同じエラーが発生。対象のトランザクション(ブロック)を削除しましたが、またあるブロック高でエラーに。こうなればもうブロック高481824以降のデータを全消しだ!実際はその時にエラーとなっていたブロック高以降を以下のようにして消しました。

Delete from utxoset where blockheight >= 483709;

デーモンを起動しなおすこと2日ほど経過し同期が完了しました。その後今までのような主キー違反によるプロセス終了がなくなったのでした。めでたしめでたし。

おまけ

この続き : 744字 / 画像 0枚
200

会員登録 / ログインして続きを読む

関連記事

記事を書いた人

ちょビットコイナー nostr id: npub1l83ycz54gng3nd8suvww43fardjsca37x7z5rcwlmeqzudg027fqe9hwaa

SNSにシェア

このクリエイターの人気記事

LNノードの運用益はどれぐらい?パート1

1821

【Muun】ちょっと変わったライトニング搭載ノンカストディアルウォレット

1746

LNノードの運用益はどれぐらい?パート3

1092