Skip to content

Commit 79b8e9e

Browse files
committed
Encapsulate Channel enum variants inside a struct
Instead of exposing the Channel enum variants, make a Channel struct that wraps a ChannelPhase enum. This allows updating a Channel's phase without consuming it, which isn't possible when it is in a map without removing the entry first (e.g., as is done in ChannelManager).
1 parent 17d5fee commit 79b8e9e

File tree

2 files changed

+70
-56
lines changed

2 files changed

+70
-56
lines changed

lightning/src/ln/channel.rs

Lines changed: 68 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,9 +1124,15 @@ impl_writeable_tlv_based!(PendingChannelMonitorUpdate, {
11241124
(0, update, required),
11251125
});
11261126

1127-
/// The `Channel` enum describes the current phase in life of a lightning channel with each of
1127+
/// A payment channel with a counterparty throughout its life-cycle, encapsulating negotiation and
1128+
/// funding phases.
1129+
pub(super) struct Channel<SP: Deref> where SP::Target: SignerProvider {
1130+
phase: ChannelPhase<SP>,
1131+
}
1132+
1133+
/// The `ChannelPhase` enum describes the current phase in life of a lightning channel with each of
11281134
/// its variants containing an appropriate channel struct.
1129-
pub(super) enum Channel<SP: Deref> where SP::Target: SignerProvider {
1135+
enum ChannelPhase<SP: Deref> where SP::Target: SignerProvider {
11301136
UnfundedOutboundV1(OutboundV1Channel<SP>),
11311137
UnfundedInboundV1(InboundV1Channel<SP>),
11321138
#[allow(dead_code)] // TODO(dual_funding): Remove once creating V2 channels is enabled.
@@ -1139,54 +1145,54 @@ impl<SP: Deref> Channel<SP> where
11391145
<SP::Target as SignerProvider>::EcdsaSigner: ChannelSigner,
11401146
{
11411147
pub fn context(&self) -> &ChannelContext<SP> {
1142-
match self {
1143-
Channel::Funded(chan) => &chan.context,
1144-
Channel::UnfundedOutboundV1(chan) => &chan.context,
1145-
Channel::UnfundedInboundV1(chan) => &chan.context,
1146-
Channel::UnfundedV2(chan) => &chan.context,
1148+
match &self.phase {
1149+
ChannelPhase::Funded(chan) => &chan.context,
1150+
ChannelPhase::UnfundedOutboundV1(chan) => &chan.context,
1151+
ChannelPhase::UnfundedInboundV1(chan) => &chan.context,
1152+
ChannelPhase::UnfundedV2(chan) => &chan.context,
11471153
}
11481154
}
11491155

11501156
pub fn context_mut(&mut self) -> &mut ChannelContext<SP> {
1151-
match self {
1152-
Channel::Funded(ref mut chan) => &mut chan.context,
1153-
Channel::UnfundedOutboundV1(ref mut chan) => &mut chan.context,
1154-
Channel::UnfundedInboundV1(ref mut chan) => &mut chan.context,
1155-
Channel::UnfundedV2(ref mut chan) => &mut chan.context,
1157+
match &mut self.phase {
1158+
ChannelPhase::Funded(chan) => &mut chan.context,
1159+
ChannelPhase::UnfundedOutboundV1(chan) => &mut chan.context,
1160+
ChannelPhase::UnfundedInboundV1(chan) => &mut chan.context,
1161+
ChannelPhase::UnfundedV2(chan) => &mut chan.context,
11561162
}
11571163
}
11581164

11591165
pub fn unfunded_context_mut(&mut self) -> Option<&mut UnfundedChannelContext> {
1160-
match self {
1161-
Channel::Funded(_) => { debug_assert!(false); None },
1162-
Channel::UnfundedOutboundV1(chan) => Some(&mut chan.unfunded_context),
1163-
Channel::UnfundedInboundV1(chan) => Some(&mut chan.unfunded_context),
1164-
Channel::UnfundedV2(chan) => Some(&mut chan.unfunded_context),
1166+
match &mut self.phase {
1167+
ChannelPhase::Funded(_) => { debug_assert!(false); None },
1168+
ChannelPhase::UnfundedOutboundV1(chan) => Some(&mut chan.unfunded_context),
1169+
ChannelPhase::UnfundedInboundV1(chan) => Some(&mut chan.unfunded_context),
1170+
ChannelPhase::UnfundedV2(chan) => Some(&mut chan.unfunded_context),
11651171
}
11661172
}
11671173

11681174
pub fn is_funded(&self) -> bool {
1169-
matches!(self, Channel::Funded(_))
1175+
matches!(self.phase, ChannelPhase::Funded(_))
11701176
}
11711177

11721178
pub fn as_funded(&self) -> Option<&FundedChannel<SP>> {
1173-
if let Channel::Funded(channel) = self {
1179+
if let ChannelPhase::Funded(channel) = &self.phase {
11741180
Some(channel)
11751181
} else {
11761182
None
11771183
}
11781184
}
11791185

11801186
pub fn as_funded_mut(&mut self) -> Option<&mut FundedChannel<SP>> {
1181-
if let Channel::Funded(channel) = self {
1187+
if let ChannelPhase::Funded(channel) = &mut self.phase {
11821188
Some(channel)
11831189
} else {
11841190
None
11851191
}
11861192
}
11871193

11881194
pub fn as_unfunded_outbound_v1_mut(&mut self) -> Option<&mut OutboundV1Channel<SP>> {
1189-
if let Channel::UnfundedOutboundV1(channel) = self {
1195+
if let ChannelPhase::UnfundedOutboundV1(channel) = &mut self.phase {
11901196
Some(channel)
11911197
} else {
11921198
None
@@ -1195,47 +1201,47 @@ impl<SP: Deref> Channel<SP> where
11951201

11961202
#[cfg(test)]
11971203
pub fn is_unfunded_v1(&self) -> bool {
1198-
matches!(self, Channel::UnfundedOutboundV1(_) | Channel::UnfundedInboundV1(_))
1204+
matches!(self.phase, ChannelPhase::UnfundedOutboundV1(_) | ChannelPhase::UnfundedInboundV1(_))
11991205
}
12001206

12011207
pub fn is_unfunded_outbound_v1(&self) -> bool {
1202-
matches!(self, Channel::UnfundedOutboundV1(_))
1208+
matches!(self.phase, ChannelPhase::UnfundedOutboundV1(_))
12031209
}
12041210

12051211
pub fn into_unfunded_outbound_v1(self) -> Result<OutboundV1Channel<SP>, Self> {
1206-
if let Channel::UnfundedOutboundV1(channel) = self {
1212+
if let ChannelPhase::UnfundedOutboundV1(channel) = self.phase {
12071213
Ok(channel)
12081214
} else {
12091215
Err(self)
12101216
}
12111217
}
12121218

12131219
pub fn into_unfunded_inbound_v1(self) -> Result<InboundV1Channel<SP>, Self> {
1214-
if let Channel::UnfundedInboundV1(channel) = self {
1220+
if let ChannelPhase::UnfundedInboundV1(channel) = self.phase {
12151221
Ok(channel)
12161222
} else {
12171223
Err(self)
12181224
}
12191225
}
12201226

12211227
pub fn as_unfunded_v2(&self) -> Option<&PendingV2Channel<SP>> {
1222-
if let Channel::UnfundedV2(channel) = self {
1228+
if let ChannelPhase::UnfundedV2(channel) = &self.phase {
12231229
Some(channel)
12241230
} else {
12251231
None
12261232
}
12271233
}
12281234

12291235
pub fn as_unfunded_v2_mut(&mut self) -> Option<&mut PendingV2Channel<SP>> {
1230-
if let Channel::UnfundedV2(channel) = self {
1236+
if let ChannelPhase::UnfundedV2(channel) = &mut self.phase {
12311237
Some(channel)
12321238
} else {
12331239
None
12341240
}
12351241
}
12361242

12371243
pub fn into_unfunded_v2(self) -> Option<PendingV2Channel<SP>> {
1238-
if let Channel::UnfundedV2(channel) = self {
1244+
if let ChannelPhase::UnfundedV2(channel) = self.phase {
12391245
Some(channel)
12401246
} else {
12411247
None
@@ -1245,9 +1251,9 @@ impl<SP: Deref> Channel<SP> where
12451251
pub fn signer_maybe_unblocked<L: Deref>(
12461252
&mut self, chain_hash: ChainHash, logger: &L,
12471253
) -> Option<SignerResumeUpdates> where L::Target: Logger {
1248-
match self {
1249-
Channel::Funded(chan) => Some(chan.signer_maybe_unblocked(logger)),
1250-
Channel::UnfundedOutboundV1(chan) => {
1254+
match &mut self.phase {
1255+
ChannelPhase::Funded(chan) => Some(chan.signer_maybe_unblocked(logger)),
1256+
ChannelPhase::UnfundedOutboundV1(chan) => {
12511257
let (open_channel, funding_created) = chan.signer_maybe_unblocked(chain_hash, logger);
12521258
Some(SignerResumeUpdates {
12531259
commitment_update: None,
@@ -1263,7 +1269,7 @@ impl<SP: Deref> Channel<SP> where
12631269
shutdown_result: None,
12641270
})
12651271
},
1266-
Channel::UnfundedInboundV1(chan) => {
1272+
ChannelPhase::UnfundedInboundV1(chan) => {
12671273
let logger = WithChannelContext::from(logger, &chan.context, None);
12681274
let accept_channel = chan.signer_maybe_unblocked(&&logger);
12691275
Some(SignerResumeUpdates {
@@ -1280,38 +1286,38 @@ impl<SP: Deref> Channel<SP> where
12801286
shutdown_result: None,
12811287
})
12821288
},
1283-
Channel::UnfundedV2(_) => None,
1289+
ChannelPhase::UnfundedV2(_) => None,
12841290
}
12851291
}
12861292

12871293
pub fn is_resumable(&self) -> bool {
1288-
match self {
1289-
Channel::Funded(_) => false,
1290-
Channel::UnfundedOutboundV1(chan) => chan.is_resumable(),
1291-
Channel::UnfundedInboundV1(_) => false,
1292-
Channel::UnfundedV2(_) => false,
1294+
match &self.phase {
1295+
ChannelPhase::Funded(_) => false,
1296+
ChannelPhase::UnfundedOutboundV1(chan) => chan.is_resumable(),
1297+
ChannelPhase::UnfundedInboundV1(_) => false,
1298+
ChannelPhase::UnfundedV2(_) => false,
12931299
}
12941300
}
12951301

12961302
pub fn maybe_get_open_channel<L: Deref>(
12971303
&mut self, chain_hash: ChainHash, logger: &L,
12981304
) -> Option<OpenChannelMessage> where L::Target: Logger {
1299-
match self {
1300-
Channel::Funded(_) => None,
1301-
Channel::UnfundedOutboundV1(chan) => {
1305+
match &mut self.phase {
1306+
ChannelPhase::Funded(_) => None,
1307+
ChannelPhase::UnfundedOutboundV1(chan) => {
13021308
let logger = WithChannelContext::from(logger, &chan.context, None);
13031309
chan.get_open_channel(chain_hash, &&logger)
13041310
.map(|msg| OpenChannelMessage::V1(msg))
13051311
},
1306-
Channel::UnfundedInboundV1(_) => {
1312+
ChannelPhase::UnfundedInboundV1(_) => {
13071313
// Since unfunded inbound channel maps are cleared upon disconnecting a peer,
13081314
// they are not persisted and won't be recovered after a crash.
13091315
// Therefore, they shouldn't exist at this point.
13101316
debug_assert!(false);
13111317
None
13121318
},
13131319
#[cfg(dual_funding)]
1314-
Channel::UnfundedV2(chan) => {
1320+
ChannelPhase::UnfundedV2(chan) => {
13151321
if chan.context.is_outbound() {
13161322
Some(OpenChannelMessage::V2(chan.get_open_channel_v2(chain_hash)))
13171323
} else {
@@ -1323,7 +1329,7 @@ impl<SP: Deref> Channel<SP> where
13231329
}
13241330
},
13251331
#[cfg(not(dual_funding))]
1326-
Channel::UnfundedV2(_) => {
1332+
ChannelPhase::UnfundedV2(_) => {
13271333
debug_assert!(false);
13281334
None
13291335
},
@@ -1337,16 +1343,16 @@ impl<SP: Deref> Channel<SP> where
13371343
F::Target: FeeEstimator,
13381344
L::Target: Logger,
13391345
{
1340-
match self {
1341-
Channel::Funded(_) => Ok(None),
1342-
Channel::UnfundedOutboundV1(chan) => {
1346+
match &mut self.phase {
1347+
ChannelPhase::Funded(_) => Ok(None),
1348+
ChannelPhase::UnfundedOutboundV1(chan) => {
13431349
let logger = WithChannelContext::from(logger, &chan.context, None);
13441350
chan.maybe_handle_error_without_close(chain_hash, fee_estimator, &&logger)
13451351
.map(|msg| Some(OpenChannelMessage::V1(msg)))
13461352
},
1347-
Channel::UnfundedInboundV1(_) => Ok(None),
1353+
ChannelPhase::UnfundedInboundV1(_) => Ok(None),
13481354
#[cfg(dual_funding)]
1349-
Channel::UnfundedV2(chan) => {
1355+
ChannelPhase::UnfundedV2(chan) => {
13501356
if chan.context.is_outbound() {
13511357
chan.maybe_handle_error_without_close(chain_hash, fee_estimator)
13521358
.map(|msg| Some(OpenChannelMessage::V2(msg)))
@@ -1355,7 +1361,7 @@ impl<SP: Deref> Channel<SP> where
13551361
}
13561362
},
13571363
#[cfg(not(dual_funding))]
1358-
Channel::UnfundedV2(_) => {
1364+
ChannelPhase::UnfundedV2(_) => {
13591365
debug_assert!(false);
13601366
Ok(None)
13611367
},
@@ -1369,7 +1375,9 @@ where
13691375
<SP::Target as SignerProvider>::EcdsaSigner: ChannelSigner,
13701376
{
13711377
fn from(channel: OutboundV1Channel<SP>) -> Self {
1372-
Channel::UnfundedOutboundV1(channel)
1378+
Channel {
1379+
phase: ChannelPhase::UnfundedOutboundV1(channel),
1380+
}
13731381
}
13741382
}
13751383

@@ -1379,7 +1387,9 @@ where
13791387
<SP::Target as SignerProvider>::EcdsaSigner: ChannelSigner,
13801388
{
13811389
fn from(channel: InboundV1Channel<SP>) -> Self {
1382-
Channel::UnfundedInboundV1(channel)
1390+
Channel {
1391+
phase: ChannelPhase::UnfundedInboundV1(channel),
1392+
}
13831393
}
13841394
}
13851395

@@ -1389,7 +1399,9 @@ where
13891399
<SP::Target as SignerProvider>::EcdsaSigner: ChannelSigner,
13901400
{
13911401
fn from(channel: PendingV2Channel<SP>) -> Self {
1392-
Channel::UnfundedV2(channel)
1402+
Channel {
1403+
phase: ChannelPhase::UnfundedV2(channel),
1404+
}
13931405
}
13941406
}
13951407

@@ -1399,7 +1411,9 @@ where
13991411
<SP::Target as SignerProvider>::EcdsaSigner: ChannelSigner,
14001412
{
14011413
fn from(channel: FundedChannel<SP>) -> Self {
1402-
Channel::Funded(channel)
1414+
Channel {
1415+
phase: ChannelPhase::Funded(channel),
1416+
}
14031417
}
14041418
}
14051419

lightning/src/ln/functional_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9221,7 +9221,7 @@ fn test_duplicate_chan_id() {
92219221
let logger = test_utils::TestLogger::new();
92229222
chan.get_funding_created(tx.clone(), funding_outpoint, false, &&logger).map_err(|_| ()).unwrap()
92239223
} else {
9224-
panic!("Unexpected Channel variant")
9224+
panic!("Unexpected Channel phase")
92259225
}.unwrap()
92269226
};
92279227
check_added_monitors!(nodes[0], 0);
@@ -9926,7 +9926,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e
99269926
if let Some(mut chan) = channel.as_unfunded_outbound_v1_mut() {
99279927
chan.context.holder_dust_limit_satoshis = 546;
99289928
} else {
9929-
panic!("Unexpected Channel variant");
9929+
panic!("Unexpected Channel phase");
99309930
}
99319931
}
99329932

0 commit comments

Comments
 (0)