Skip to content
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

Implement accepting dual-funded channels without contributing #3137

Open
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

dunxen
Copy link
Contributor

@dunxen dunxen commented Jun 20, 2024

We split this out from #2302 for easier review and to address the common non-public API parts of the V2 channel establishment implementation.

This will allow the holder to be an acceptor, but not initiator of V2 channels. We also don't expose an API for contributing to an inbound channel.

The functionality to initiate V2 channels and fund inbound channels forms part of #2302.

@dunxen dunxen force-pushed the 2024-06-non-public-API-v2-channels branch 3 times, most recently from b981cd7 to 0caf60e Compare June 20, 2024 16:14
@dunxen dunxen marked this pull request as ready for review June 20, 2024 16:27
@dunxen dunxen mentioned this pull request Jun 20, 2024
4 tasks
@dunxen dunxen force-pushed the 2024-06-non-public-API-v2-channels branch from 0caf60e to 44821af Compare June 24, 2024 16:55
@codecov-commenter
Copy link

codecov-commenter commented Jun 24, 2024

Codecov Report

Attention: Patch coverage is 62.30159% with 570 lines in your changes missing coverage. Please review.

Project coverage is 89.19%. Comparing base (0db051b) to head (a52d5c7).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
lightning/src/ln/channelmanager.rs 58.92% 235 Missing and 18 partials ⚠️
lightning/src/ln/channel.rs 69.46% 154 Missing and 17 partials ⚠️
lightning/src/ln/interactivetxs.rs 51.81% 142 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3137      +/-   ##
==========================================
- Coverage   89.61%   89.19%   -0.42%     
==========================================
  Files         127      127              
  Lines      103534   105156    +1622     
  Branches   103534   105156    +1622     
==========================================
+ Hits        92781    93796    +1015     
- Misses       8053     8614     +561     
- Partials     2700     2746      +46     

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

Copy link
Contributor

@optout21 optout21 left a comment

Choose a reason for hiding this comment

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

Looks great, mostly localized code improvements suggested.

lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
lightning/src/ln/mod.rs Outdated Show resolved Hide resolved
@optout21
Copy link
Contributor

As I see, the dual_funding cfg flag has been removed (not a problem)

@optout21
Copy link
Contributor

Looks to me that #2989 is in fact included in this PR (good!)

@dunxen dunxen force-pushed the 2024-06-non-public-API-v2-channels branch 4 times, most recently from 0db700b to 7dceedd Compare July 3, 2024 09:44
@dunxen dunxen requested review from optout21 and TheBlueMatt and removed request for optout21 July 3, 2024 09:51
optout21
optout21 previously approved these changes Jul 3, 2024
lightning/src/events/mod.rs Outdated Show resolved Hide resolved
@dunxen dunxen requested a review from jkczyz July 4, 2024 15:02
Copy link
Collaborator

@TheBlueMatt TheBlueMatt left a comment

Choose a reason for hiding this comment

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

Some initial comments, sorry this took so long to get back to.

lightning/src/events/mod.rs Show resolved Hide resolved
lightning/src/events/mod.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
if chan.interactive_tx_signing_session.is_some() {
let monitor = try_chan_phase_entry!(self,
chan.commitment_signed_initial_v2(&msg, best_block, &self.signer_provider, &&logger), chan_phase_entry);
if let Ok(persist_status) = self.chain_monitor.watch_channel(chan.context.get_funding_txo().unwrap(), monitor) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If the persist status is pending we need to handle the later stuff in monitor_updating_restored. Really the whole contents of the block here should be in monitor_updating_restored.

lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
Copy link
Contributor Author

@dunxen dunxen left a comment

Choose a reason for hiding this comment

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

Thanks @TheBlueMatt, for review and some good points raised. I'll address these ASAP ❤️

@dunxen dunxen force-pushed the 2024-06-non-public-API-v2-channels branch from 7dceedd to 64c35f4 Compare July 10, 2024 16:05
@dunxen
Copy link
Contributor Author

dunxen commented Jul 10, 2024

Still working on remaining initial feedback.

@dunxen dunxen force-pushed the 2024-06-non-public-API-v2-channels branch from 64c35f4 to a46da5a Compare July 11, 2024 14:55
@TheBlueMatt
Copy link
Collaborator

No rush, let me know when you want another pass.

@dunxen dunxen force-pushed the 2024-06-non-public-API-v2-channels branch 2 times, most recently from 0613f64 to 93896c4 Compare July 16, 2024 10:36
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
@dunxen
Copy link
Contributor Author

dunxen commented Oct 30, 2024

Thanks for the feedback, @jkczyz. Addressing it today.

Copy link
Contributor

@jkczyz jkczyz left a comment

Choose a reason for hiding this comment

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

Mostly minor things while going through a last pass.

lightning/src/ln/interactivetxs.rs Outdated Show resolved Hide resolved
lightning/src/ln/interactivetxs.rs Outdated Show resolved Hide resolved
lightning/src/events/mod.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
@dunxen dunxen force-pushed the 2024-06-non-public-API-v2-channels branch from 63d4c8f to be4449a Compare November 5, 2024 11:21
@dunxen
Copy link
Contributor Author

dunxen commented Nov 6, 2024

@TheBlueMatt this ready for another pass when you get a gap 🙏

lightning/src/ln/channel.rs Show resolved Hide resolved
lightning/src/ln/channel.rs Show resolved Hide resolved
for (idx, input) in funding_inputs.iter().enumerate() {
if let Some(output) = input.1.as_transaction().output.get(input.0.previous_output.vout as usize) {
total_input_satoshis = total_input_satoshis.saturating_add(output.value.to_sat());
our_contributed_weight = our_contributed_weight.saturating_add(estimate_input_weight(output).to_wu());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't we need to account for the weight the witness will have? Presumably users doing dual funding will have to provide that as an input when they provide funding inputs. Luckily doesn't impact this PR because we don't do dual-funding yet but will need to be addressed before we do that.

Copy link
Contributor Author

@dunxen dunxen Nov 8, 2024

Choose a reason for hiding this comment

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

Sorry for missing this comment which is a super important one 🤦‍♂️

It may be possible if they provide "dummy" witnesses or provide the sizes for the witnesses.

They won't be able to provide valid witnesses (that involve signatures) before construction of the funding transaction is finished.

The issue is since this transaction is always using SIGHASH_ALL for any inputs sigs, we don't know what the sighash we need to sign will be for the funding tx at this point as we have no idea of the inputs or outputs the counterparty will provide (except for the 2-of-2 funding output of course). So the signatures cannot be created by the user before construction is done. At best we can estimate based on the output type for each input provided by the user (without them providing sizes or dummy witnesses).

Thoughts? Or has Fry-day fried my brain? I'm actually hoping that's the case and it's a super trivial fix :P

Copy link
Collaborator

@TheBlueMatt TheBlueMatt Nov 8, 2024

Choose a reason for hiding this comment

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

We only need to care about the outputs provided by the local user, no? We're trying to calculate the weight that we've contributed so we don't care about the counterparty's inputs. I assume we can just make the user provide them.

Copy link
Contributor Author

@dunxen dunxen Nov 8, 2024

Choose a reason for hiding this comment

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

Yeah we don't care about the weight of the counterparty's inputs/outputs, and we could ask the user to provide their own witness weights or dummy witnesses that use dummy signatures where appropriate.

What they won't be able to provide is valid signatures in witnesses until after the whole tx is constructed as it's SIGHASH_ALL, but we don't need them yet, just the sizes.

We will have to ask the user again to provide those valid witnesses after transaction construction like we do are doing for V2.

So should we just as for weights of witnesses along with the inputs? Then they can provide actual valid witnesses after construction like #2302 already does.

lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channelmanager.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
@@ -5298,6 +5625,58 @@ impl<SP: Deref> Channel<SP> where
}
}

pub fn tx_signatures(&mut self, msg: &msgs::TxSignatures) -> Result<(Option<msgs::TxSignatures>, Option<Transaction>), ChannelError> {
if let Some(ref mut signing_session) = self.interactive_tx_signing_session {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't we need to check the state here? ISTM a peer could send a tx_signatures message to us before sending us the initial commitment_signed leaving us unable to claim our funds if the peer goes away and the funding tx confirms. We'll also need to wait until the initial ChannelMonitor (from commitment_signed handling) has finished persisting before we broadcast.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should check state and wait for persistence of initial ChannelMonitor here, but in InteractiveTxSigningSession we will only allow our tx_signatures to be sent if we have received a commitment_signed, but looks like something went missing in commitment_signed_initial_v2 along the way.

Nothing broke in the test as we always send an empty witnesses array in tx_signatures since we don't support contributing funds/inputs here. I'll make sure it goes through the full flow in this PR anyway so we can catch that error.

Thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Might be worth adding a test with async persist here too. Set the persistence to InProgress, provide tx_signatures and make sure the tx doesn't broadcast then finish the persist and make sure it goes out then.

@@ -5298,6 +5625,58 @@ impl<SP: Deref> Channel<SP> where
}
}

pub fn tx_signatures(&mut self, msg: &msgs::TxSignatures) -> Result<(Option<msgs::TxSignatures>, Option<Transaction>), ChannelError> {
if let Some(ref mut signing_session) = self.interactive_tx_signing_session {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We should check state and wait for persistence of initial ChannelMonitor here, but in InteractiveTxSigningSession we will only allow our tx_signatures to be sent if we have received a commitment_signed, but looks like something went missing in commitment_signed_initial_v2 along the way.

Nothing broke in the test as we always send an empty witnesses array in tx_signatures since we don't support contributing funds/inputs here. I'll make sure it goes through the full flow in this PR anyway so we can catch that error.

Thanks!

lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Show resolved Hide resolved
lightning/src/ln/channel.rs Outdated Show resolved Hide resolved
lightning/src/ln/channel.rs Show resolved Hide resolved
We'll only gate public API related to contributing toward an inbound or opening
a dual funded channel.
Here we add the `interactive_tx_constructor` field to the `Channel`,
`OutboundV2Channel`, and `InboundV2Channel` structs.
For now this is unneeded as we do not provide any inputs as channel
acceptor and we do not allow creating outbound channels yet. It will
be re-added when that functionality is introduced.
1. InteractiveTxConstructorArgs is introduced to act as a single, more
   readable input to InteractiveTxConstructor::new().
2. Various documentation updates.
Comment on lines +1730 to +1735
Some(ref mut tx_constructor) => tx_constructor.handle_tx_complete(msg)
.inspect(|tx_complete_value| {
if let HandleTxCompleteValue::SendTxComplete(_, signing_session) = tx_complete_value {
self.context_mut().next_funding_txid = Some(signing_session.unsigned_tx.txid());
}
})
Copy link
Contributor

Choose a reason for hiding this comment

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

Can't used inspect as it hasn't made it into our MSRV (1.63.0).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I've removed it locally and haven't pushed latest changes yet 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants