Skip to content

Commit 73dc1ff

Browse files
committed
Store previous HolderCommitmentPoint
When splicing a channel, sending and receiving the initial commitment_signed message should use the previous commitment point rather then the current one. Store this in FundedChannel whenever the commitment point is advanced and re-derive it using the signer upon restart.
1 parent 0160e54 commit 73dc1ff

File tree

2 files changed

+83
-58
lines changed

2 files changed

+83
-58
lines changed

lightning/src/ln/async_signer_tests.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,10 @@ fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack(
350350
assert!(events.is_empty(), "expected no message, got {}", events.len());
351351
}
352352
}
353+
354+
// Enable SignerOp::GetPerCommitmentPoint since testing the node serialization round-trip
355+
// involves using the signer to get the previous holder commitment point.
356+
dst.enable_channel_signer_op(&src_node_id, &chan_id, SignerOp::GetPerCommitmentPoint);
353357
}
354358

355359
#[test]

lightning/src/ln/channel.rs

Lines changed: 79 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,32 +1310,31 @@ impl HolderCommitmentPoint {
13101310
}
13111311
}
13121312

1313-
/// If we are not pending the next commitment point, this method advances the commitment number
1314-
/// and requests the next commitment point from the signer. Returns `Ok` if we were able to
1315-
/// advance our commitment number (even if we are still pending the next commitment point).
1313+
/// Returns the next [`HolderCommitmentPoint`] if it is available (i.e., was previously obtained
1314+
/// from `signer` and cached), leaving the callee unchanged.
13161315
///
1317-
/// If our signer is not ready to provide the next commitment point, we will advance but won't
1318-
/// be able to advance again immediately. Instead, this hould be tried again later in
1319-
/// `signer_unblocked` via `try_resolve_pending`.
1316+
/// Otherwise, returns an `Err` indicating that the signer wasn't previously ready and that the
1317+
/// caller must invoke `try_resolve_pending` once it is.
13201318
///
1321-
/// If our signer is ready to provide the next commitment point, the next call to `advance` will
1322-
/// succeed.
1319+
/// Attempts to resolve the next point on the *returned* [`HolderCommitmentPoint`], if `signer`
1320+
/// is ready, allowing *it* to be advanced later. Otherwise, `try_resolve_pending` must be
1321+
/// called on it, typically via [`Channel::signer_maybe_unblocked`].
13231322
pub fn advance<SP: Deref, L: Deref>(
1324-
&mut self, signer: &ChannelSignerType<SP>, secp_ctx: &Secp256k1<secp256k1::All>, logger: &L,
1325-
) -> Result<(), ()>
1323+
&self, signer: &ChannelSignerType<SP>, secp_ctx: &Secp256k1<secp256k1::All>, logger: &L,
1324+
) -> Result<HolderCommitmentPoint, ()>
13261325
where
13271326
SP::Target: SignerProvider,
13281327
L::Target: Logger,
13291328
{
13301329
if let Some(next_point) = self.next_point {
1331-
*self = Self {
1330+
let mut advanced_point = Self {
13321331
transaction_number: self.transaction_number - 1,
13331332
point: next_point,
13341333
next_point: None,
13351334
};
13361335

1337-
self.try_resolve_pending(signer, secp_ctx, logger);
1338-
return Ok(());
1336+
advanced_point.try_resolve_pending(signer, secp_ctx, logger);
1337+
return Ok(advanced_point);
13391338
}
13401339
Err(())
13411340
}
@@ -1851,6 +1850,7 @@ where
18511850
pending_funding: vec![],
18521851
context: chan.context,
18531852
interactive_tx_signing_session: chan.interactive_tx_signing_session,
1853+
previous_holder_commitment_point: None,
18541854
next_holder_commitment_point: initial_holder_commitment_point,
18551855
#[cfg(splicing)]
18561856
pending_splice: None,
@@ -2766,9 +2766,9 @@ where
27662766

27672767
#[rustfmt::skip]
27682768
fn initial_commitment_signed<L: Deref>(
2769-
&mut self, channel_id: ChannelId, counterparty_signature: Signature, holder_commitment_point: &mut HolderCommitmentPoint,
2769+
&mut self, channel_id: ChannelId, counterparty_signature: Signature, holder_commitment_point: &HolderCommitmentPoint,
27702770
best_block: BestBlock, signer_provider: &SP, logger: &L,
2771-
) -> Result<(ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>, CommitmentTransaction), ChannelError>
2771+
) -> Result<(ChannelMonitor<<SP::Target as SignerProvider>::EcdsaSigner>, CommitmentTransaction, HolderCommitmentPoint), ChannelError>
27722772
where
27732773
L::Target: Logger
27742774
{
@@ -2824,14 +2824,16 @@ where
28242824
context.channel_state = ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::new());
28252825
}
28262826
}
2827-
if holder_commitment_point.advance(&context.holder_signer, &context.secp_ctx, logger).is_err() {
2828-
// We only fail to advance our commitment point/number if we're currently
2829-
// waiting for our signer to unblock and provide a commitment point.
2830-
// We cannot send accept_channel/open_channel before this has occurred, so if we
2831-
// err here by the time we receive funding_created/funding_signed, something has gone wrong.
2832-
debug_assert!(false, "We should be ready to advance our commitment point by the time we receive {}", self.received_msg());
2833-
return Err(ChannelError::close("Failed to advance holder commitment point".to_owned()));
2834-
}
2827+
let advanced_holder_commitment_point = holder_commitment_point
2828+
.advance(&context.holder_signer, &context.secp_ctx, logger)
2829+
.map_err(|()| {
2830+
// We only fail to advance our commitment point/number if we're currently
2831+
// waiting for our signer to unblock and provide a commitment point.
2832+
// We cannot send accept_channel/open_channel before this has occurred, so if we
2833+
// err here by the time we receive funding_created/funding_signed, something has gone wrong.
2834+
debug_assert!(false, "We should be ready to advance our commitment point by the time we receive {}", self.received_msg());
2835+
ChannelError::close("Failed to advance holder commitment point".to_owned())
2836+
})?;
28352837

28362838
let context = self.context();
28372839
let funding = self.funding();
@@ -2852,7 +2854,7 @@ where
28522854

28532855
self.context_mut().cur_counterparty_commitment_transaction_number -= 1;
28542856

2855-
Ok((channel_monitor, counterparty_initial_commitment_tx))
2857+
Ok((channel_monitor, counterparty_initial_commitment_tx, advanced_holder_commitment_point))
28562858
}
28572859

28582860
fn is_v2_established(&self) -> bool;
@@ -6066,6 +6068,9 @@ where
60666068
/// This field is cleared once our counterparty sends a `channel_ready`.
60676069
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
60686070

6071+
/// The commitment point used for the previous commitment transaction.
6072+
previous_holder_commitment_point: Option<HolderCommitmentPoint>,
6073+
60696074
/// The commitment point used for the next commitment transaction.
60706075
next_holder_commitment_point: HolderCommitmentPoint,
60716076

@@ -6947,12 +6952,13 @@ where
69476952
return Err(ChannelError::Close((msg.to_owned(), reason)));
69486953
}
69496954

6950-
let next_holder_commitment_point = &mut self.next_holder_commitment_point.clone();
6951-
self.context.assert_no_commitment_advancement(next_holder_commitment_point.transaction_number(), "initial commitment_signed");
6955+
let holder_commitment_point = self.next_holder_commitment_point.clone();
6956+
self.context.assert_no_commitment_advancement(holder_commitment_point.transaction_number(), "initial commitment_signed");
69526957

6953-
let (channel_monitor, _) = self.initial_commitment_signed(
6954-
self.context.channel_id(), msg.signature, next_holder_commitment_point, best_block, signer_provider, logger)?;
6955-
self.next_holder_commitment_point = *next_holder_commitment_point;
6958+
let (channel_monitor, _, next_holder_commitment_point) = self.initial_commitment_signed(
6959+
self.context.channel_id(), msg.signature, &holder_commitment_point, best_block, signer_provider, logger)?;
6960+
self.previous_holder_commitment_point = Some(holder_commitment_point);
6961+
self.next_holder_commitment_point = next_holder_commitment_point;
69566962

69576963
log_info!(logger, "Received initial commitment_signed from peer for channel {}", &self.context.channel_id());
69586964

@@ -7083,14 +7089,10 @@ where
70837089
));
70847090
}
70857091

7092+
let holder_commitment_point = &self.next_holder_commitment_point;
70867093
let update = self
70877094
.context
7088-
.validate_commitment_signed(
7089-
&self.funding,
7090-
&self.next_holder_commitment_point,
7091-
msg,
7092-
logger,
7093-
)
7095+
.validate_commitment_signed(&self.funding, holder_commitment_point, msg, logger)
70947096
.map(|(commitment_tx, htlcs_included)| {
70957097
let (nondust_htlc_sources, dust_htlcs) =
70967098
Self::get_commitment_htlc_data(&htlcs_included);
@@ -7212,23 +7214,24 @@ where
72127214
where
72137215
L::Target: Logger,
72147216
{
7215-
if self
7217+
let next_holder_commitment_point = self
72167218
.next_holder_commitment_point
72177219
.advance(&self.context.holder_signer, &self.context.secp_ctx, logger)
7218-
.is_err()
7219-
{
7220-
// We only fail to advance our commitment point/number if we're currently
7221-
// waiting for our signer to unblock and provide a commitment point.
7222-
// During post-funding channel operation, we only advance our point upon
7223-
// receiving a commitment_signed, and our counterparty cannot send us
7224-
// another commitment signed until we've provided a new commitment point
7225-
// in revoke_and_ack, which requires unblocking our signer and completing
7226-
// the advance to the next point. This should be unreachable since
7227-
// a new commitment_signed should fail at our signature checks in
7228-
// validate_commitment_signed.
7229-
debug_assert!(false, "We should be ready to advance our commitment point by the time we receive commitment_signed");
7230-
return Err(ChannelError::close("Failed to advance our commitment point".to_owned()));
7231-
}
7220+
.map_err(|()| {
7221+
// We only fail to advance our commitment point/number if we're currently
7222+
// waiting for our signer to unblock and provide a commitment point.
7223+
// During post-funding channel operation, we only advance our point upon
7224+
// receiving a commitment_signed, and our counterparty cannot send us
7225+
// another commitment signed until we've provided a new commitment point
7226+
// in revoke_and_ack, which requires unblocking our signer and completing
7227+
// the advance to the next point. This should be unreachable since
7228+
// a new commitment_signed should fail at our signature checks in
7229+
// validate_commitment_signed.
7230+
debug_assert!(false, "We should be ready to advance our commitment point by the time we receive commitment_signed");
7231+
ChannelError::close("Failed to advance our commitment point".to_owned())
7232+
})?;
7233+
self.previous_holder_commitment_point = Some(self.next_holder_commitment_point);
7234+
self.next_holder_commitment_point = next_holder_commitment_point;
72327235

72337236
// Update state now that we've passed all the can-fail calls...
72347237
let mut need_commitment = false;
@@ -12042,15 +12045,15 @@ where
1204212045
if !matches!(self.context.channel_state, ChannelState::FundingNegotiated(_)) {
1204312046
return Err((self, ChannelError::close("Received funding_signed in strange state!".to_owned())));
1204412047
}
12045-
let mut initial_holder_commitment_point = match self.unfunded_context.initial_holder_commitment_point {
12048+
let initial_holder_commitment_point = match self.unfunded_context.initial_holder_commitment_point {
1204612049
Some(point) => point,
1204712050
None => return Err((self, ChannelError::close("Received funding_signed before our first commitment point was available".to_owned()))),
1204812051
};
1204912052
self.context.assert_no_commitment_advancement(initial_holder_commitment_point.transaction_number(), "funding_signed");
1205012053

12051-
let (channel_monitor, _) = match self.initial_commitment_signed(
12054+
let (channel_monitor, _, next_holder_commitment_point) = match self.initial_commitment_signed(
1205212055
self.context.channel_id(), msg.signature,
12053-
&mut initial_holder_commitment_point, best_block, signer_provider, logger
12056+
&initial_holder_commitment_point, best_block, signer_provider, logger
1205412057
) {
1205512058
Ok(channel_monitor) => channel_monitor,
1205612059
Err(err) => return Err((self, err)),
@@ -12063,7 +12066,8 @@ where
1206312066
pending_funding: vec![],
1206412067
context: self.context,
1206512068
interactive_tx_signing_session: None,
12066-
next_holder_commitment_point: initial_holder_commitment_point,
12069+
previous_holder_commitment_point: Some(initial_holder_commitment_point),
12070+
next_holder_commitment_point,
1206712071
#[cfg(splicing)]
1206812072
pending_splice: None,
1206912073
};
@@ -12318,7 +12322,7 @@ where
1231812322
// channel.
1231912323
return Err((self, ChannelError::close("Received funding_created after we got the channel!".to_owned())));
1232012324
}
12321-
let mut initial_holder_commitment_point = match self.unfunded_context.initial_holder_commitment_point {
12325+
let initial_holder_commitment_point = match self.unfunded_context.initial_holder_commitment_point {
1232212326
Some(point) => point,
1232312327
None => return Err((self, ChannelError::close("Received funding_created before our first commitment point was available".to_owned()))),
1232412328
};
@@ -12327,9 +12331,9 @@ where
1232712331
let funding_txo = OutPoint { txid: msg.funding_txid, index: msg.funding_output_index };
1232812332
self.funding.channel_transaction_parameters.funding_outpoint = Some(funding_txo);
1232912333

12330-
let (channel_monitor, counterparty_initial_commitment_tx) = match self.initial_commitment_signed(
12334+
let (channel_monitor, counterparty_initial_commitment_tx, next_holder_commitment_point) = match self.initial_commitment_signed(
1233112335
ChannelId::v1_from_funding_outpoint(funding_txo), msg.signature,
12332-
&mut initial_holder_commitment_point, best_block, signer_provider, logger
12336+
&initial_holder_commitment_point, best_block, signer_provider, logger
1233312337
) {
1233412338
Ok(channel_monitor) => channel_monitor,
1233512339
Err(err) => return Err((self, err)),
@@ -12349,7 +12353,8 @@ where
1234912353
pending_funding: vec![],
1235012354
context: self.context,
1235112355
interactive_tx_signing_session: None,
12352-
next_holder_commitment_point: initial_holder_commitment_point,
12356+
previous_holder_commitment_point: Some(initial_holder_commitment_point),
12357+
next_holder_commitment_point,
1235312358
#[cfg(splicing)]
1235412359
pending_splice: None,
1235512360
};
@@ -13868,6 +13873,21 @@ where
1386813873
},
1386913874
};
1387013875

13876+
let previous_holder_commitment_point = {
13877+
let previous_holder_commitment_transaction_number =
13878+
next_holder_commitment_point.transaction_number() + 1;
13879+
let previous_point = holder_signer
13880+
.get_per_commitment_point(previous_holder_commitment_transaction_number, &secp_ctx)
13881+
.expect(
13882+
"Must be able to derive the previous commitment point upon channel restoration",
13883+
);
13884+
Some(HolderCommitmentPoint {
13885+
transaction_number: previous_holder_commitment_transaction_number,
13886+
point: previous_point,
13887+
next_point: Some(next_holder_commitment_point.point()),
13888+
})
13889+
};
13890+
1387113891
Ok(FundedChannel {
1387213892
funding: FundingScope {
1387313893
value_to_self_msat,
@@ -14005,6 +14025,7 @@ where
1400514025
is_holder_quiescence_initiator: None,
1400614026
},
1400714027
interactive_tx_signing_session,
14028+
previous_holder_commitment_point,
1400814029
next_holder_commitment_point,
1400914030
#[cfg(splicing)]
1401014031
pending_splice: None,

0 commit comments

Comments
 (0)