-
Notifications
You must be signed in to change notification settings - Fork 950
fuzz-tests: Add a test for full_channel
operations
#8437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Changelog-None: Functions defined in `channeld/full_channel.h` contain channel operations like `ADD_HTLC`, `FULFILL_HTLC`, `UPDATE_FEERATE`, etc. Since they are a critical part of the HTLC state machine and may be influenced by external agents, add a stateful test for them.
Add a minimal input set as a seed corpus for the newly introduced test. This leads to discovery of interesting code paths faster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice target at a high level.
I think we're missing a lot of opportunities to fuzz invalid/unexpected/rare states, where bugs could be hiding. Some ideas for improvement:
- Unshackle the fuzzer a bit, so it can pick random values sometimes.
- Consider allowing the fuzzer to simulate the various commitment dance messages arriving at unexpected times (e.g., sending
revoke_and_ack
when the peer hasn't updated the commitment yet). - Consider allowing the fuzzer to generate multiple HTLC operations before doing the commitment signed dance. This is valid behavior per the spec.
memset(&p_htlc.preimage, (int)p_htlc.id, sizeof(p_htlc.preimage)); | ||
|
||
if (add_htlc(lchannel, sender, p_htlc.id, &p_htlc.preimage, msat, cltv)) { | ||
add_htlc(rchannel, sender, p_htlc.id, &p_htlc.preimage, msat, cltv); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should assert that the HTLC is successfully added to rchannel
here.
struct pending_htlc p_htlc = pending_htlcs[idx]; | ||
|
||
if (fulfill_htlc(lchannel, p_htlc.sender, p_htlc.id, &p_htlc.preimage)) { | ||
fulfill_htlc(rchannel, p_htlc.sender, p_htlc.id, &p_htlc.preimage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should assert that the HTLC is successfully fulfilled on rchannel
.
|
||
enum side sender = (fromwire_u8(&data, &size) % 2) ? REMOTE : LOCAL; | ||
struct amount_msat msat = fromwire_amount_msat_bounded(&data, &size); | ||
u32 cltv = current_blockheight + fromwire_u16(&data, &size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be too restrictive. The peer could set any CLTV in update_add_htlc
.
break; | ||
|
||
enum side sender = (fromwire_u8(&data, &size) % 2) ? REMOTE : LOCAL; | ||
struct amount_msat msat = fromwire_amount_msat_bounded(&data, &size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The peer could set any amount in their update_add_htlc
message.
* recv_revoke_and_ack -> recv_commit -> sending_revoke_and_ack) | ||
* in the correct opener vs. accepter order. | ||
*/ | ||
static void exchange_commits(struct channel *channel, enum side side, const struct htlc ***changed_htlcs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be very interesting to fuzz the commitment dance as well. For each of these messages, the channel peer can send all kinds of unexpected fields.
if (!channel_get_htlc(channel, original_sender, id)) | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The peer could send an invalid HTLC ID.
} | ||
case 3: /* UPDATE_FEE */ | ||
{ | ||
u32 feerate = fromwire_bounded_feerate(&data, &size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The peer could set any feerate.
{ | ||
u32 feerate = fromwire_bounded_feerate(&data, &size); | ||
if (update_feerate(lchannel, feerate)) | ||
update_feerate(rchannel, feerate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should assert that the feerate is successfully updated for rchannel
.
u32 height_increase = 1 + fromwire_u32(&data, &size); | ||
current_blockheight += height_increase; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The peer could set any blockheight, including one that is less than the previous one.
channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript_alt, | ||
lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0, &anchor, NULL); | ||
channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript_alt, | ||
rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0, &anchor, NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it expensive to generate these transactions? Maybe we should generate them after each loop iteration.
Functions defined in
channeld/full_channel.h
contain channel operations likeADD_HTLC
,FULFILL_HTLC
,UPDATE_FEERATE
, etc. Since they are a critical part of the HTLC state machine and may be influenced by external agents, add a stateful test for them.Checklist
Before submitting the PR, ensure the following tasks are completed. If an item is not applicable to your PR, please mark it as checked:
CC: @morehouse