Skip to content

Commit 8a835e5

Browse files
committed
SplicingChannel: make post_pending optional, add post_funded
1 parent 3cca201 commit 8a835e5

File tree

1 file changed

+134
-48
lines changed

1 file changed

+134
-48
lines changed

lightning/src/ln/channel.rs

Lines changed: 134 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,7 +1215,7 @@ impl<SP: Deref> Channel<SP> where
12151215
ChannelPhase::UnfundedInboundV1(chan) => &chan.context,
12161216
ChannelPhase::UnfundedV2(chan) => &chan.context,
12171217
#[cfg(splicing)]
1218-
ChannelPhase::RefundingV2(chan) => &chan.pre_funded.context,
1218+
ChannelPhase::RefundingV2(chan) => chan.context(),
12191219
}
12201220
}
12211221

@@ -1227,7 +1227,7 @@ impl<SP: Deref> Channel<SP> where
12271227
ChannelPhase::UnfundedInboundV1(chan) => &mut chan.context,
12281228
ChannelPhase::UnfundedV2(chan) => &mut chan.context,
12291229
#[cfg(splicing)]
1230-
ChannelPhase::RefundingV2(chan) => &mut chan.pre_funded.context,
1230+
ChannelPhase::RefundingV2(chan) => chan.context_mut(),
12311231
}
12321232
}
12331233

@@ -1239,7 +1239,7 @@ impl<SP: Deref> Channel<SP> where
12391239
ChannelPhase::UnfundedInboundV1(chan) => &chan.funding,
12401240
ChannelPhase::UnfundedV2(chan) => &chan.funding,
12411241
#[cfg(splicing)]
1242-
ChannelPhase::RefundingV2(chan) => &chan.pre_funded.funding,
1242+
ChannelPhase::RefundingV2(chan) => chan.funding(),
12431243
}
12441244
}
12451245

@@ -1252,7 +1252,7 @@ impl<SP: Deref> Channel<SP> where
12521252
ChannelPhase::UnfundedInboundV1(chan) => &mut chan.funding,
12531253
ChannelPhase::UnfundedV2(chan) => &mut chan.funding,
12541254
#[cfg(splicing)]
1255-
ChannelPhase::RefundingV2(chan) => &mut chan.pre_funded.funding,
1255+
ChannelPhase::RefundingV2(chan) => chan.funding_mut(),
12561256
}
12571257
}
12581258

@@ -1264,7 +1264,7 @@ impl<SP: Deref> Channel<SP> where
12641264
ChannelPhase::UnfundedInboundV1(chan) => (&chan.funding, &mut chan.context),
12651265
ChannelPhase::UnfundedV2(chan) => (&chan.funding, &mut chan.context),
12661266
#[cfg(splicing)]
1267-
ChannelPhase::RefundingV2(chan) => (&chan.pre_funded.funding, &mut chan.pre_funded.context),
1267+
ChannelPhase::RefundingV2(chan) => chan.funding_and_context_mut(),
12681268
}
12691269
}
12701270

@@ -1348,7 +1348,13 @@ impl<SP: Deref> Channel<SP> where
13481348
match &mut self.phase {
13491349
ChannelPhase::UnfundedV2(channel) => Some(channel),
13501350
#[cfg(splicing)]
1351-
ChannelPhase::RefundingV2(channel) => Some(&mut channel.post_pending),
1351+
ChannelPhase::RefundingV2(channel) => {
1352+
if let Some(ref mut post_pending) = &mut channel.post_pending {
1353+
Some(post_pending)
1354+
} else {
1355+
None
1356+
}
1357+
}
13521358
_ => None,
13531359
}
13541360
}
@@ -1531,8 +1537,8 @@ impl<SP: Deref> Channel<SP> where
15311537
}
15321538
#[cfg(splicing)]
15331539
ChannelPhase::RefundingV2(chan) => {
1534-
let logger = WithChannelContext::from(logger, &chan.post_pending.context, None);
1535-
chan.post_pending.funding_tx_constructed(counterparty_node_id, signing_session, &&logger)
1540+
let logger = WithChannelContext::from(logger, chan.context(), None);
1541+
chan.funding_tx_constructed(counterparty_node_id, signing_session, &&logger)
15361542
}
15371543
_ => {
15381544
Err(ChannelError::Warn("Got a tx_complete message with no interactive transaction construction expected or in-progress".to_owned()))
@@ -1593,42 +1599,26 @@ impl<SP: Deref> Channel<SP> where
15931599
},
15941600
#[cfg(splicing)]
15951601
ChannelPhase::RefundingV2(chan) => {
1596-
let holder_commitment_point = match chan.post_pending.unfunded_context.holder_commitment_point {
1597-
Some(point) => point,
1598-
None => {
1599-
let channel_id = chan.post_pending.context.channel_id();
1600-
// TODO(dual_funding): Add async signing support.
1601-
return Err( ChannelError::close(
1602-
format!("Expected to have holder commitment points available upon finishing interactive splice tx construction for channel {}",
1603-
channel_id)));
1604-
}
1605-
};
1606-
let mut funded_channel = FundedChannel {
1607-
funding: chan.post_pending.funding,
1608-
context: chan.post_pending.context,
1609-
interactive_tx_signing_session: chan.post_pending.interactive_tx_signing_session,
1610-
holder_commitment_point,
1611-
is_v2_established: true,
1612-
#[cfg(splicing)]
1613-
pending_splice_pre: None,
1614-
#[cfg(splicing)]
1615-
pending_splice_post: chan.post_pending.pending_splice_post,
1616-
};
1617-
let res = funded_channel.commitment_signed_initial_v2(msg, best_block, signer_provider, logger)
1618-
.map(|monitor| (Some(monitor), None))
1619-
// TODO: Change to `inspect_err` when MSRV is high enough.
1620-
.map_err(|err| {
1621-
// We always expect a `ChannelError` close.
1622-
debug_assert!(matches!(err, ChannelError::Close(_)));
1623-
err
1624-
});
1625-
self.phase = ChannelPhase::Funded(funded_channel);
1626-
res
1602+
if let Some(mut post_funded) = chan.post_funded {
1603+
let res = post_funded.commitment_signed_initial_v2(msg, best_block, signer_provider, logger)
1604+
.map(|monitor| (Some(monitor), None))
1605+
// TODO: Change to `inspect_err` when MSRV is high enough.
1606+
.map_err(|err| {
1607+
// We always expect a `ChannelError` close.
1608+
debug_assert!(matches!(err, ChannelError::Close(_)));
1609+
err
1610+
});
1611+
self.phase = ChannelPhase::Funded(post_funded);
1612+
res
1613+
} else {
1614+
self.phase = ChannelPhase::RefundingV2(chan);
1615+
Err(ChannelError::close("Got a commitment_signed message for an unfunded channel!".into()))
1616+
}
16271617
}
16281618
_ => {
16291619
self.phase = phase;
16301620
debug_assert!(!matches!(self.phase, ChannelPhase::Undefined));
1631-
Err(ChannelError::close("Got a commitment_signed message for an unfunded V1 channel!".into()))
1621+
Err(ChannelError::close("Got a commitment_signed message for an unfunded channel!".into()))
16321622
}
16331623
};
16341624
debug_assert!(!matches!(self.phase, ChannelPhase::Undefined));
@@ -1682,8 +1672,12 @@ impl<SP: Deref> Channel<SP> where
16821672
let _res = self.phase_to_splice(post_chan)?;
16831673

16841674
if let ChannelPhase::RefundingV2(chan) = &mut self.phase {
1685-
let splice_ack_msg = chan.post_pending.splice_init(msg, signer_provider, entropy_source, our_node_id, logger)?;
1686-
Ok(splice_ack_msg)
1675+
if let Some(ref mut post_pending) = &mut chan.post_pending {
1676+
let splice_ack_msg = post_pending.splice_init(msg, signer_provider, entropy_source, our_node_id, logger)?;
1677+
Ok(splice_ack_msg)
1678+
} else {
1679+
Err(ChannelError::Warn("Internal error: splicing channel is not negotiating after splice_init".to_owned()))
1680+
}
16871681
} else {
16881682
unreachable!("Must have been transitioned to RefundingV2 in above call if successful");
16891683
}
@@ -1721,8 +1715,12 @@ impl<SP: Deref> Channel<SP> where
17211715
let _res = self.phase_to_splice(post_chan)?;
17221716

17231717
if let ChannelPhase::RefundingV2(chan) = &mut self.phase {
1724-
let tx_msg_opt = chan.post_pending.splice_ack(msg, pending_splice.our_funding_contribution, signer_provider, entropy_source, our_node_id, logger)?;
1725-
Ok(tx_msg_opt)
1718+
if let Some(post_pending) = &mut chan.post_pending {
1719+
let tx_msg_opt = post_pending.splice_ack(msg, pending_splice.our_funding_contribution, signer_provider, entropy_source, our_node_id, logger)?;
1720+
Ok(tx_msg_opt)
1721+
} else {
1722+
Err(ChannelError::Warn("Internal error: splicing channel is not negotiating after splice_ack".to_owned()))
1723+
}
17261724
} else {
17271725
unreachable!("Must have been transitioned to RefundingV2 in above call if successful");
17281726
}
@@ -1784,17 +1782,104 @@ where
17841782
#[cfg(splicing)]
17851783
pub(super) struct SplicingChannel<SP: Deref> where SP::Target: SignerProvider {
17861784
pub pre_funded: FundedChannel<SP>,
1787-
pub post_pending: PendingV2Channel<SP>,
1788-
// pub post_funded: Option<FundedChannel<SP>>,
1785+
pub post_pending: Option<PendingV2Channel<SP>>,
1786+
pub post_funded: Option<FundedChannel<SP>>,
17891787
}
17901788

17911789
#[cfg(splicing)]
17921790
impl<SP: Deref> SplicingChannel<SP> where SP::Target: SignerProvider {
17931791
pub(super) fn new(pre_funded: FundedChannel<SP>, post_pending: PendingV2Channel<SP>) -> Self {
17941792
Self {
17951793
pre_funded,
1796-
post_pending,
1797-
// post_funded: None,
1794+
post_pending: Some(post_pending),
1795+
post_funded: None,
1796+
}
1797+
}
1798+
1799+
pub(super) fn context(&self) -> &ChannelContext<SP> {
1800+
// If post is funded, use that, otherwise use pre
1801+
if let Some(ref post_funded) = &self.post_funded {
1802+
&post_funded.context
1803+
} else {
1804+
&self.pre_funded.context
1805+
}
1806+
}
1807+
1808+
pub(super) fn context_mut(&mut self) -> &mut ChannelContext<SP> {
1809+
// If post is funded, use that, otherwise use pre
1810+
if let Some(ref mut post_funded) = &mut self.post_funded {
1811+
&mut post_funded.context
1812+
} else {
1813+
&mut self.pre_funded.context
1814+
}
1815+
}
1816+
1817+
pub(super) fn funding(&self) -> &FundingScope {
1818+
// If post is funded, use that, otherwise use pre
1819+
if let Some(ref post_funded) = &self.post_funded {
1820+
&post_funded.funding
1821+
} else {
1822+
&self.pre_funded.funding
1823+
}
1824+
}
1825+
1826+
#[cfg(any(test, feature = "_externalize_tests"))]
1827+
pub(super) fn funding_mut(&mut self) -> &mut FundingScope {
1828+
// If post is funded, use that, otherwise use pre
1829+
if let Some(ref mut post_funded) = &mut self.post_funded {
1830+
&mut post_funded.funding
1831+
} else {
1832+
&mut self.pre_funded.funding
1833+
}
1834+
}
1835+
1836+
pub(super) fn funding_and_context_mut(&mut self) -> (&FundingScope, &mut ChannelContext<SP>) {
1837+
// If post is funded, use that, otherwise use pre
1838+
if let Some(ref mut post_funded) = &mut self.post_funded {
1839+
(&mut post_funded.funding, &mut post_funded.context)
1840+
} else {
1841+
(&mut self.pre_funded.funding, &mut self.pre_funded.context)
1842+
}
1843+
}
1844+
1845+
pub(super) fn funding_tx_constructed<L: Deref>(
1846+
&mut self, counterparty_node_id: &PublicKey, signing_session: InteractiveTxSigningSession, logger: &L,
1847+
) -> Result<(msgs::CommitmentSigned, Option<Event>), ChannelError> where L::Target: Logger {
1848+
if let Some(mut post_pending) = self.post_pending.take() {
1849+
let logger = WithChannelContext::from(logger, &post_pending.context, None);
1850+
let res = post_pending.funding_tx_constructed(counterparty_node_id, signing_session, &&logger)?;
1851+
1852+
// Promote pending channel to Funded
1853+
let holder_commitment_point = match post_pending.unfunded_context.holder_commitment_point {
1854+
Some(point) => point,
1855+
None => {
1856+
let channel_id = self.context().channel_id();
1857+
// TODO(dual_funding): Add async signing support.
1858+
return Err( ChannelError::close(format!(
1859+
"Expected to have holder commitment points available upon finishing interactive tx construction for channel {}",
1860+
channel_id,
1861+
)));
1862+
}
1863+
};
1864+
let funded_channel = FundedChannel {
1865+
funding: post_pending.funding,
1866+
context: post_pending.context,
1867+
interactive_tx_signing_session: post_pending.interactive_tx_signing_session,
1868+
holder_commitment_point,
1869+
is_v2_established: true,
1870+
#[cfg(splicing)]
1871+
pending_splice_pre: None,
1872+
#[cfg(splicing)]
1873+
pending_splice_post: post_pending.pending_splice_post,
1874+
};
1875+
self.post_funded = Some(funded_channel);
1876+
self.post_pending = None;
1877+
1878+
Ok(res)
1879+
} else {
1880+
Err(ChannelError::Warn(
1881+
"Got a tx_complete message with no interactive transaction construction expected or in-progress".to_owned()
1882+
))
17981883
}
17991884
}
18001885
}
@@ -2692,6 +2777,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
26922777
let transaction_number = self.unfunded_context.transaction_number();
26932778
let is_splice_pending = self.is_splice_pending();
26942779

2780+
// Find the funding output
26952781
let mut output_index = None;
26962782
let expected_spk = self.funding.get_funding_redeemscript().to_p2wsh();
26972783
for (idx, outp) in signing_session.unsigned_tx.outputs().enumerate() {

0 commit comments

Comments
 (0)