-
Notifications
You must be signed in to change notification settings - Fork 421
Do not generate a channel-closed mon update for never-signed chans #750
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
Do not generate a channel-closed mon update for never-signed chans #750
Conversation
Codecov Report
@@ Coverage Diff @@
## main #750 +/- ##
==========================================
- Coverage 91.44% 91.32% -0.12%
==========================================
Files 37 37
Lines 22249 22383 +134
==========================================
+ Hits 20346 20442 +96
- Misses 1903 1941 +38
Continue to review full report at Codecov.
|
795b46e to
96f6124
Compare
|
full_stack_target found a second, very related bug, so went ahead and fixed that too. |
valentinewallace
left a comment
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.
Nice to get these bugfixes in 🌴
lightning/src/chain/chainmonitor.rs
Outdated
| // user could use this object with some proxying in between which makes this | ||
| // possible, but in tests and fuzzing, this should be a panic. | ||
| #[cfg(any(test, feature = "fuzztarget"))] | ||
| panic!(); |
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.
nit, add panic error string and error logs if a user manages to hit this (because even though they can hit this as a proxy, iiuc they shouldn't)?
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.
I do hope no user is building with feature = fuzztarget! But, added a message in case we hit it while writing tests.
lightning/src/ln/channelmanager.rs
Outdated
| self.internal_funding_transaction_generated(temporary_channel_id, funding_txo, true); | ||
| } | ||
| #[cfg(test)] | ||
| pub(crate) fn funding_transaction_generated_dup_funding_id(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) { |
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.
Rather than adding this function, I prefer this approach:
diff --git a/lightning/src/ln/general_unit_tests.rs b/lightning/src/ln/general_unit_tests.rs
index 15fdf1f0..b13eee6f 100644
--- a/lightning/src/ln/general_unit_tests.rs
+++ b/lightning/src/ln/general_unit_tests.rs
@@ -569,7 +569,8 @@ fn test_duplicate_chan_id() {
}
let funding_signed_msg = get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, nodes[0].node.get_our_node_id());
- let channel_id = ::chain::transaction::OutPoint { txid: funding_created_msg.funding_txid, index: funding_created_msg.funding_output_index }.to_channel_id();
+ let outpoint = ::chain::transaction::OutPoint { txid: funding_created_msg.funding_txid, index: funding_created_msg.funding_output_index };
+ let channel_id = outpoint.to_channel_id();
// Now we have the first channel past funding_created (ie it has a txid-based channel_id, not a
// temporary one).
@@ -600,9 +601,14 @@ fn test_duplicate_chan_id() {
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()));
create_funding_transaction(&nodes[0], 100000, 42); // Get and check the FundingGenerationReady event
- nodes[0].node.funding_transaction_generated_dup_funding_id(&open_chan_2_msg.temporary_channel_id, funding_output);
+ let funding_created = {
+ let mut a_channel_lock = nodes[0].node.channel_state.lock().unwrap();
+ let mut as_chan = a_channel_lock.by_id.get_mut(&open_chan_2_msg.temporary_channel_id).unwrap();
+ let logger = test_utils::TestLogger::new();
+ as_chan.get_outbound_funding_created(outpoint, &&logger).unwrap()
+ };
check_added_monitors!(nodes[0], 0);
- nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()));
+ nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
// At this point we'll try to add a duplicate channel monitor, which will be rejected, but
// still needs to be cleared here.
check_added_monitors!(nodes[1], 1);
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.
Oh nice! I admit I spent too long trying to manually build the message signature, didn't realize our internal method here already made it easy.
valentinewallace
left a comment
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.
last 2 comments
db98df6 to
22dbcbf
Compare
22dbcbf to
eb6b27f
Compare
|
Squashed with no diff. |
| nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap(); | ||
| let open_chan_2_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); | ||
| nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_2_msg); | ||
| nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id())); |
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.
Consider making a local variable for the AcceptChannel message for consistency with how it was done earlier.
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.
Ah! I had previously moved to only storing as a variable if we need to modify it and resend. I just missed that we no longer modify+resend the previous one.
The full_stack_target managed to find a bug where, if we receive
a funding_created message which has a channel_id identical to an
existing channel, we'll end up
(a) having the monitor update for the new channel fail (due to
duplicate outpoint),
(b) creating a monitor update for the new channel as we
force-close it,
(c) panicing due to the force-close monitor update is applied to
the original channel and is considered out-of-order.
Obviously we shouldn't be creating a force-close monitor update for
a channel which can never appear on chain, so we do that here and
add a test which previously failed and checks a few
duplicate-channel-id cases.
Like the previous commit for channel-closed monitor updates for inbound channels during processing of a funding_created message, this resolves a more general issue for closing outbound channels which have sent a funding_created but not yet received a funding_signed. This issue was also detected by full_stack_target. To make similar issues easier to detect in testing and fuzzing, an additional assertion is added to panic on updates to a channel monitor before registering it.
eb6b27f to
36063ee
Compare
|
Only change was to make the two |
I'm getting some fuzzing iterations in for 0.0.12, and sadly found a few small things.
The full_stack_target managed to find a bug where, if we receive
a funding_created message which has a channel_id identical to an
existing channel, we'll end up
(a) having the monitor update for the new channel fail (due to
duplicate outpoint),
(b) creating a monitor update for the new channel as we
force-close it,
(c) panicing due to the force-close monitor update is applied to
the original channel and is considered out-of-order.
Obviously we shouldn't be creating a force-close monitor update for
a channel which can never appear on chain, so we do that here and
add a test which previously failed and checks a few
duplicate-channel-id cases.