@@ -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.
@@ -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,
@@ -4214,6 +4221,7 @@ pub(super) struct DualFundingChannelContext {
4214
4221
pub(super) struct Channel<SP: Deref> where SP::Target: SignerProvider {
4215
4222
pub context: ChannelContext<SP>,
4216
4223
pub interactive_tx_signing_session: Option<InteractiveTxSigningSession>,
4224
+ holder_commitment_point: HolderCommitmentPoint,
4217
4225
}
4218
4226
4219
4227
#[cfg(any(test, fuzzing))]
@@ -8297,28 +8305,31 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
8297
8305
let holder_signer = signer_provider.derive_channel_signer(channel_value_satoshis, channel_keys_id);
8298
8306
let pubkeys = holder_signer.pubkeys().clone();
8299
8307
8300
- let chan = Self {
8301
- context: ChannelContext::new_for_outbound_channel(
8302
- fee_estimator,
8303
- entropy_source,
8304
- signer_provider,
8305
- counterparty_node_id,
8306
- their_features,
8307
- channel_value_satoshis,
8308
- push_msat,
8309
- user_id,
8310
- config,
8311
- current_chain_height,
8312
- outbound_scid_alias,
8313
- temporary_channel_id,
8314
- holder_selected_channel_reserve_satoshis,
8315
- channel_keys_id,
8316
- holder_signer,
8317
- pubkeys,
8318
- logger,
8319
- )?,
8320
- unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 }
8308
+ let context = ChannelContext::new_for_outbound_channel(
8309
+ fee_estimator,
8310
+ entropy_source,
8311
+ signer_provider,
8312
+ counterparty_node_id,
8313
+ their_features,
8314
+ channel_value_satoshis,
8315
+ push_msat,
8316
+ user_id,
8317
+ config,
8318
+ current_chain_height,
8319
+ outbound_scid_alias,
8320
+ temporary_channel_id,
8321
+ holder_selected_channel_reserve_satoshis,
8322
+ channel_keys_id,
8323
+ holder_signer,
8324
+ pubkeys,
8325
+ logger,
8326
+ )?;
8327
+ let unfunded_context = UnfundedChannelContext {
8328
+ unfunded_channel_age_ticks: 0,
8329
+ holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
8321
8330
};
8331
+
8332
+ let chan = Self { context, unfunded_context };
8322
8333
Ok(chan)
8323
8334
}
8324
8335
@@ -8510,9 +8521,11 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
8510
8521
8511
8522
log_info!(logger, "Received funding_signed from peer for channel {}", &self.context.channel_id());
8512
8523
8524
+ let holder_commitment_point = self.context.holder_commitment_point;
8513
8525
let mut channel = Channel {
8514
8526
context: self.context,
8515
8527
interactive_tx_signing_session: None,
8528
+ holder_commitment_point,
8516
8529
};
8517
8530
8518
8531
let need_channel_ready = channel.check_get_channel_ready(0, logger).is_some();
@@ -8600,29 +8613,31 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
8600
8613
htlc_basepoint: HtlcBasepoint::from(msg.common_fields.htlc_basepoint)
8601
8614
};
8602
8615
8603
- let chan = Self {
8604
- context: ChannelContext::new_for_inbound_channel(
8605
- fee_estimator,
8606
- entropy_source,
8607
- signer_provider,
8608
- counterparty_node_id,
8609
- their_features,
8610
- user_id,
8611
- config,
8612
- current_chain_height,
8613
- &&logger,
8614
- is_0conf,
8615
- 0,
8616
-
8617
- counterparty_pubkeys,
8618
- channel_type,
8619
- holder_selected_channel_reserve_satoshis,
8620
- msg.channel_reserve_satoshis,
8621
- msg.push_msat,
8622
- msg.common_fields.clone(),
8623
- )?,
8624
- unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
8616
+ let context = ChannelContext::new_for_inbound_channel(
8617
+ fee_estimator,
8618
+ entropy_source,
8619
+ signer_provider,
8620
+ counterparty_node_id,
8621
+ their_features,
8622
+ user_id,
8623
+ config,
8624
+ current_chain_height,
8625
+ &&logger,
8626
+ is_0conf,
8627
+ 0,
8628
+
8629
+ counterparty_pubkeys,
8630
+ channel_type,
8631
+ holder_selected_channel_reserve_satoshis,
8632
+ msg.channel_reserve_satoshis,
8633
+ msg.push_msat,
8634
+ msg.common_fields.clone(),
8635
+ )?;
8636
+ let unfunded_context = UnfundedChannelContext {
8637
+ unfunded_channel_age_ticks: 0,
8638
+ holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
8625
8639
};
8640
+ let chan = Self { context, unfunded_context };
8626
8641
Ok(chan)
8627
8642
}
8628
8643
@@ -8735,9 +8750,11 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
8735
8750
8736
8751
// Promote the channel to a full-fledged one now that we have updated the state and have a
8737
8752
// `ChannelMonitor`.
8753
+ let holder_commitment_point = self.context.holder_commitment_point;
8738
8754
let mut channel = Channel {
8739
8755
context: self.context,
8740
8756
interactive_tx_signing_session: None,
8757
+ holder_commitment_point,
8741
8758
};
8742
8759
let need_channel_ready = channel.check_get_channel_ready(0, logger).is_some();
8743
8760
channel.monitor_updating_paused(false, false, need_channel_ready, Vec::new(), Vec::new(), Vec::new());
@@ -8784,27 +8801,32 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
8784
8801
"Provided current chain height of {} doesn't make sense for a height-based timelock for the funding transaction",
8785
8802
current_chain_height) })?;
8786
8803
8804
+ let context = ChannelContext::new_for_outbound_channel(
8805
+ fee_estimator,
8806
+ entropy_source,
8807
+ signer_provider,
8808
+ counterparty_node_id,
8809
+ their_features,
8810
+ funding_satoshis,
8811
+ 0,
8812
+ user_id,
8813
+ config,
8814
+ current_chain_height,
8815
+ outbound_scid_alias,
8816
+ temporary_channel_id,
8817
+ holder_selected_channel_reserve_satoshis,
8818
+ channel_keys_id,
8819
+ holder_signer,
8820
+ pubkeys,
8821
+ logger,
8822
+ )?;
8823
+ let unfunded_context = UnfundedChannelContext {
8824
+ unfunded_channel_age_ticks: 0,
8825
+ holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
8826
+ };
8787
8827
let chan = Self {
8788
- context: ChannelContext::new_for_outbound_channel(
8789
- fee_estimator,
8790
- entropy_source,
8791
- signer_provider,
8792
- counterparty_node_id,
8793
- their_features,
8794
- funding_satoshis,
8795
- 0,
8796
- user_id,
8797
- config,
8798
- current_chain_height,
8799
- outbound_scid_alias,
8800
- temporary_channel_id,
8801
- holder_selected_channel_reserve_satoshis,
8802
- channel_keys_id,
8803
- holder_signer,
8804
- pubkeys,
8805
- logger,
8806
- )?,
8807
- unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 },
8828
+ context,
8829
+ unfunded_context,
8808
8830
dual_funding_context: DualFundingChannelContext {
8809
8831
our_funding_satoshis: funding_satoshis,
8810
8832
funding_tx_locktime,
@@ -8880,9 +8902,13 @@ impl<SP: Deref> OutboundV2Channel<SP> where SP::Target: SignerProvider {
8880
8902
}
8881
8903
8882
8904
pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
8905
+ let holder_commitment_point = self.unfunded_context.holder_commitment_point.ok_or(ChannelError::close(
8906
+ format!("Expected to have holder commitment points available upon finishing interactive tx construction for channel {}",
8907
+ self.context.channel_id())))?;
8883
8908
let channel = Channel {
8884
8909
context: self.context,
8885
8910
interactive_tx_signing_session: Some(signing_session),
8911
+ holder_commitment_point,
8886
8912
};
8887
8913
8888
8914
Ok(channel)
@@ -8993,11 +9019,15 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
8993
9019
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }
8994
9020
)))?);
8995
9021
9022
+ let unfunded_context = UnfundedChannelContext {
9023
+ unfunded_channel_age_ticks: 0,
9024
+ holder_commitment_point: HolderCommitmentPoint::new(&context.holder_signer, &context.secp_ctx),
9025
+ };
8996
9026
Ok(Self {
8997
9027
context,
8998
9028
dual_funding_context,
8999
9029
interactive_tx_constructor,
9000
- unfunded_context: UnfundedChannelContext { unfunded_channel_age_ticks: 0 } ,
9030
+ unfunded_context,
9001
9031
})
9002
9032
}
9003
9033
@@ -9074,9 +9104,13 @@ impl<SP: Deref> InboundV2Channel<SP> where SP::Target: SignerProvider {
9074
9104
}
9075
9105
9076
9106
pub fn into_channel(self, signing_session: InteractiveTxSigningSession) -> Result<Channel<SP>, ChannelError>{
9107
+ let holder_commitment_point = self.unfunded_context.holder_commitment_point.ok_or(ChannelError::close(
9108
+ format!("Expected to have holder commitment points available upon finishing interactive tx construction for channel {}",
9109
+ self.context.channel_id())))?;
9077
9110
let channel = Channel {
9078
9111
context: self.context,
9079
9112
interactive_tx_signing_session: Some(signing_session),
9113
+ holder_commitment_point,
9080
9114
};
9081
9115
9082
9116
Ok(channel)
@@ -10157,6 +10191,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
10157
10191
next_funding_txid: None,
10158
10192
},
10159
10193
interactive_tx_signing_session: None,
10194
+ holder_commitment_point,
10160
10195
})
10161
10196
}
10162
10197
}
0 commit comments