Skip to content

Fix chanmon_consistency fuzz test for splice RBF#4536

Draft
jkczyz wants to merge 4 commits intolightningdevkit:mainfrom
jkczyz:2026-04-splice-rbf-fuzz-fixes
Draft

Fix chanmon_consistency fuzz test for splice RBF#4536
jkczyz wants to merge 4 commits intolightningdevkit:mainfrom
jkczyz:2026-04-splice-rbf-fuzz-fixes

Conversation

@jkczyz
Copy link
Copy Markdown
Contributor

@jkczyz jkczyz commented Apr 1, 2026

The chanmon_consistency fuzz target panicked on various inputs involving
splice RBF because it immediately confirmed splice transactions in the
SplicePending handler. When RBF replacements were also confirmed for the
same channel, both transactions ended up in the chain despite spending the
same funding UTXO -- an impossible scenario that caused force-closes.

  • Model RBF replacement properly by adding a pending transaction pool to
    ChainState. Splice transactions are held in the pool until chain-sync
    time, when one is selected deterministically (by txid sort order) among
    conflicting candidates. Double-spends with already-confirmed transactions
    are rejected.
  • Handle DiscardFunding with FundingInfo::Tx variant, which is produced
    when a splice transaction is discarded during RBF replacement.
  • Accept splice and RBF validation warnings in the HandleError assertion,
    which can occur when the fuzzer delivers messages in unusual orders.
  • Handle BroadcastChannelUpdate in push_excess_b_events, which can be
    left over when process_msg_events processes a limited number of messages.

See #4504

jkczyz and others added 4 commits April 1, 2026 15:46
…ency

The process_events! macro only handled DiscardFunding events with
FundingInfo::Contribution, but splice RBF replacements can produce
DiscardFunding with FundingInfo::Tx when the original splice transaction
is discarded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The SplicePending event handler was immediately confirming splice
transactions, which caused force-closes when RBF splice replacements
were also confirmed for the same channel. Since both transactions spend
the same funding UTXO, only one can exist on a real chain.

Model this properly by adding a mempool-like pending pool to ChainState.
Splice transactions are added to the pending pool instead of being
confirmed immediately. Conflicting RBF candidates coexist in the pool
until chain-sync time, when one is selected deterministically (by txid
sort order) and the rest are rejected as double-spends. If a conflicting
transaction was already confirmed, new candidates are dropped.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The HandleError assertion only accepted "timeout awaiting response"
warnings. However, the fuzzer can deliver messages in unusual orders that
trigger legitimate splice and RBF validation failures (e.g., attempting
RBF after splice_locked, splicing before quiescence, or splicing a
channel that is not live). These produce DisconnectPeerWithWarning with
different messages that the assertion needs to accept.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When process_msg_events processes a single message for node B (via
OneMessage or OnePendingMessage mode), remaining events are passed to
push_excess_b_events for routing. Timer ticks can generate
BroadcastChannelUpdate events from marking channels disabled on
disconnect, which may be left over after the single processed message.
Since it is a broadcast not directed at a specific peer, it can be
safely skipped.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ldk-reviews-bot
Copy link
Copy Markdown

👋 Hi! I see this is a draft PR.
I'll wait to assign reviewers until you mark it as ready for review.
Just convert it out of draft status when you're ready for review!

@jkczyz
Copy link
Copy Markdown
Contributor Author

jkczyz commented Apr 1, 2026

This should fix the test for the following inputs:

09ff80a4a6ff09ff80a4a6ffab02b5a6a402b5a6
015da0a2a0acadff80ffffb1b0ffa2a0ffabffa2ffa2acffa0ffbba2a0
61a000ff0802b3a9aaa2aaaa4c80a4aaaaa0ffaccd004838ff
581f84a11aa23a3b5c7080100dff72c0180d7080ff01ffa0ffac
56ffa0a0ff80a010ffb0ffa2a0ffadffac
adffb30fa30ec14041401084a6abacadffffffb0ffa2a0ffabacadffff
a6ffa4ffff3d80bba4a6ffacffffff
61080002a2aaa0ff2280163115a0ffa9adaccdcdffabac011600000d2b
27a360a6a4ff84ffffffffffffffb0ffa2a0ffabacffffffffd2
ffffa2a080ffa4ffffffa6ff80ffa4ffffffa6ffffffabb0
a0a4803b70ffa4ffffffffffffffffffffffff1171ab00000000000000
70a480ff27a480ffffb9b270ac80ff27a480ffffb7b21f1fb900000000
5b0aa2a480ffa4ffffffa0ffabffffffffffffffff
ff41a0ffaa80800000ff41a0ffaa8080000000000100ac843b3bff84ac
415a008070800000ff41a0ff004080f284aaa0ffabac00b080
33004069ff6969b0606969b060a4ff8080a4ff8080b1ffacffb3ff33
0270a480ff27a480ffff1280ff27a480ff1280ff27ac80ff
2e80a0ffb280a0ffb231acacacacacacacacacacacacff
5b262680ffa4a42780ffa480ffac0c000000ffd80000d400e0d9b3
caff24a480ff11a6b6b6b623b6ffa480ff11a6b6b6b6b6b669a4b601ac
610800b784a4a6ffbeb7ffb4ffb7a1ffb7b3cdcdffabac011600000dad
3fff3ba180a1ffa480ffacacaccaff11b21d1d1d
80fe80ffa4ffff41801119a480ffa4acffa2a0ffff4180111980fffa45
3f80a4ffbb80a47070ffb0ffffffffa0abaca0ffa9a8000000b17a
61a0b9b9000000000000000031ffffa48080ffb1a6a4ffa6ffa0ffaccd
0fa30f84321b41b1adac49ffffb0ffa2a0ffffac481b01b52323192319
3a24b7a4b780ffa05bff24a4ff15ffabffffffffff06b1b1b1ff2d
3a24b7a4b780ffb0ffa2a0ffabacadffffffffff15ffffffff06ff2d
ad4aa480ffffb960a05858005affaba0cab284
aba01500000000001500000000000080ffb1a0ffab0080b1ffaba0ff
d4a480ff68a070ffa8a8b6acffb6b6b6b6b6b6b6b6b6b6b6b6b6000000
01ffa4a42780ffa4800040ffac010000003145ff45
3aa4ffb7805bb7ff24a480ff5bffb7ffb7acffb7805bb7ffffff2d
61a015adffb30fa30ec18484a18484a10823a440414043aaaaa0ffaccd
ffa480ffff0a0a0aff41a0ffaaa0aba480ffff
ff4140a019808080111980ffaaa000ffabaab000a0ab00acff
0000000080ff8008a4ffff41801119a472b6b6b6ff41b41bacadff0102
22a01200161bff3115848084a4a1153012007116b1a0b0ffabac001831
23b0a4ff8080b1ffa4ffb3ff8080b1ffacffb3ffb3ffb3ffb3
11a6ffb6b6b6b6a4ffb6b6b580bebebc41b1ff55a0a2ffabad41b1ff11801d
61080002a2aaa0ffaaaaadaa80aaa0ffa9adcdcdffabac011200000dad
a2a23b1bffff633b84843ba2a23b1bffff633b84843bffadffffadff
a4a42780ffffffffffffffffffffffffff1f26ffffaaa0ffabac00ff
61a000ffffffffffff80ffffff40000802b3a9aaa2aaaaaaaaa0ffaccd
ffa0ffa3011780c8701070ffb0ffa2a01bffab
23b0ffa4ff8080b1ffa4ffb3ff80b3ffb3a4ffb3ffb3ffb3a0b0ffabb3
61a000ff081f1f301a2480aaaaaaa0ff00adcdcd0018acad
80a4803b70ffa4ffffff060660ffffffacff8080b1ffffffffff000060
11a6ffff4110b9a4ffff3d80bba4a600000000000000ffa4ffac2cb6b6
5b262680ffa4a42780ffa4ff80ffa480ffa4a427ffabffffffff1f264c
70801da1ff0162a0ffabac1a001ab0ffa200ab10191140801a
80a4803b70ffa4ffffffabffffffffff0affffffffff80
23b0a4ff80b014000000a2a0adffaca25dab0580a9ff21ffb3ffb3ffb3
b4ffb4b780a410428480ffffb4b780f5ffffffa410428480ffab307033
b784a461a000aa12aaaaaaa6ffbeb7ffb4ffb7a1ffaaaccd
ffb0ffa2a0ffffffff34110a22ffff80a015ffab69a5ffffa2b0
187080a1a270ffaaa0ffac70c0307a00843832ffffffff8419ff8080
09ff80a4abff09ff80a4ff80a4abff09ff80a4a603a402b5a6010000
23b0a4ffff80a4ffb1ffb38080800002aca60080b1ffa4ffb3ffb3ffb3
23b0a4ff0440000080a4b0b3ffb0a40aa2a0ffab512254ffffffffb3
103dffa000408010ffffffa04b1031ffffffffffffff35acadffffb1b0
265b80ff26a4a42780ffa480ffa480ffa4ff80ffa4ffffffff1fac264c
28ffa480ffa4a4ffffff2780ff000200abfdff2839dffbfbfbfbfbfb
60b580bebe1012a601841b1831bc41b1ff55a0a2ffabad41b1ff11801d
ffa0c9801119800284ffa3a6ffb600000017a40c0000ffb3ff45ffacad
b96970a480ff27a480ffffb960ffb0ffa2a2ffadffb9acb9b9b3b9
610800a0700080ffa9aaaaaa4100a0ffa9accdcdffab17ad
a7a6ff014084ffa6ffffffffffad
70804870a4a6a6808440192211a68084ffa2a0ffabac01bc00000000b9
6108aaaaaaaaa0ffa9ff41ff80a4a4ff41bb3dbb80ffac
3a24ffa4ff8012245ba432ff11a63dff41fffffcfcfc1084ffabababab
8480a4a1840800001aa4a10ab2a015ffabaca5101d000003ffffa21a09
23b0a4ff8080b1ffa4ffb3a38080b1ffa4ffb3ffb3ffabb323b0a4ffb3
343434a2801230220100000032161616ffa1a0ffff06a4a6ffacff8412
23b0a4ff8080b1ffa4140000ffac48b023b0a4
23b0a4ff8080b0a4ff8080b1ffacffb3ffff
23b0a4ffff80a4ffb1ffb38080801eac0000a480b1ff74000000000000
ffb0ffa2a0ff1100a6bcabb1b084adacffffa2a0ffabffac2cada2b0
5b262680ffa4a42780ffa40e000000a0ffabacb1ffffb1b0a2b01f264c
848426a4a10100003a0000ffffacad19232323a108101d0080ff1a1a74
ffa4ff8041a4ff41bb3dbb80ff41ab3d80ff41bbbb80a480ff5780
70a42780aaffa480ffb0ffa20effabadadffffb1b0a2a4
5b262680ffa4a42780ffa480ffacffffff04e0264c
61ffffffffffffa000ff0802b3b7f58040a9baa2aacbaaaaa0ffac29
ffffa2a0ffffffffff484845803b0aa0a0ffabadadff0670005848b140
3a0015a4b780ffa05bb7ff240ba4ffff0aabfffbff2d
6108aaaaaaada0ff80402661ffffffffaaa0ffa9ac4d4d4d4d4d4d4dad
23b0a4ff80b080a4fe8080b1ffa4ffb3ff8080b0a4ff8080b1ffabffff
5b262680ffa4a42780ffa480ffabffffffffffffffff1f264c
610008a200a0aa801172a17272ff48a0ffb34831acabac011600000dad
ffa000408010ffa04b10ffffffffffab058012a6a4ff
a2a2a2a30084843aa1a45080ff84ffff00acffffffffffffffffffffff
581f84a11a5c0d70ffaa1f84a11a5c0d70ffaaa0ab00a273b8ffb0
daa480a6ffffffffffffffffffb30080a323f4ffa0ffb1ffffffffabff
ffb0a2a0ff8181ffa2ffffffff5c80b1b2a015ffabaca5ffffaab0
248585858572b100278085853a858585858585858585a61ad3

@jkczyz jkczyz mentioned this pull request Apr 1, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.12%. Comparing base (1ff1bb4) to head (64205b8).
⚠️ Report is 120 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4536   +/-   ##
=======================================
  Coverage   87.12%   87.12%           
=======================================
  Files         163      163           
  Lines      108740   108765   +25     
  Branches   108740   108765   +25     
=======================================
+ Hits        94735    94765   +30     
+ Misses      11520    11514    -6     
- Partials     2485     2486    +1     
Flag Coverage Δ
fuzzing 40.17% <ø> (-0.04%) ⬇️
tests 86.22% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jkczyz jkczyz self-assigned this Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants