Skip to content

smite-ir: add SendError and SendWarning operations and generators - #257

Open
erickcestari wants to merge 5 commits into
lnfuzz:masterfrom
erickcestari:send-error-warning
Open

erickcestari wants to merge 5 commits into
lnfuzz:masterfrom
erickcestari:send-error-warning

Conversation

@erickcestari

Copy link
Copy Markdown
Contributor

Adds SendError and SendWarning operations plus a generator for each, so programs can send BOLT 1 error and warning messages and exercise the target's error handling and force-close paths. The generators use the all-zero channel_id one time in four to cover the "all channels" case.

Closes #256

@erickcestari

Copy link
Copy Markdown
Contributor Author

At the current state of the PR, adding SendError breaks AcceptChannelOracle for LDK (I haven't tested it with other implementations yet), because LDK accepts a new open_channel with the same temporary_channel_id after the first one has been errored out.

INFO  [smite::scenarios] Scenario initialized! Executing input...
INFO  [smite::runners] Reading input from "/input.bin"
DEBUG [smite_scenarios::scenarios::ir] [14.642µs] Executing IR program (138 instructions, 1674 input bytes)
DEBUG [smite_scenarios::executor] [630.406µs] SendOpenChannel: 331 bytes
DEBUG [smite_scenarios::executor] [812.627µs] RecvAcceptChannel: waiting
DEBUG [smite_scenarios::executor] [2.305253ms] RecvAcceptChannel: received
DEBUG [smite_scenarios::executor] [2.421323ms] SendError: 36 bytes
DEBUG [smite_scenarios::executor] [2.510861ms] SendOpenChannel: 331 bytes
DEBUG [smite_scenarios::executor] [2.516255ms] RecvAcceptChannel: waiting
DEBUG [smite_scenarios::executor] [3.631017ms] RecvAcceptChannel: received
ERROR [smite::runners] Test case failed: invalid accept_channel for temporary_channel_id 33c6df673bcc970e0d07f771b2dbe842304a1bf40a4527f5a450927e0f78a817: temporary_channel_id reuse: previous negotiation has not reached funding_created

@erickcestari

erickcestari commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

Added OrphanedAccepts to count accept_channel replies still in flight for negotiations we failed with an error before receiving them. A reply still in flight when the error is sent is validated against the failed negotiation instead of being reported as unknown.

Comment thread smite-scenarios/src/executor.rs Outdated
Comment on lines +562 to +564
// A reply to a negotiation we failed with `error` is checked
// against it but not recorded: the target has forgotten it.
let orphan = self.orphaned_accepts.take(ac.temporary_channel_id);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: #257 (comment)

A reply still in flight when the error is sent is validated against the failed negotiation instead of being reported as unknown.

I don't know how relevant this is (currently), since we don't open multiple channels afaik, but if the target never replies to the first open_channel but accepts a second open_channelwith the same temporary_channel_id, we will think the received accept_channel is orphaned:

SMITE (us)                                 TARGET
   |                                          |
   |------------ open_channel (X) ----------->|
   |                                          |
   |--------------- error (X) --------------->|
   |                                          |
   |------- open_channel (X, reuse) --------->|
   |                                          |
💥 |<---------- accept_channel (X) -----------|
   |                                          |

Is this a problem?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, and it is reachable today on LDK. ldk-node accepts inbound channels manually, so accept_channel is only sent from its event task, and our error removes the pending request first. Since requests are keyed by temporary_channel_id, the stale event then accepts the reused open_channel. We get a single accept_channel answering the second open. LND and CLN answer synchronously, and Eclair drops an error for a channel it hasn't spawned yet, so they still answer the first one.

The reply now answers the first negotiation it is valid for (orphans oldest first, then live), and skipped orphans are dropped. When it is valid for both we can't tell, so it counts as the orphan's reply. That only costs depth, not a false positive.

Comment thread smite-scenarios/src/executor.rs Outdated
@erickcestari
erickcestari force-pushed the send-error-warning branch 2 times, most recently from dbb6ca6 to 7804af1 Compare September 21, 2026 14:33
…ndError

The target forgets a channel we fail with `error`, so renegotiating its
temporary_channel_id or reusing its funding outpoint was wrongly reported
as reuse or a duplicate funding_signed. A reply still in flight when the
error is sent is validated against the failed channel instead of being
reported as unknown.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement SendError and SendWarning generators

2 participants