Skip to content

Commit 3068c8c

Browse files
committed
Support async signing for V2 channel establishment
When handling a tx_complete message, allow signers to return an error indicating that the signer has not yet complete. This will leave the ChannelPhase in an unfunded variant until the signer becomes unblocked.
1 parent 24682dc commit 3068c8c

File tree

2 files changed

+48
-30
lines changed

2 files changed

+48
-30
lines changed

lightning/src/ln/channel.rs

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,7 +1760,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
17601760

17611761
fn funding_tx_constructed<L: Deref>(
17621762
&mut self, logger: &L
1763-
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
1763+
) -> Result<(Option<msgs::CommitmentSigned>, Option<Event>), ChannelError>
17641764
where
17651765
L::Target: Logger
17661766
{
@@ -1803,11 +1803,14 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
18031803

18041804
let commitment_signed = context.get_initial_commitment_signed(logger);
18051805
let commitment_signed = match commitment_signed {
1806-
Ok(commitment_signed) => {
1806+
Some(commitment_signed) => {
18071807
context.funding_transaction = Some(unsigned_tx.into_unsigned_tx());
18081808
commitment_signed
18091809
},
1810-
Err(err) => return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }))),
1810+
None => {
1811+
context.channel_transaction_parameters.funding_outpoint = None;
1812+
return Ok((None, None));
1813+
},
18111814
};
18121815

18131816
let funding_ready_for_sig_event = None;
@@ -1839,7 +1842,7 @@ pub(super) trait InteractivelyFunded<SP: Deref> where SP::Target: SignerProvider
18391842
// Clear the interactive transaction constructor
18401843
self.interactive_tx_constructor_mut().take();
18411844

1842-
Ok((commitment_signed, funding_ready_for_sig_event))
1845+
Ok((Some(commitment_signed), funding_ready_for_sig_event))
18431846
}
18441847
}
18451848

@@ -4031,7 +4034,7 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
40314034

40324035
fn get_initial_counterparty_commitment_signature<L: Deref>(
40334036
&self, logger: &L
4034-
) -> Result<Signature, ChannelError>
4037+
) -> Option<Signature>
40354038
where
40364039
SP::Target: SignerProvider,
40374040
L::Target: Logger
@@ -4044,19 +4047,15 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
40444047
ChannelSignerType::Ecdsa(ref ecdsa) => {
40454048
ecdsa.sign_counterparty_commitment(&counterparty_initial_commitment_tx, Vec::new(), Vec::new(), &self.secp_ctx)
40464049
.map(|(signature, _)| signature)
4047-
.map_err(|_| ChannelError::Close(
4048-
(
4049-
"Failed to get signatures for new commitment_signed".to_owned(),
4050-
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
4051-
)))
4050+
.ok()
40524051
},
40534052
// TODO (taproot|arik)
40544053
#[cfg(taproot)]
40554054
_ => todo!(),
40564055
}
40574056
}
40584057

4059-
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Result<msgs::CommitmentSigned, ChannelError>
4058+
fn get_initial_commitment_signed<L: Deref>(&mut self, logger: &L) -> Option<msgs::CommitmentSigned>
40604059
where
40614060
SP::Target: SignerProvider,
40624061
L::Target: Logger
@@ -4072,32 +4071,42 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
40724071
panic!("Should not have advanced channel commitment tx numbers prior to initial commitment_signed");
40734072
}
40744073

4075-
let signature = match self.get_initial_counterparty_commitment_signature(logger) {
4076-
Ok(res) => res,
4077-
Err(e) => {
4078-
log_error!(logger, "Got bad signatures: {:?}!", e);
4079-
self.channel_transaction_parameters.funding_outpoint = None;
4080-
return Err(e);
4081-
}
4082-
};
4074+
match self.get_initial_counterparty_commitment_signature(logger) {
4075+
Some(signature) => {
4076+
if self.signer_pending_funding {
4077+
log_trace!(logger, "Counterparty commitment signature ready for initial commitment_signed message: clearing signer_pending_funding");
4078+
self.signer_pending_funding = false;
4079+
}
40834080

4084-
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id());
4081+
log_info!(logger, "Generated commitment_signed for peer for channel {}", &self.channel_id);
40854082

4086-
Ok(msgs::CommitmentSigned {
4087-
channel_id: self.channel_id,
4088-
htlc_signatures: vec![],
4089-
signature,
4090-
batch: None,
4091-
#[cfg(taproot)]
4092-
partial_signature_with_nonce: None,
4093-
})
4083+
Some(msgs::CommitmentSigned {
4084+
channel_id: self.channel_id,
4085+
htlc_signatures: vec![],
4086+
signature,
4087+
batch: None,
4088+
#[cfg(taproot)]
4089+
partial_signature_with_nonce: None,
4090+
})
4091+
},
4092+
None => {
4093+
#[cfg(not(async_signing))] {
4094+
panic!("Failed to get signature for initial commitment_signed");
4095+
}
4096+
#[cfg(async_signing)] {
4097+
log_trace!(logger, "Counterparty commitment signature not available for initial commitment_signed message; setting signer_pending_funding");
4098+
self.signer_pending_funding = true;
4099+
None
4100+
}
4101+
},
4102+
}
40944103
}
40954104

40964105
#[cfg(test)]
40974106
pub fn get_initial_counterparty_commitment_signature_for_test<L: Deref>(
40984107
&mut self, logger: &L, channel_transaction_parameters: ChannelTransactionParameters,
40994108
counterparty_cur_commitment_point_override: PublicKey,
4100-
) -> Result<Signature, ChannelError>
4109+
) -> Option<Signature>
41014110
where
41024111
SP::Target: SignerProvider,
41034112
L::Target: Logger

lightning/src/ln/channelmanager.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8307,7 +8307,7 @@ where
83078307
peer_state.pending_msg_events.push(msg_send_event);
83088308
};
83098309
if let Some(signing_session) = signing_session_opt {
8310-
let (commitment_signed, funding_ready_for_sig_event_opt) = match chan_phase_entry.get_mut() {
8310+
let (commitment_signed_opt, funding_ready_for_sig_event_opt) = match chan_phase_entry.get_mut() {
83118311
ChannelPhase::UnfundedOutboundV2(chan) => {
83128312
*chan.interactive_tx_signing_session_mut() = Some(signing_session);
83138313
chan.funding_tx_constructed(&self.logger)
@@ -8321,6 +8321,15 @@ where
83218321
.into())),
83228322
}.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
83238323

8324+
// Check if the signer returned a result.
8325+
//
8326+
// TODO: This can be removed once ChannelPhase is refactored into Channel as the phase
8327+
// transition will happen internally.
8328+
let commitment_signed = match commitment_signed_opt {
8329+
Some(commitment_signed) => commitment_signed,
8330+
None => return Ok(()),
8331+
};
8332+
83248333
let (channel_id, channel_phase) = chan_phase_entry.remove_entry();
83258334
let channel = match channel_phase {
83268335
ChannelPhase::UnfundedOutboundV2(chan) => chan.into_channel(),

0 commit comments

Comments
 (0)