Skip to content

Commit ed42039

Browse files
committed
Handle transition to Funded inline, without remove+readd from map
2 parents 31b72d1 + 7c8f482 commit ed42039

File tree

2 files changed

+54
-21
lines changed

2 files changed

+54
-21
lines changed

lightning/src/ln/channel.rs

+44-10
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,7 @@ impl<'a, SP: Deref> ChannelPhase<SP> where
11391139
SP::Target: SignerProvider,
11401140
<SP::Target as SignerProvider>::EcdsaSigner: ChannelSigner,
11411141
{
1142+
#[inline]
11421143
pub fn context(&'a self) -> &'a ChannelContext<SP> {
11431144
match self {
11441145
ChannelPhase::Funded(chan) => &chan.context,
@@ -1149,6 +1150,7 @@ impl<'a, SP: Deref> ChannelPhase<SP> where
11491150
}
11501151
}
11511152

1153+
#[inline]
11521154
pub fn context_mut(&'a mut self) -> &'a mut ChannelContext<SP> {
11531155
match self {
11541156
ChannelPhase::Funded(ref mut chan) => &mut chan.context,
@@ -1162,40 +1164,72 @@ impl<'a, SP: Deref> ChannelPhase<SP> where
11621164

11631165
/// A top-level channel struct, containing a channel phase
11641166
pub(super) struct ChannelWrapper<SP: Deref> where SP::Target: SignerProvider {
1165-
phase: ChannelPhase<SP>,
1167+
/// The inner channel phase
1168+
/// Option is used to facilitate in-place replacement (see e.g. move_v2_to_funded),
1169+
/// but it is never None, ensured in new() and set_phase()
1170+
phase: Option<ChannelPhase<SP>>,
11661171
}
11671172

11681173
impl<'a, SP: Deref> ChannelWrapper<SP> where SP::Target: SignerProvider {
11691174
pub fn new(phase: ChannelPhase<SP>) -> Self {
1170-
Self { phase }
1175+
Self {
1176+
phase: Some(phase),
1177+
}
11711178
}
11721179

1180+
#[inline]
11731181
pub fn phase(&self) -> &ChannelPhase<SP> {
1174-
&self.phase
1182+
self.phase.as_ref().unwrap()
11751183
}
11761184

1185+
#[inline]
11771186
pub fn phase_mut(&mut self) -> &mut ChannelPhase<SP> {
1178-
&mut self.phase
1187+
self.phase.as_mut().unwrap()
11791188
}
11801189

11811190
pub fn phase_take(self) -> ChannelPhase<SP> {
1182-
self.phase
1191+
match self.phase {
1192+
Some(phase) => phase,
1193+
None => panic!("None phase"),
1194+
}
11831195
}
11841196

11851197
pub fn get_funded_channel(&self) -> Option<&Channel<SP>> {
1186-
if let ChannelPhase::Funded(chan) = &self.phase {
1198+
if let ChannelPhase::Funded(chan) = &self.phase.as_ref().unwrap() {
11871199
Some(chan)
11881200
} else {
11891201
None
11901202
}
11911203
}
11921204

1205+
/// Change the internal phase
1206+
#[inline]
1207+
pub fn set_phase(&mut self, new_phase: ChannelPhase<SP>) {
1208+
self.phase = Some(new_phase);
1209+
}
1210+
1211+
pub fn move_v2_to_funded(&mut self, signing_session: InteractiveTxSigningSession) -> Result<(), ChannelError> {
1212+
// We need a borrow to the phase field, but self is only a mut ref
1213+
let phase_inline = self.phase.take().unwrap();
1214+
let new_phase = match phase_inline {
1215+
ChannelPhase::UnfundedOutboundV2(chan) =>
1216+
ChannelPhase::Funded(chan.into_funded_channel(signing_session)?),
1217+
ChannelPhase::UnfundedInboundV2(chan) =>
1218+
ChannelPhase::Funded(chan.into_funded_channel(signing_session)?),
1219+
_ => phase_inline,
1220+
};
1221+
self.set_phase(new_phase);
1222+
Ok(())
1223+
}
1224+
1225+
#[inline]
11931226
pub fn context(&'a self) -> &'a ChannelContext<SP> {
1194-
self.phase.context()
1227+
self.phase().context()
11951228
}
11961229

1230+
#[inline]
11971231
pub fn context_mut(&'a mut self) -> &'a mut ChannelContext<SP> {
1198-
self.phase.context_mut()
1232+
self.phase_mut().context_mut()
11991233
}
12001234
}
12011235

@@ -8888,7 +8922,7 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
88888922
}
88898923
}
88908924

8891-
pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
8925+
pub fn into_funded_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
88928926
let channel = Channel {
88938927
context: self.context,
88948928
interactive_tx_signing_session: Some(signing_session),
@@ -9082,7 +9116,7 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
90829116
self.generate_accept_channel_v2_message()
90839117
}
90849118

9085-
pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
9119+
pub fn into_funded_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
90869120
let channel = Channel {
90879121
context: self.context,
90889122
interactive_tx_signing_session: Some(signing_session),

lightning/src/ln/channelmanager.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -5037,6 +5037,7 @@ where
50375037
}
50385038
}
50395039
} else {
5040+
// put it back
50405041
peer_state.channel_by_id.insert(temporary_channel_id, ChannelWrapper::new(phase));
50415042
return Err(APIError::APIMisuseError {
50425043
err: format!(
@@ -8368,18 +8369,16 @@ where
83688369
"Got a tx_complete message with no interactive transaction construction expected or in-progress"
83698370
.into())),
83708371
}.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
8371-
let (channel_id, channel) = chan_entry.remove_entry();
8372-
let channel = match channel.phase_take() {
8373-
ChannelPhase::UnfundedOutboundV2(chan) => chan.into_channel(signing_session),
8374-
ChannelPhase::UnfundedInboundV2(chan) => chan.into_channel(signing_session),
8375-
_ => {
8372+
8373+
// change the channel phase inline
8374+
match chan_entry.get_mut().move_v2_to_funded(signing_session) {
8375+
Ok(_) => {},
8376+
Err(err) => {
83768377
debug_assert!(false); // It cannot be another variant as we are in the `Ok` branch of the above match.
8377-
Err(ChannelError::Warn(
8378-
"Got a tx_complete message with no interactive transaction construction expected or in-progress"
8379-
.into()))
8380-
},
8381-
}.map_err(|err| MsgHandleErrInternal::send_err_msg_no_close(format!("{}", err), msg.channel_id))?;
8382-
peer_state.channel_by_id.insert(channel_id, ChannelWrapper::new(ChannelPhase::Funded(channel)));
8378+
return Err(MsgHandleErrInternal::send_err_msg_no_close(format!("Got a tx_complete message, could not transition to funding, {}", err), msg.channel_id))?;
8379+
}
8380+
}
8381+
83838382
if let Some(funding_ready_for_sig_event) = funding_ready_for_sig_event_opt {
83848383
let mut pending_events = self.pending_events.lock().unwrap();
83858384
pending_events.push_back((funding_ready_for_sig_event, None));

0 commit comments

Comments
 (0)