-
Notifications
You must be signed in to change notification settings - Fork 366
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
base: main
Are you sure you want to change the base?
Implement accepting dual-funded channels without contributing #3137
Conversation
b981cd7
to
0caf60e
Compare
0caf60e
to
44821af
Compare
Codecov ReportAttention: Patch coverage is
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. |
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.
Looks great, mostly localized code improvements suggested.
As I see, the |
Looks to me that #2989 is in fact included in this PR (good!) |
0db700b
to
7dceedd
Compare
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.
Some initial comments, sorry this took so long to get back to.
lightning/src/ln/channelmanager.rs
Outdated
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) { |
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.
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
.
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.
Thanks @TheBlueMatt, for review and some good points raised. I'll address these ASAP ❤️
7dceedd
to
64c35f4
Compare
Still working on remaining initial feedback. |
64c35f4
to
a46da5a
Compare
No rush, let me know when you want another pass. |
0613f64
to
93896c4
Compare
Thanks for the feedback, @jkczyz. Addressing it today. |
4859142
to
fe5e557
Compare
fe5e557
to
63d4c8f
Compare
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.
Mostly minor things while going through a last pass.
63d4c8f
to
be4449a
Compare
@TheBlueMatt this ready for another pass when you get a gap 🙏 |
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()); |
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.
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.
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.
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
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.
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.
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.
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.
@@ -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 { |
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.
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.
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.
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!
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.
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 { |
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.
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!
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.
… up funding_tx_constructed
be4449a
to
d1823d5
Compare
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()); | ||
} | ||
}) |
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.
Can't used inspect
as it hasn't made it into our MSRV (1.63.0).
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.
Yeah I've removed it locally and haven't pushed latest changes yet 👍
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.