Skip to content

Commit 37be726

Browse files
committed
Promote V2 channels to FundedChannel on initial commitment_signed receipt
Before this commit, unfunded V2 channels were promoted to `FundedChannel`s in `PendingV2Channel::funding_tx_constructed`. Since a monitor is only created upon receipt of an initial `commitment_signed`, this would cause a crash if the channel was read from persisted data between those two events. Consequently, we also need to hold an `interactive_tx_signing_session` for both of our unfunded V2 channel structs.
1 parent 5f79661 commit 37be726

File tree

2 files changed

+84
-62
lines changed

2 files changed

+84
-62
lines changed

lightning/src/ln/channel.rs

+71-43
Original file line numberDiff line numberDiff line change
@@ -1412,27 +1412,51 @@ impl<SP: Deref> Channel<SP> where
14121412
where
14131413
L::Target: Logger
14141414
{
1415-
let phase = core::mem::replace(&mut self.phase, ChannelPhase::Undefined);
1416-
let result = if let ChannelPhase::UnfundedV2(chan) = phase {
1415+
let result = if let ChannelPhase::UnfundedV2(chan) = &mut self.phase {
14171416
let logger = WithChannelContext::from(logger, &chan.context, None);
1418-
match chan.funding_tx_constructed(signing_session, &&logger) {
1419-
Ok((chan, commitment_signed, event)) => {
1420-
self.phase = ChannelPhase::Funded(chan);
1421-
Ok((commitment_signed, event))
1422-
},
1423-
Err((chan, e)) => {
1424-
self.phase = ChannelPhase::UnfundedV2(chan);
1425-
Err(e)
1426-
},
1427-
}
1417+
chan.funding_tx_constructed(signing_session, &&logger)
14281418
} else {
1429-
self.phase = phase;
14301419
Err(ChannelError::Warn("Got a tx_complete message with no interactive transaction construction expected or in-progress".to_owned()))
14311420
};
14321421

1433-
debug_assert!(!matches!(self.phase, ChannelPhase::Undefined));
14341422
result
14351423
}
1424+
1425+
pub fn commitment_signed<L: Deref>(
1426+
&mut self, msg: &msgs::CommitmentSigned, best_block: BestBlock, signer_provider: &SP, logger: &L
1427+
) -> Result<(Option<ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>>, Option<ChannelMonitorUpdate>), ChannelError>
1428+
where
1429+
L::Target: Logger
1430+
{
1431+
let phase = core::mem::replace(&mut self.phase, ChannelPhase::Undefined);
1432+
match phase {
1433+
ChannelPhase::UnfundedV2(chan) => {
1434+
let mut funded_channel = match chan.into_funded_channel() {
1435+
Ok(funded_channel) => funded_channel,
1436+
Err((pending_channel, err)) => {
1437+
self.phase = ChannelPhase::UnfundedV2(pending_channel);
1438+
return Err(err);
1439+
}
1440+
};
1441+
let res = match funded_channel.commitment_signed_initial_v2(msg, best_block, signer_provider, logger) {
1442+
Ok(monitor) => {
1443+
Ok((Some(monitor), None))
1444+
},
1445+
Err(err) => {
1446+
Err(err)
1447+
}
1448+
};
1449+
self.phase = ChannelPhase::Funded(funded_channel);
1450+
res
1451+
},
1452+
ChannelPhase::Funded(mut funded_channel) => {
1453+
let res = funded_channel.commitment_signed(msg, logger).map(|monitor_update_opt| (None, monitor_update_opt));
1454+
self.phase = ChannelPhase::Funded(funded_channel);
1455+
res
1456+
},
1457+
_ => Err(ChannelError::close("Got a commitment_signed message for an unfunded V1 channel!".into())),
1458+
}
1459+
}
14361460
}
14371461

14381462
impl<SP: Deref> From<OutboundV1Channel<SP>> for Channel<SP>
@@ -2074,8 +2098,8 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
20742098
}
20752099

20762100
pub fn funding_tx_constructed<L: Deref>(
2077-
mut self, mut signing_session: InteractiveTxSigningSession, logger: &L
2078-
) -> Result<(FundedChannel<SP>, msgs::CommitmentSigned, Option<Event>), (PendingV2Channel<SP>, ChannelError)>
2101+
&mut self, mut signing_session: InteractiveTxSigningSession, logger: &L
2102+
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError>
20792103
where
20802104
L::Target: Logger
20812105
{
@@ -2091,7 +2115,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
20912115
(
20922116
"Multiple outputs matched the expected script and value".to_owned(),
20932117
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
2094-
))).map_err(|e| (self, e));
2118+
)));
20952119
}
20962120
output_index = Some(idx as u16);
20972121
}
@@ -2103,7 +2127,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
21032127
(
21042128
"No output matched the funding script_pubkey".to_owned(),
21052129
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
2106-
))).map_err(|e| (self, e));
2130+
)));
21072131
};
21082132
self.context.channel_transaction_parameters.funding_outpoint = Some(outpoint);
21092133
self.context.holder_signer.as_mut().provide_channel_parameters(&self.context.channel_transaction_parameters);
@@ -2117,8 +2141,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
21172141
},
21182142
Err(err) => {
21192143
self.context.channel_transaction_parameters.funding_outpoint = None;
2120-
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })))
2121-
.map_err(|e| (self, e));
2144+
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })));
21222145
},
21232146
};
21242147

@@ -2129,10 +2152,10 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
21292152
false,
21302153
"Zero inputs were provided & zero witnesses were provided, but a count mismatch was somehow found",
21312154
);
2132-
return Err((self, ChannelError::Close((
2155+
return Err(ChannelError::Close((
21332156
"V2 channel rejected due to sender error".into(),
21342157
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }
2135-
))));
2158+
)));
21362159
}
21372160
None
21382161
} else {
@@ -2154,36 +2177,19 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
21542177
false,
21552178
"We don't support users providing inputs but somehow we had more than zero inputs",
21562179
);
2157-
return Err((self, ChannelError::Close((
2180+
return Err(ChannelError::Close((
21582181
"V2 channel rejected due to sender error".into(),
21592182
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }
2160-
))));
2183+
)));
21612184
};
21622185

21632186
self.context.channel_state = ChannelState::FundingNegotiated;
21642187

21652188
// Clear the interactive transaction constructor
21662189
self.interactive_tx_constructor.take();
2190+
self.interactive_tx_signing_session = Some(signing_session);
21672191

2168-
match self.unfunded_context.holder_commitment_point {
2169-
Some(holder_commitment_point) => {
2170-
let funded_chan = FundedChannel {
2171-
context: self.context,
2172-
interactive_tx_signing_session: Some(signing_session),
2173-
holder_commitment_point,
2174-
is_v2_established: true,
2175-
};
2176-
Ok((funded_chan, commitment_signed, funding_ready_for_sig_event))
2177-
},
2178-
None => {
2179-
Err(ChannelError::close(
2180-
format!(
2181-
"Expected to have holder commitment points available upon finishing interactive tx construction for channel {}",
2182-
self.context.channel_id(),
2183-
)))
2184-
.map_err(|e| (self, e))
2185-
},
2186-
}
2192+
Ok((commitment_signed, funding_ready_for_sig_event))
21872193
}
21882194
}
21892195

@@ -9093,6 +9099,8 @@ pub(super) struct PendingV2Channel<SP: Deref> where SP::Target: SignerProvider {
90939099
pub dual_funding_context: DualFundingChannelContext,
90949100
/// The current interactive transaction construction session under negotiation.
90959101
pub interactive_tx_constructor: Option<InteractiveTxConstructor>,
9102+
/// The signing session created after `tx_complete` handling
9103+
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
90969104
}
90979105

90989106
impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
@@ -9157,6 +9165,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
91579165
our_funding_inputs: funding_inputs,
91589166
},
91599167
interactive_tx_constructor: None,
9168+
interactive_tx_signing_session: None,
91609169
};
91619170
Ok(chan)
91629171
}
@@ -9327,6 +9336,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
93279336
context,
93289337
dual_funding_context,
93299338
interactive_tx_constructor,
9339+
interactive_tx_signing_session: None,
93309340
unfunded_context,
93319341
})
93329342
}
@@ -9404,6 +9414,24 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
94049414
pub fn get_accept_channel_v2_message(&self) -> msgs::AcceptChannelV2 {
94059415
self.generate_accept_channel_v2_message()
94069416
}
9417+
9418+
pub fn into_funded_channel(self) -> Result<FundedChannel<SP>, (PendingV2Channel<SP>, ChannelError)> {
9419+
let holder_commitment_point = match self.unfunded_context.holder_commitment_point {
9420+
Some(point) => point,
9421+
None => {
9422+
let channel_id = self.context.channel_id();
9423+
return Err((self, ChannelError::close(
9424+
format!("Expected to have holder commitment points available upon finishing interactive tx construction for channel {}",
9425+
channel_id))));
9426+
}
9427+
};
9428+
Ok(FundedChannel {
9429+
context: self.context,
9430+
interactive_tx_signing_session: self.interactive_tx_signing_session,
9431+
holder_commitment_point,
9432+
is_v2_established: true,
9433+
})
9434+
}
94079435
}
94089436

94099437
// Unfunded channel utilities

lightning/src/ln/channelmanager.rs

+13-19
Original file line numberDiff line numberDiff line change
@@ -8933,14 +8933,15 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
89338933
let peer_state = &mut *peer_state_lock;
89348934
match peer_state.channel_by_id.entry(msg.channel_id) {
89358935
hash_map::Entry::Occupied(mut chan_entry) => {
8936-
if let Some(chan) = chan_entry.get_mut().as_funded_mut() {
8937-
let logger = WithChannelContext::from(&self.logger, &chan.context, None);
8938-
let funding_txo = chan.context.get_funding_txo();
8939-
8940-
if chan.interactive_tx_signing_session.is_some() {
8941-
let monitor = try_channel_entry!(
8942-
self, peer_state, chan.commitment_signed_initial_v2(msg, best_block, &self.signer_provider, &&logger),
8943-
chan_entry);
8936+
let chan = chan_entry.get_mut();
8937+
let logger = WithChannelContext::from(&self.logger, &chan.context(), None);
8938+
let funding_txo = chan.context().get_funding_txo();
8939+
let (monitor_opt, monitor_update_opt) = try_channel_entry!(
8940+
self, peer_state, chan.commitment_signed(msg, best_block, &self.signer_provider, &&logger),
8941+
chan_entry);
8942+
8943+
if let Some(chan) = chan.as_funded_mut() {
8944+
if let Some(monitor) = monitor_opt {
89448945
let monitor_res = self.chain_monitor.watch_channel(monitor.channel_id(), monitor);
89458946
if let Ok(persist_state) = monitor_res {
89468947
handle_new_monitor_update!(self, persist_state, peer_state_lock, peer_state,
@@ -8955,19 +8956,12 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
89558956
)
89568957
)), chan_entry)
89578958
}
8958-
} else {
8959-
let monitor_update_opt = try_channel_entry!(
8960-
self, peer_state, chan.commitment_signed(msg, &&logger), chan_entry);
8961-
if let Some(monitor_update) = monitor_update_opt {
8962-
handle_new_monitor_update!(self, funding_txo.unwrap(), monitor_update, peer_state_lock,
8963-
peer_state, per_peer_state, chan);
8964-
}
8959+
} else if let Some(monitor_update) = monitor_update_opt {
8960+
handle_new_monitor_update!(self, funding_txo.unwrap(), monitor_update, peer_state_lock,
8961+
peer_state, per_peer_state, chan);
89658962
}
8966-
Ok(())
8967-
} else {
8968-
return try_channel_entry!(self, peer_state, Err(ChannelError::close(
8969-
"Got a commitment_signed message for an unfunded channel!".into())), chan_entry);
89708963
}
8964+
Ok(())
89718965
},
89728966
hash_map::Entry::Vacant(_) => Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a message for a channel from the wrong node! No such channel for the passed counterparty_node_id {}", counterparty_node_id), msg.channel_id))
89738967
}

0 commit comments

Comments
 (0)