@@ -1119,6 +1119,81 @@ pub(crate) struct ShutdownResult {
1119
1119
pub(crate) channel_funding_txo: Option<OutPoint>,
1120
1120
}
1121
1121
1122
+ #[derive(Debug, Copy, Clone)]
1123
+ enum HolderCommitmentPoint {
1124
+ Uninitialized { transaction_number: u64 },
1125
+ PendingNext { transaction_number: u64, current: PublicKey },
1126
+ Available { transaction_number: u64, current: PublicKey, next: PublicKey },
1127
+ }
1128
+
1129
+ impl HolderCommitmentPoint where {
1130
+ pub fn new() -> Self {
1131
+ HolderCommitmentPoint::Uninitialized { transaction_number: INITIAL_COMMITMENT_NUMBER }
1132
+ }
1133
+
1134
+ pub fn is_available(&self) -> bool {
1135
+ if let HolderCommitmentPoint::Available { .. } = self { true } else { false }
1136
+ }
1137
+
1138
+ pub fn transaction_number(&self) -> u64 {
1139
+ match self {
1140
+ HolderCommitmentPoint::Uninitialized { transaction_number } => *transaction_number,
1141
+ HolderCommitmentPoint::PendingNext { transaction_number, .. } => *transaction_number,
1142
+ HolderCommitmentPoint::Available { transaction_number, .. } => *transaction_number,
1143
+ }
1144
+ }
1145
+
1146
+ pub fn current_point(&self) -> PublicKey {
1147
+ match self {
1148
+ HolderCommitmentPoint::Uninitialized { .. } => panic!("holder commitment is uninitialized"),
1149
+ HolderCommitmentPoint::PendingNext { current, .. } => *current,
1150
+ HolderCommitmentPoint::Available { current, .. } => *current,
1151
+ }
1152
+ }
1153
+
1154
+ pub fn next_point(&self) -> Option<PublicKey> {
1155
+ match self {
1156
+ HolderCommitmentPoint::Uninitialized { .. } => panic!("holder commitment is uninitialized"),
1157
+ HolderCommitmentPoint::PendingNext { .. } => None,
1158
+ HolderCommitmentPoint::Available { next, .. } => Some(*next),
1159
+ }
1160
+ }
1161
+
1162
+ pub fn advance<SP: Deref, L: Deref>(&self, signer: &ChannelSignerType<SP>, secp_ctx: &Secp256k1<secp256k1::All>, logger: &L) -> Self
1163
+ where SP::Target: SignerProvider, L::Target: Logger
1164
+ {
1165
+ match self {
1166
+ HolderCommitmentPoint::Available { transaction_number, next, .. } => {
1167
+ HolderCommitmentPoint::PendingNext {
1168
+ transaction_number: transaction_number - 1,
1169
+ current: *next,
1170
+ }.request_next(signer, secp_ctx, logger)
1171
+ }
1172
+ _ => panic!("Cannot advance holder commitment; there is no next point available")
1173
+ }
1174
+ }
1175
+
1176
+ pub fn request_next<SP: Deref, L: Deref>(&self, signer: &ChannelSignerType<SP>, secp_ctx: &Secp256k1<secp256k1::All>, logger: &L) -> Self
1177
+ where SP::Target: SignerProvider, L::Target: Logger
1178
+ {
1179
+ match self {
1180
+ HolderCommitmentPoint::Uninitialized { transaction_number } => {
1181
+ let current = signer.as_ref().get_per_commitment_point(*transaction_number, secp_ctx);
1182
+ log_trace!(logger, "Retrieved current per-commitment point {}", transaction_number);
1183
+ HolderCommitmentPoint::PendingNext { transaction_number: *transaction_number, current }.request_next(signer, secp_ctx, logger)
1184
+ // TODO: handle error case when get_per_commitment_point becomes async
1185
+ }
1186
+ HolderCommitmentPoint::PendingNext { transaction_number, current } => {
1187
+ let next = signer.as_ref().get_per_commitment_point(transaction_number - 1, secp_ctx);
1188
+ log_trace!(logger, "Retrieved next per-commitment point {}", transaction_number - 1);
1189
+ HolderCommitmentPoint::Available { transaction_number: *transaction_number, current: *current, next }
1190
+ // TODO: handle error case when get_per_commitment_point becomes async
1191
+ }
1192
+ HolderCommitmentPoint::Available { .. } => *self,
1193
+ }
1194
+ }
1195
+ }
1196
+
1122
1197
/// If the majority of the channels funds are to the fundee and the initiator holds only just
1123
1198
/// enough funds to cover their reserve value, channels are at risk of getting "stuck". Because the
1124
1199
/// initiator controls the feerate, if they then go to increase the channel fee, they may have no
@@ -1297,6 +1372,7 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
1297
1372
// generation start at 0 and count up...this simplifies some parts of implementation at the
1298
1373
// cost of others, but should really just be changed.
1299
1374
1375
+ holder_commitment_point: HolderCommitmentPoint,
1300
1376
cur_holder_commitment_transaction_number: u64,
1301
1377
cur_counterparty_commitment_transaction_number: u64,
1302
1378
value_to_self_msat: u64, // Excluding all pending_htlcs, fees, and anchor outputs
@@ -1739,6 +1815,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1739
1815
1740
1816
let value_to_self_msat = our_funding_satoshis * 1000 + msg_push_msat;
1741
1817
1818
+ let holder_signer = ChannelSignerType::Ecdsa(holder_signer);
1819
+ let holder_commitment_point = HolderCommitmentPoint::new().request_next(&holder_signer, &secp_ctx, &&logger);
1820
+
1742
1821
// TODO(dual_funding): Checks for `funding_feerate_sat_per_1000_weight`?
1743
1822
1744
1823
let channel_context = ChannelContext {
@@ -1764,10 +1843,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1764
1843
1765
1844
latest_monitor_update_id: 0,
1766
1845
1767
- holder_signer: ChannelSignerType::Ecdsa(holder_signer) ,
1846
+ holder_signer,
1768
1847
shutdown_scriptpubkey,
1769
1848
destination_script,
1770
1849
1850
+ holder_commitment_point,
1771
1851
cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
1772
1852
cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
1773
1853
value_to_self_msat,
@@ -1965,6 +2045,9 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1965
2045
1966
2046
let temporary_channel_id = temporary_channel_id.unwrap_or_else(|| ChannelId::temporary_from_entropy_source(entropy_source));
1967
2047
2048
+ let holder_signer = ChannelSignerType::Ecdsa(holder_signer);
2049
+ let holder_commitment_point = HolderCommitmentPoint::new().request_next(&holder_signer, &secp_ctx, logger);
2050
+
1968
2051
Ok(Self {
1969
2052
user_id,
1970
2053
@@ -1988,10 +2071,11 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
1988
2071
1989
2072
latest_monitor_update_id: 0,
1990
2073
1991
- holder_signer: ChannelSignerType::Ecdsa(holder_signer) ,
2074
+ holder_signer,
1992
2075
shutdown_scriptpubkey,
1993
2076
destination_script,
1994
2077
2078
+ holder_commitment_point,
1995
2079
cur_holder_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
1996
2080
cur_counterparty_commitment_transaction_number: INITIAL_COMMITMENT_NUMBER,
1997
2081
value_to_self_msat,
@@ -8783,6 +8867,9 @@ impl<SP: Deref> Writeable for Channel<SP> where SP::Target: SignerProvider {
8783
8867
monitor_pending_update_adds = Some(&self.context.monitor_pending_update_adds);
8784
8868
}
8785
8869
8870
+ let cur_holder_commitment_point = self.context.holder_commitment_point.current_point();
8871
+ let next_holder_commitment_point = self.context.holder_commitment_point.next_point();
8872
+
8786
8873
write_tlv_fields!(writer, {
8787
8874
(0, self.context.announcement_sigs, option),
8788
8875
// minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a
@@ -8819,7 +8906,8 @@ impl<SP: Deref> Writeable for Channel<SP> where SP::Target: SignerProvider {
8819
8906
(39, pending_outbound_blinding_points, optional_vec),
8820
8907
(41, holding_cell_blinding_points, optional_vec),
8821
8908
(43, malformed_htlcs, optional_vec), // Added in 0.0.119
8822
- // 45 and 47 are reserved for async signing
8909
+ (45, cur_holder_commitment_point, required),
8910
+ (47, next_holder_commitment_point, option),
8823
8911
(49, self.context.local_initiated_shutdown, option), // Added in 0.0.122
8824
8912
});
8825
8913
@@ -9130,6 +9218,9 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
9130
9218
let mut malformed_htlcs: Option<Vec<(u64, u16, [u8; 32])>> = None;
9131
9219
let mut monitor_pending_update_adds: Option<Vec<msgs::UpdateAddHTLC>> = None;
9132
9220
9221
+ let mut cur_holder_commitment_point_opt: Option<PublicKey> = None;
9222
+ let mut next_holder_commitment_point_opt: Option<PublicKey> = None;
9223
+
9133
9224
read_tlv_fields!(reader, {
9134
9225
(0, announcement_sigs, option),
9135
9226
(1, minimum_depth, option),
@@ -9160,7 +9251,8 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
9160
9251
(39, pending_outbound_blinding_points_opt, optional_vec),
9161
9252
(41, holding_cell_blinding_points_opt, optional_vec),
9162
9253
(43, malformed_htlcs, optional_vec), // Added in 0.0.119
9163
- // 45 and 47 are reserved for async signing
9254
+ (45, cur_holder_commitment_point_opt, option),
9255
+ (47, next_holder_commitment_point_opt, option),
9164
9256
(49, local_initiated_shutdown, option),
9165
9257
});
9166
9258
@@ -9272,6 +9364,21 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
9272
9364
}
9273
9365
}
9274
9366
9367
+ // If we're restoring this channel for the first time after an upgrade, then we require that the
9368
+ // signer be available so that we can immediately populate the current commitment point. Channel
9369
+ // restoration will fail if this is not possible.
9370
+ let holder_commitment_point = match (cur_holder_commitment_point_opt, next_holder_commitment_point_opt) {
9371
+ (Some(current), Some(next)) => HolderCommitmentPoint::Available {
9372
+ transaction_number: cur_holder_commitment_transaction_number, current, next
9373
+ },
9374
+ (Some(current), _) => HolderCommitmentPoint::PendingNext {
9375
+ transaction_number: cur_holder_commitment_transaction_number, current
9376
+ },
9377
+ (_, _) => HolderCommitmentPoint::Uninitialized {
9378
+ transaction_number: cur_holder_commitment_transaction_number
9379
+ }
9380
+ };
9381
+
9275
9382
Ok(Channel {
9276
9383
context: ChannelContext {
9277
9384
user_id,
@@ -9297,6 +9404,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
9297
9404
shutdown_scriptpubkey,
9298
9405
destination_script,
9299
9406
9407
+ holder_commitment_point,
9300
9408
cur_holder_commitment_transaction_number,
9301
9409
cur_counterparty_commitment_transaction_number,
9302
9410
value_to_self_msat,
0 commit comments