@@ -954,29 +954,27 @@ pub(crate) struct ShutdownResult {
954
954
/// commitment points from our signer.
955
955
#[derive(Debug, Copy, Clone)]
956
956
enum HolderCommitmentPoint {
957
- // TODO: add a variant for before our first commitment point is retrieved
958
957
/// We've advanced our commitment number and are waiting on the next commitment point.
959
- /// Until the `get_per_commitment_point` signer method becomes async, this variant
960
- /// will not be used.
958
+ ///
959
+ /// We should retry advancing to `Available` via `try_resolve_pending` once our
960
+ /// signer is ready to provide the next commitment point.
961
961
PendingNext { transaction_number: u64, current: PublicKey },
962
- /// Our current commitment point is ready, we've cached our next point,
963
- /// and we are not pending a new one.
962
+ /// Our current commitment point is ready and we've cached our next point.
964
963
Available { transaction_number: u64, current: PublicKey, next: PublicKey },
965
964
}
966
965
967
966
impl HolderCommitmentPoint {
968
- pub fn new<SP: Deref>(signer: &ChannelSignerType<SP>, secp_ctx: &Secp256k1<secp256k1::All>) -> Self
967
+ pub fn new<SP: Deref>(signer: &ChannelSignerType<SP>, secp_ctx: &Secp256k1<secp256k1::All>) -> Option< Self>
969
968
where SP::Target: SignerProvider
970
969
{
971
- HolderCommitmentPoint::Available {
972
- transaction_number: INITIAL_COMMITMENT_NUMBER,
973
- // TODO(async_signing): remove this expect with the Uninitialized variant
974
- current: signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER, secp_ctx)
975
- .expect("Signer must be able to provide initial commitment point"),
976
- // TODO(async_signing): remove this expect with the Uninitialized variant
977
- next: signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, secp_ctx)
978
- .expect("Signer must be able to provide second commitment point"),
979
- }
970
+ let current = signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER, secp_ctx).ok()?;
971
+ let next = signer.as_ref().get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, secp_ctx).ok();
972
+ let point = if let Some(next) = next {
973
+ HolderCommitmentPoint::Available { transaction_number: INITIAL_COMMITMENT_NUMBER, current, next }
974
+ } else {
975
+ HolderCommitmentPoint::PendingNext { transaction_number: INITIAL_COMMITMENT_NUMBER, current }
976
+ };
977
+ Some(point)
980
978
}
981
979
982
980
pub fn is_available(&self) -> bool {
@@ -1169,6 +1167,8 @@ pub(super) struct UnfundedChannelContext {
1169
1167
/// This is so that we don't keep channels around that haven't progressed to a funded state
1170
1168
/// in a timely manner.
1171
1169
unfunded_channel_age_ticks: usize,
1170
+ /// Tracks the commitment number and commitment point before the channel is funded.
1171
+ holder_commitment_point: Option<HolderCommitmentPoint>,
1172
1172
}
1173
1173
1174
1174
impl UnfundedChannelContext {
@@ -1180,6 +1180,11 @@ impl UnfundedChannelContext {
1180
1180
self.unfunded_channel_age_ticks += 1;
1181
1181
self.unfunded_channel_age_ticks >= UNFUNDED_CHANNEL_AGE_LIMIT_TICKS
1182
1182
}
1183
+
1184
+ fn transaction_number(&self) -> u64 {
1185
+ self.holder_commitment_point.as_ref().map(|point| point.transaction_number())
1186
+ .unwrap_or(INITIAL_COMMITMENT_NUMBER)
1187
+ }
1183
1188
}
1184
1189
1185
1190
/// Contains everything about the channel including state, and various flags.
@@ -1501,7 +1506,7 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
1501
1506
// The `next_funding_txid` field allows peers to finalize the signing steps of an interactive
1502
1507
// transaction construction, or safely abort that transaction if it was not signed by one of the
1503
1508
// peers, who has thus already removed it from its state.
1504
- //
1509
+ //
1505
1510
// If we've sent `commtiment_signed` for an interactively constructed transaction
1506
1511
// during a signing session, but have not received `tx_signatures` we MUST set `next_funding_txid`
1507
1512
// to the txid of that interactive transaction, else we MUST NOT set it.
@@ -2058,7 +2063,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
2058
2063
let value_to_self_msat = our_funding_satoshis * 1000 + msg_push_msat;
2059
2064
2060
2065
let holder_signer = ChannelSignerType::Ecdsa(holder_signer);
2061
- let holder_commitment_point = HolderCommitmentPoint::new(&holder_signer, &secp_ctx);
2066
+ // Unwrap here since it gets removed in the next commit
2067
+ let holder_commitment_point = HolderCommitmentPoint::new(&holder_signer, &secp_ctx).unwrap();
2062
2068
2063
2069
// TODO(dual_funding): Checks for `funding_feerate_sat_per_1000_weight`?
2064
2070
@@ -2297,7 +2303,8 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
2297
2303
let temporary_channel_id = temporary_channel_id.unwrap_or_else(|| ChannelId::temporary_from_entropy_source(entropy_source));
2298
2304
2299
2305
let holder_signer = ChannelSignerType::Ecdsa(holder_signer);
2300
- let holder_commitment_point = HolderCommitmentPoint::new(&holder_signer, &secp_ctx);
2306
+ // Unwrap here since it gets removed in the next commit
2307
+ let holder_commitment_point = HolderCommitmentPoint::new(&holder_signer, &secp_ctx).unwrap();
2301
2308
2302
2309
Ok(Self {
2303
2310
user_id,
@@ -4206,6 +4213,7 @@ pub(super) struct DualFundingChannelContext {
4206
4213
pub(super) struct Channel<SP: Deref> where SP::Target: SignerProvider {
4207
4214
pub context: ChannelContext<SP>,
4208
4215
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
4216
+ holder_commitment_point: HolderCommitmentPoint,
4209
4217
}
4210
4218
4211
4219
#[cfg(any(test, fuzzing))]
@@ -8267,28 +8275,31 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
8267
8275
let holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
8268
8276
let pubkeys = holder_signer.pubkeys().clone();
8269
8277
8270
- let chan = Self {
8271
- context: ChannelContext::new_for_outbound_channel(
8272
- fee_estimator,
8273
- entropy_source,
8274
- signer_provider,
8275
- counterparty_node_id,
8276
- their_features,
8277
- channel_value_satoshis,
8278
- push_msat,
8279
- user_id,
8280
- config,
8281
- current_chain_height,
8282
- outbound_scid_alias,
8283
- temporary_channel_id,
8284
- holder_selected_channel_reserve_satoshis,
8285
- channel_keys_id,
8286
- holder_signer,
8287
- pubkeys,
8288
- logger,
8289
- )?,
8290
- unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 }
8278
+ let context = ChannelContext::new_for_outbound_channel(
8279
+ fee_estimator,
8280
+ entropy_source,
8281
+ signer_provider,
8282
+ counterparty_node_id,
8283
+ their_features,
8284
+ channel_value_satoshis,
8285
+ push_msat,
8286
+ user_id,
8287
+ config,
8288
+ current_chain_height,
8289
+ outbound_scid_alias,
8290
+ temporary_channel_id,
8291
+ holder_selected_channel_reserve_satoshis,
8292
+ channel_keys_id,
8293
+ holder_signer,
8294
+ pubkeys,
8295
+ logger,
8296
+ )?;
8297
+ let unfunded_context = UnfundedChannelContext {
8298
+ unfunded_channel_age_ticks: 0,
8299
+ holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
8291
8300
};
8301
+
8302
+ let chan = Self { context, unfunded_context };
8292
8303
Ok(chan)
8293
8304
}
8294
8305
@@ -8480,9 +8491,11 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
8480
8491
8481
8492
log_info!(logger, "Received funding_signed from peer for channel {}", &self.context.channel_id());
8482
8493
8494
+ let holder_commitment_point = self.context.holder_commitment_point;
8483
8495
let mut channel = Channel {
8484
8496
context: self.context,
8485
8497
interactive_tx_signing_session: None,
8498
+ holder_commitment_point,
8486
8499
};
8487
8500
8488
8501
let need_channel_ready = channel.check_get_channel_ready(0, logger).is_some();
@@ -8570,29 +8583,31 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
8570
8583
htlc_basepoint: HtlcBasepoint::from(msg.common_fields.htlc_basepoint)
8571
8584
};
8572
8585
8573
- let chan = Self {
8574
- context: ChannelContext::new_for_inbound_channel(
8575
- fee_estimator,
8576
- entropy_source,
8577
- signer_provider,
8578
- counterparty_node_id,
8579
- their_features,
8580
- user_id,
8581
- config,
8582
- current_chain_height,
8583
- &&logger,
8584
- is_0conf,
8585
- 0,
8586
-
8587
- counterparty_pubkeys,
8588
- channel_type,
8589
- holder_selected_channel_reserve_satoshis,
8590
- msg.channel_reserve_satoshis,
8591
- msg.push_msat,
8592
- msg.common_fields.clone(),
8593
- )?,
8594
- unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
8586
+ let context = ChannelContext::new_for_inbound_channel(
8587
+ fee_estimator,
8588
+ entropy_source,
8589
+ signer_provider,
8590
+ counterparty_node_id,
8591
+ their_features,
8592
+ user_id,
8593
+ config,
8594
+ current_chain_height,
8595
+ &&logger,
8596
+ is_0conf,
8597
+ 0,
8598
+
8599
+ counterparty_pubkeys,
8600
+ channel_type,
8601
+ holder_selected_channel_reserve_satoshis,
8602
+ msg.channel_reserve_satoshis,
8603
+ msg.push_msat,
8604
+ msg.common_fields.clone(),
8605
+ )?;
8606
+ let unfunded_context = UnfundedChannelContext {
8607
+ unfunded_channel_age_ticks: 0,
8608
+ holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
8595
8609
};
8610
+ let chan = Self { context, unfunded_context };
8596
8611
Ok(chan)
8597
8612
}
8598
8613
@@ -8705,9 +8720,11 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
8705
8720
8706
8721
// Promote the channel to a full-fledged one now that we have updated the state and have a
8707
8722
// `ChannelMonitor`.
8723
+ let holder_commitment_point = self.context.holder_commitment_point;
8708
8724
let mut channel = Channel {
8709
8725
context: self.context,
8710
8726
interactive_tx_signing_session: None,
8727
+ holder_commitment_point,
8711
8728
};
8712
8729
let need_channel_ready = channel.check_get_channel_ready(0, logger).is_some();
8713
8730
channel.monitor_updating_paused(false, false, need_channel_ready, Vec::new(), Vec::new(), Vec::new());
@@ -8754,27 +8771,32 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
8754
8771
"Provided current chain height of {} doesn't make sense for a height-based timelock for the funding transaction",
8755
8772
current_chain_height) })?;
8756
8773
8774
+ let context = ChannelContext::new_for_outbound_channel(
8775
+ fee_estimator,
8776
+ entropy_source,
8777
+ signer_provider,
8778
+ counterparty_node_id,
8779
+ their_features,
8780
+ funding_satoshis,
8781
+ 0,
8782
+ user_id,
8783
+ config,
8784
+ current_chain_height,
8785
+ outbound_scid_alias,
8786
+ temporary_channel_id,
8787
+ holder_selected_channel_reserve_satoshis,
8788
+ channel_keys_id,
8789
+ holder_signer,
8790
+ pubkeys,
8791
+ logger,
8792
+ )?;
8793
+ let unfunded_context = UnfundedChannelContext {
8794
+ unfunded_channel_age_ticks: 0,
8795
+ holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
8796
+ };
8757
8797
let chan = Self {
8758
- context: ChannelContext::new_for_outbound_channel(
8759
- fee_estimator,
8760
- entropy_source,
8761
- signer_provider,
8762
- counterparty_node_id,
8763
- their_features,
8764
- funding_satoshis,
8765
- 0,
8766
- user_id,
8767
- config,
8768
- current_chain_height,
8769
- outbound_scid_alias,
8770
- temporary_channel_id,
8771
- holder_selected_channel_reserve_satoshis,
8772
- channel_keys_id,
8773
- holder_signer,
8774
- pubkeys,
8775
- logger,
8776
- )?,
8777
- unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
8798
+ context,
8799
+ unfunded_context,
8778
8800
dual_funding_context: DualFundingChannelContext {
8779
8801
our_funding_satoshis: funding_satoshis,
8780
8802
funding_tx_locktime,
@@ -8850,9 +8872,13 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
8850
8872
}
8851
8873
8852
8874
pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
8875
+ let holder_commitment_point = self.unfunded_context.holder_commitment_point.ok_or(ChannelError::close(
8876
+ format!("Expected to have holder commitment points available upon finishing interactive tx construction for channel {}",
8877
+ self.context.channel_id())))?;
8853
8878
let channel = Channel {
8854
8879
context: self.context,
8855
8880
interactive_tx_signing_session: Some(signing_session),
8881
+ holder_commitment_point,
8856
8882
};
8857
8883
8858
8884
Ok(channel)
@@ -8963,11 +8989,15 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
8963
8989
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }
8964
8990
)))?);
8965
8991
8992
+ let unfunded_context = UnfundedChannelContext {
8993
+ unfunded_channel_age_ticks: 0,
8994
+ holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
8995
+ };
8966
8996
Ok(Self {
8967
8997
context,
8968
8998
dual_funding_context,
8969
8999
interactive_tx_constructor,
8970
- unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 } ,
9000
+ unfunded_context,
8971
9001
})
8972
9002
}
8973
9003
@@ -9044,9 +9074,13 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
9044
9074
}
9045
9075
9046
9076
pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
9077
+ let holder_commitment_point = self.unfunded_context.holder_commitment_point.ok_or(ChannelError::close(
9078
+ format!("Expected to have holder commitment points available upon finishing interactive tx construction for channel {}",
9079
+ self.context.channel_id())))?;
9047
9080
let channel = Channel {
9048
9081
context: self.context,
9049
9082
interactive_tx_signing_session: Some(signing_session),
9083
+ holder_commitment_point,
9050
9084
};
9051
9085
9052
9086
Ok(channel)
@@ -10125,6 +10159,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
10125
10159
next_funding_txid,
10126
10160
},
10127
10161
interactive_tx_signing_session: None,
10162
+ holder_commitment_point,
10128
10163
})
10129
10164
}
10130
10165
}
0 commit comments