@@ -113,6 +113,7 @@ enum FeeUpdateState {
113
113
Outbound,
114
114
}
115
115
116
+ #[derive(Clone)]
116
117
enum InboundHTLCRemovalReason {
117
118
FailRelay(msgs::OnionErrorPacket),
118
119
FailMalformed(([u8; 32], u16)),
@@ -147,6 +148,7 @@ impl_writeable_tlv_based_enum!(InboundHTLCResolution,
147
148
},
148
149
);
149
150
151
+ #[derive(Clone)]
150
152
enum InboundHTLCState {
151
153
/// Offered by remote, to be included in next local commitment tx. I.e., the remote sent an
152
154
/// update_add_htlc message for this HTLC.
@@ -221,6 +223,7 @@ impl From<&InboundHTLCState> for Option<InboundHTLCStateDetails> {
221
223
}
222
224
}
223
225
226
+ #[derive(Clone)]
224
227
struct InboundHTLCOutput {
225
228
htlc_id: u64,
226
229
amount_msat: u64,
@@ -229,7 +232,8 @@ struct InboundHTLCOutput {
229
232
state: InboundHTLCState,
230
233
}
231
234
232
- #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
235
+ #[derive(Clone)]
236
+ #[cfg_attr(test, derive(Debug, PartialEq))]
233
237
enum OutboundHTLCState {
234
238
/// Added by us and included in a commitment_signed (if we were AwaitingRemoteRevoke when we
235
239
/// created it we would have put it in the holding cell instead). When they next revoke_and_ack
@@ -311,7 +315,8 @@ impl<'a> Into<Option<&'a HTLCFailReason>> for &'a OutboundHTLCOutcome {
311
315
}
312
316
}
313
317
314
- #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
318
+ #[derive(Clone)]
319
+ #[cfg_attr(test, derive(Debug, PartialEq))]
315
320
struct OutboundHTLCOutput {
316
321
htlc_id: u64,
317
322
amount_msat: u64,
@@ -324,7 +329,8 @@ struct OutboundHTLCOutput {
324
329
}
325
330
326
331
/// See AwaitingRemoteRevoke ChannelState for more info
327
- #[cfg_attr(test, derive(Clone, Debug, PartialEq))]
332
+ #[derive(Clone)]
333
+ #[cfg_attr(test, derive(Debug, PartialEq))]
328
334
enum HTLCUpdateAwaitingACK {
329
335
AddHTLC { // TODO: Time out if we're getting close to cltv_expiry
330
336
// always outbound
@@ -834,7 +840,7 @@ pub(super) enum ChannelUpdateStatus {
834
840
}
835
841
836
842
/// We track when we sent an `AnnouncementSignatures` to our peer in a few states, described here.
837
- #[derive(PartialEq)]
843
+ #[derive(Clone, PartialEq)]
838
844
pub enum AnnouncementSigsState {
839
845
/// We have not sent our peer an `AnnouncementSignatures` yet, or our peer disconnected since
840
846
/// we sent the last `AnnouncementSignatures`.
@@ -1162,6 +1168,7 @@ pub(crate) const UNFUNDED_CHANNEL_AGE_LIMIT_TICKS: usize = 60;
1162
1168
/// Number of blocks needed for an output from a coinbase transaction to be spendable.
1163
1169
pub(crate) const COINBASE_MATURITY: u32 = 100;
1164
1170
1171
+ #[derive(Clone)]
1165
1172
struct PendingChannelMonitorUpdate {
1166
1173
update: ChannelMonitorUpdate,
1167
1174
}
@@ -4811,6 +4818,112 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
4811
4818
self.counterparty_cur_commitment_point = Some(counterparty_cur_commitment_point_override);
4812
4819
self.get_initial_counterparty_commitment_signature(funding, logger)
4813
4820
}
4821
+
4822
+ /// Clone, each field, with the exception of the channel signer.
4823
+ #[allow(unused)]
4824
+ fn clone(&self, holder_signer: <SP::Target as SignerProvider>::EcdsaSigner) -> Self {
4825
+ Self {
4826
+ // Use provided channel signer
4827
+ holder_signer: ChannelSignerType::Ecdsa(holder_signer),
4828
+
4829
+ config: self.config,
4830
+ prev_config: self.prev_config,
4831
+ inbound_handshake_limits_override: self.inbound_handshake_limits_override,
4832
+ user_id: self.user_id,
4833
+ channel_id: self.channel_id,
4834
+ temporary_channel_id: self.temporary_channel_id,
4835
+ channel_state: self.channel_state,
4836
+ announcement_sigs_state: self.announcement_sigs_state.clone(),
4837
+ secp_ctx: self.secp_ctx.clone(),
4838
+ // channel_value_satoshis: self.channel_value_satoshis,
4839
+ latest_monitor_update_id: self.latest_monitor_update_id,
4840
+ shutdown_scriptpubkey: self.shutdown_scriptpubkey.clone(),
4841
+ destination_script: self.destination_script.clone(),
4842
+ // holder_commitment_point: self.holder_commitment_point,
4843
+ cur_counterparty_commitment_transaction_number: self.cur_counterparty_commitment_transaction_number,
4844
+ // value_to_self_msat: self.value_to_self_msat,
4845
+ pending_inbound_htlcs: self.pending_inbound_htlcs.clone(),
4846
+ pending_outbound_htlcs: self.pending_outbound_htlcs.clone(),
4847
+ holding_cell_htlc_updates: self.holding_cell_htlc_updates.clone(),
4848
+ resend_order: self.resend_order.clone(),
4849
+ monitor_pending_channel_ready: self.monitor_pending_channel_ready,
4850
+ monitor_pending_revoke_and_ack: self.monitor_pending_revoke_and_ack,
4851
+ monitor_pending_commitment_signed: self.monitor_pending_commitment_signed,
4852
+ monitor_pending_forwards: self.monitor_pending_forwards.clone(),
4853
+ monitor_pending_failures: self.monitor_pending_failures.clone(),
4854
+ monitor_pending_finalized_fulfills: self.monitor_pending_finalized_fulfills.clone(),
4855
+ monitor_pending_update_adds: self.monitor_pending_update_adds.clone(),
4856
+ monitor_pending_tx_signatures: self.monitor_pending_tx_signatures.clone(),
4857
+ signer_pending_revoke_and_ack: self.signer_pending_revoke_and_ack,
4858
+ signer_pending_commitment_update: self.signer_pending_commitment_update,
4859
+ signer_pending_funding: self.signer_pending_funding,
4860
+ signer_pending_closing: self.signer_pending_closing,
4861
+ signer_pending_channel_ready: self.signer_pending_channel_ready,
4862
+ pending_update_fee: self.pending_update_fee,
4863
+ holding_cell_update_fee: self.holding_cell_update_fee,
4864
+ next_holder_htlc_id: self.next_holder_htlc_id,
4865
+ next_counterparty_htlc_id: self.next_counterparty_htlc_id,
4866
+ feerate_per_kw: self.feerate_per_kw,
4867
+ update_time_counter: self.update_time_counter,
4868
+ // Create new mutex with copied values
4869
+ // #[cfg(debug_assertions)]
4870
+ // holder_max_commitment_tx_output: self.holder_max_commitment_tx_output.clone(),
4871
+ // #[cfg(debug_assertions)]
4872
+ // counterparty_max_commitment_tx_output: self.counterparty_max_commitment_tx_output.clone(),
4873
+ last_sent_closing_fee: self.last_sent_closing_fee.clone(),
4874
+ last_received_closing_sig: self.last_received_closing_sig,
4875
+ target_closing_feerate_sats_per_kw: self.target_closing_feerate_sats_per_kw,
4876
+ pending_counterparty_closing_signed: self.pending_counterparty_closing_signed.clone(),
4877
+ closing_fee_limits: self.closing_fee_limits,
4878
+ expecting_peer_commitment_signed: self.expecting_peer_commitment_signed,
4879
+ funding_tx_confirmed_in: self.funding_tx_confirmed_in,
4880
+ funding_tx_confirmation_height: self.funding_tx_confirmation_height,
4881
+ short_channel_id: self.short_channel_id,
4882
+ channel_creation_height: self.channel_creation_height,
4883
+ counterparty_dust_limit_satoshis: self.counterparty_dust_limit_satoshis,
4884
+ holder_dust_limit_satoshis: self.holder_dust_limit_satoshis,
4885
+ counterparty_max_htlc_value_in_flight_msat: self.counterparty_max_htlc_value_in_flight_msat,
4886
+ holder_max_htlc_value_in_flight_msat: self.holder_max_htlc_value_in_flight_msat,
4887
+ // counterparty_selected_channel_reserve_satoshis: self.counterparty_selected_channel_reserve_satoshis,
4888
+ // holder_selected_channel_reserve_satoshis: self.holder_selected_channel_reserve_satoshis,
4889
+ counterparty_htlc_minimum_msat: self.counterparty_htlc_minimum_msat,
4890
+ holder_htlc_minimum_msat: self.holder_htlc_minimum_msat,
4891
+ counterparty_max_accepted_htlcs: self.counterparty_max_accepted_htlcs,
4892
+ holder_max_accepted_htlcs: self.holder_max_accepted_htlcs,
4893
+ minimum_depth: self.minimum_depth,
4894
+ counterparty_forwarding_info: self.counterparty_forwarding_info.clone(),
4895
+ // channel_transaction_parameters: self.channel_transaction_parameters.clone(),
4896
+ // funding_transaction: self.funding_transaction.clone(),
4897
+ is_manual_broadcast: self.is_manual_broadcast,
4898
+ is_batch_funding: self.is_batch_funding,
4899
+ counterparty_cur_commitment_point: self.counterparty_cur_commitment_point,
4900
+ counterparty_prev_commitment_point: self.counterparty_prev_commitment_point,
4901
+ counterparty_node_id: self.counterparty_node_id,
4902
+ counterparty_shutdown_scriptpubkey: self.counterparty_shutdown_scriptpubkey.clone(),
4903
+ commitment_secrets: self.commitment_secrets.clone(),
4904
+ channel_update_status: self.channel_update_status,
4905
+ closing_signed_in_flight: self.closing_signed_in_flight,
4906
+ announcement_sigs: self.announcement_sigs,
4907
+ // Create new mutex with copied values
4908
+ // #[cfg(any(test, fuzzing))]
4909
+ // next_local_commitment_tx_fee_info_cached: self.next_local_commitment_tx_fee_info_cached.clone(),
4910
+ // #[cfg(any(test, fuzzing))]
4911
+ // next_remote_commitment_tx_fee_info_cached: self.next_remote_commitment_tx_fee_info_cached.clone(),
4912
+ workaround_lnd_bug_4006: self.workaround_lnd_bug_4006.clone(),
4913
+ sent_message_awaiting_response: self.sent_message_awaiting_response,
4914
+ channel_type: self.channel_type.clone(),
4915
+ latest_inbound_scid_alias: self.latest_inbound_scid_alias,
4916
+ outbound_scid_alias: self.outbound_scid_alias,
4917
+ channel_pending_event_emitted: self.channel_pending_event_emitted,
4918
+ funding_tx_broadcast_safe_event_emitted: self.funding_tx_broadcast_safe_event_emitted,
4919
+ channel_ready_event_emitted: self.channel_ready_event_emitted,
4920
+ local_initiated_shutdown: self.local_initiated_shutdown.clone(),
4921
+ channel_keys_id: self.channel_keys_id,
4922
+ blocked_monitor_updates: self.blocked_monitor_updates.clone(),
4923
+ next_funding_txid: self.next_funding_txid.clone(),
4924
+ is_holder_quiescence_initiator: self.is_holder_quiescence_initiator,
4925
+ }
4926
+ }
4814
4927
}
4815
4928
4816
4929
// Internal utility functions for channels
@@ -4936,6 +5049,7 @@ pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
4936
5049
}
4937
5050
4938
5051
#[cfg(any(test, fuzzing))]
5052
+ #[derive(Clone)]
4939
5053
struct CommitmentTxInfoCached {
4940
5054
fee: u64,
4941
5055
total_pending_htlcs: usize,
@@ -11332,7 +11446,7 @@ mod tests {
11332
11446
use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
11333
11447
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
11334
11448
use crate::ln::channel::InitFeatures;
11335
- use crate::ln::channel::{AwaitingChannelReadyFlags, ChannelState, FundedChannel, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, HTLCUpdateAwaitingACK, commit_tx_fee_sat};
11449
+ use crate::ln::channel::{AwaitingChannelReadyFlags, ChannelContext, ChannelState, FundedChannel, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, HTLCUpdateAwaitingACK, commit_tx_fee_sat};
11336
11450
use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
11337
11451
use crate::types::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures};
11338
11452
use crate::ln::msgs;
@@ -13129,6 +13243,57 @@ mod tests {
13129
13243
);
13130
13244
}
13131
13245
13246
+ #[test]
13247
+ fn channel_context_clone() {
13248
+ let fee_estimator = TestFeeEstimator {fee_est: 253 };
13249
+ let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_estimator);
13250
+ let seed = [42; 32];
13251
+ let network = Network::Testnet;
13252
+ let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
13253
+ let secp_ctx = Secp256k1::new();
13254
+ let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
13255
+ let config = UserConfig::default();
13256
+
13257
+ let signer_provider: &TestKeysInterface = &&keys_provider;
13258
+ let channel_value_satoshis = 10000000;
13259
+ let user_id = 42;
13260
+ let channel_keys_id = signer_provider.generate_channel_keys_id(false, user_id);
13261
+ let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
13262
+ let logger = test_utils::TestLogger::new();
13263
+ let pubkeys = holder_signer.pubkeys().clone();
13264
+
13265
+ // Create a context
13266
+ let context = ChannelContext::<&TestKeysInterface>::new_for_outbound_channel(
13267
+ &bounded_fee_estimator,
13268
+ &&keys_provider,
13269
+ &signer_provider,
13270
+ node_a_node_id,
13271
+ &channelmanager::provided_init_features(&config),
13272
+ channel_value_satoshis,
13273
+ 100000,
13274
+ user_id,
13275
+ &config,
13276
+ 0,
13277
+ 42,
13278
+ None,
13279
+ 100000,
13280
+ [42; 32],
13281
+ holder_signer,
13282
+ pubkeys,
13283
+ &logger,
13284
+ ).unwrap().1;
13285
+
13286
+ // Clone it
13287
+ let holder_signer2 = signer_provider.derive_channel_signer(channel_keys_id);
13288
+ let context_cloned = context.clone(holder_signer2);
13289
+
13290
+ // Compare some fields
13291
+ // assert_eq!(context_cloned.channel_value_satoshis, context.channel_value_satoshis);
13292
+ assert_eq!(context_cloned.channel_id, context.channel_id);
13293
+ assert_eq!(context_cloned.funding_tx_broadcast_safe_event_emitted, context.funding_tx_broadcast_safe_event_emitted);
13294
+ assert_eq!(context_cloned.channel_keys_id, context.channel_keys_id);
13295
+ }
13296
+
13132
13297
#[cfg(all(test, splicing))]
13133
13298
fn get_pre_and_post(pre_channel_value: u64, our_funding_contribution: i64, their_funding_contribution: i64) -> (u64, u64) {
13134
13299
use crate::ln::channel::PendingSplice;
0 commit comments