Skip to content

Commit 923d9b4

Browse files
committed
Clone for ChannelContext
1 parent 1a8b76b commit 923d9b4

File tree

1 file changed

+172
-5
lines changed

1 file changed

+172
-5
lines changed

lightning/src/ln/channel.rs

Lines changed: 172 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ enum FeeUpdateState {
115115
Outbound,
116116
}
117117

118+
#[derive(Clone)]
118119
enum InboundHTLCRemovalReason {
119120
FailRelay(msgs::OnionErrorPacket),
120121
FailMalformed(([u8; 32], u16)),
@@ -149,6 +150,7 @@ impl_writeable_tlv_based_enum!(InboundHTLCResolution,
149150
},
150151
);
151152

153+
#[derive(Clone)]
152154
enum InboundHTLCState {
153155
/// Offered by remote, to be included in next local commitment tx. I.e., the remote sent an
154156
/// update_add_htlc message for this HTLC.
@@ -223,6 +225,7 @@ impl From<&InboundHTLCState> for Option<InboundHTLCStateDetails> {
223225
}
224226
}
225227

228+
#[derive(Clone)]
226229
struct InboundHTLCOutput {
227230
htlc_id: u64,
228231
amount_msat: u64,
@@ -231,7 +234,8 @@ struct InboundHTLCOutput {
231234
state: InboundHTLCState,
232235
}
233236

234-
#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
237+
#[derive(Clone)]
238+
#[cfg_attr(test, derive(Debug, PartialEq))]
235239
enum OutboundHTLCState {
236240
/// Added by us and included in a commitment_signed (if we were AwaitingRemoteRevoke when we
237241
/// created it we would have put it in the holding cell instead). When they next revoke_and_ack
@@ -313,7 +317,8 @@ impl<'a> Into<Option<&'a HTLCFailReason>> for &'a OutboundHTLCOutcome {
313317
}
314318
}
315319

316-
#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
320+
#[derive(Clone)]
321+
#[cfg_attr(test, derive(Debug, PartialEq))]
317322
struct OutboundHTLCOutput {
318323
htlc_id: u64,
319324
amount_msat: u64,
@@ -326,7 +331,8 @@ struct OutboundHTLCOutput {
326331
}
327332

328333
/// See AwaitingRemoteRevoke ChannelState for more info
329-
#[cfg_attr(test, derive(Clone, Debug, PartialEq))]
334+
#[derive(Clone)]
335+
#[cfg_attr(test, derive(Debug, PartialEq))]
330336
enum HTLCUpdateAwaitingACK {
331337
AddHTLC { // TODO: Time out if we're getting close to cltv_expiry
332338
// always outbound
@@ -836,7 +842,7 @@ pub(super) enum ChannelUpdateStatus {
836842
}
837843

838844
/// We track when we sent an `AnnouncementSignatures` to our peer in a few states, described here.
839-
#[derive(PartialEq)]
845+
#[derive(Clone, PartialEq)]
840846
pub enum AnnouncementSigsState {
841847
/// We have not sent our peer an `AnnouncementSignatures` yet, or our peer disconnected since
842848
/// we sent the last `AnnouncementSignatures`.
@@ -1164,6 +1170,7 @@ pub(crate) const UNFUNDED_CHANNEL_AGE_LIMIT_TICKS: usize = 60;
11641170
/// Number of blocks needed for an output from a coinbase transaction to be spendable.
11651171
pub(crate) const COINBASE_MATURITY: u32 = 100;
11661172

1173+
#[derive(Clone)]
11671174
struct PendingChannelMonitorUpdate {
11681175
update: ChannelMonitorUpdate,
11691176
}
@@ -4873,6 +4880,112 @@ impl<SP: Deref> ChannelContext<SP> where SP::Target: SignerProvider {
48734880
self.counterparty_cur_commitment_point = Some(counterparty_cur_commitment_point_override);
48744881
self.get_initial_counterparty_commitment_signature(funding, logger)
48754882
}
4883+
4884+
/// Clone, each field, with the exception of the channel signer.
4885+
#[allow(unused)]
4886+
fn clone(&self, holder_signer: <SP::Target as SignerProvider>::EcdsaSigner) -> Self {
4887+
Self {
4888+
// Use provided channel signer
4889+
holder_signer: ChannelSignerType::Ecdsa(holder_signer),
4890+
4891+
config: self.config,
4892+
prev_config: self.prev_config,
4893+
inbound_handshake_limits_override: self.inbound_handshake_limits_override,
4894+
user_id: self.user_id,
4895+
channel_id: self.channel_id,
4896+
temporary_channel_id: self.temporary_channel_id,
4897+
channel_state: self.channel_state,
4898+
announcement_sigs_state: self.announcement_sigs_state.clone(),
4899+
secp_ctx: self.secp_ctx.clone(),
4900+
// channel_value_satoshis: self.channel_value_satoshis,
4901+
latest_monitor_update_id: self.latest_monitor_update_id,
4902+
shutdown_scriptpubkey: self.shutdown_scriptpubkey.clone(),
4903+
destination_script: self.destination_script.clone(),
4904+
// holder_commitment_point: self.holder_commitment_point,
4905+
cur_counterparty_commitment_transaction_number: self.cur_counterparty_commitment_transaction_number,
4906+
// value_to_self_msat: self.value_to_self_msat,
4907+
pending_inbound_htlcs: self.pending_inbound_htlcs.clone(),
4908+
pending_outbound_htlcs: self.pending_outbound_htlcs.clone(),
4909+
holding_cell_htlc_updates: self.holding_cell_htlc_updates.clone(),
4910+
resend_order: self.resend_order.clone(),
4911+
monitor_pending_channel_ready: self.monitor_pending_channel_ready,
4912+
monitor_pending_revoke_and_ack: self.monitor_pending_revoke_and_ack,
4913+
monitor_pending_commitment_signed: self.monitor_pending_commitment_signed,
4914+
monitor_pending_forwards: self.monitor_pending_forwards.clone(),
4915+
monitor_pending_failures: self.monitor_pending_failures.clone(),
4916+
monitor_pending_finalized_fulfills: self.monitor_pending_finalized_fulfills.clone(),
4917+
monitor_pending_update_adds: self.monitor_pending_update_adds.clone(),
4918+
monitor_pending_tx_signatures: self.monitor_pending_tx_signatures.clone(),
4919+
signer_pending_revoke_and_ack: self.signer_pending_revoke_and_ack,
4920+
signer_pending_commitment_update: self.signer_pending_commitment_update,
4921+
signer_pending_funding: self.signer_pending_funding,
4922+
signer_pending_closing: self.signer_pending_closing,
4923+
signer_pending_channel_ready: self.signer_pending_channel_ready,
4924+
pending_update_fee: self.pending_update_fee,
4925+
holding_cell_update_fee: self.holding_cell_update_fee,
4926+
next_holder_htlc_id: self.next_holder_htlc_id,
4927+
next_counterparty_htlc_id: self.next_counterparty_htlc_id,
4928+
feerate_per_kw: self.feerate_per_kw,
4929+
update_time_counter: self.update_time_counter,
4930+
// Create new mutex with copied values
4931+
// #[cfg(debug_assertions)]
4932+
// holder_max_commitment_tx_output: self.holder_max_commitment_tx_output.clone(),
4933+
// #[cfg(debug_assertions)]
4934+
// counterparty_max_commitment_tx_output: self.counterparty_max_commitment_tx_output.clone(),
4935+
last_sent_closing_fee: self.last_sent_closing_fee.clone(),
4936+
last_received_closing_sig: self.last_received_closing_sig,
4937+
target_closing_feerate_sats_per_kw: self.target_closing_feerate_sats_per_kw,
4938+
pending_counterparty_closing_signed: self.pending_counterparty_closing_signed.clone(),
4939+
closing_fee_limits: self.closing_fee_limits,
4940+
expecting_peer_commitment_signed: self.expecting_peer_commitment_signed,
4941+
funding_tx_confirmed_in: self.funding_tx_confirmed_in,
4942+
funding_tx_confirmation_height: self.funding_tx_confirmation_height,
4943+
short_channel_id: self.short_channel_id,
4944+
channel_creation_height: self.channel_creation_height,
4945+
counterparty_dust_limit_satoshis: self.counterparty_dust_limit_satoshis,
4946+
holder_dust_limit_satoshis: self.holder_dust_limit_satoshis,
4947+
counterparty_max_htlc_value_in_flight_msat: self.counterparty_max_htlc_value_in_flight_msat,
4948+
holder_max_htlc_value_in_flight_msat: self.holder_max_htlc_value_in_flight_msat,
4949+
// counterparty_selected_channel_reserve_satoshis: self.counterparty_selected_channel_reserve_satoshis,
4950+
// holder_selected_channel_reserve_satoshis: self.holder_selected_channel_reserve_satoshis,
4951+
counterparty_htlc_minimum_msat: self.counterparty_htlc_minimum_msat,
4952+
holder_htlc_minimum_msat: self.holder_htlc_minimum_msat,
4953+
counterparty_max_accepted_htlcs: self.counterparty_max_accepted_htlcs,
4954+
holder_max_accepted_htlcs: self.holder_max_accepted_htlcs,
4955+
minimum_depth: self.minimum_depth,
4956+
counterparty_forwarding_info: self.counterparty_forwarding_info.clone(),
4957+
// channel_transaction_parameters: self.channel_transaction_parameters.clone(),
4958+
// funding_transaction: self.funding_transaction.clone(),
4959+
is_manual_broadcast: self.is_manual_broadcast,
4960+
is_batch_funding: self.is_batch_funding,
4961+
counterparty_cur_commitment_point: self.counterparty_cur_commitment_point,
4962+
counterparty_prev_commitment_point: self.counterparty_prev_commitment_point,
4963+
counterparty_node_id: self.counterparty_node_id,
4964+
counterparty_shutdown_scriptpubkey: self.counterparty_shutdown_scriptpubkey.clone(),
4965+
commitment_secrets: self.commitment_secrets.clone(),
4966+
channel_update_status: self.channel_update_status,
4967+
closing_signed_in_flight: self.closing_signed_in_flight,
4968+
announcement_sigs: self.announcement_sigs,
4969+
// Create new mutex with copied values
4970+
// #[cfg(any(test, fuzzing))]
4971+
// next_local_commitment_tx_fee_info_cached: self.next_local_commitment_tx_fee_info_cached.clone(),
4972+
// #[cfg(any(test, fuzzing))]
4973+
// next_remote_commitment_tx_fee_info_cached: self.next_remote_commitment_tx_fee_info_cached.clone(),
4974+
workaround_lnd_bug_4006: self.workaround_lnd_bug_4006.clone(),
4975+
sent_message_awaiting_response: self.sent_message_awaiting_response,
4976+
channel_type: self.channel_type.clone(),
4977+
latest_inbound_scid_alias: self.latest_inbound_scid_alias,
4978+
outbound_scid_alias: self.outbound_scid_alias,
4979+
channel_pending_event_emitted: self.channel_pending_event_emitted,
4980+
funding_tx_broadcast_safe_event_emitted: self.funding_tx_broadcast_safe_event_emitted,
4981+
channel_ready_event_emitted: self.channel_ready_event_emitted,
4982+
local_initiated_shutdown: self.local_initiated_shutdown.clone(),
4983+
channel_keys_id: self.channel_keys_id,
4984+
blocked_monitor_updates: self.blocked_monitor_updates.clone(),
4985+
next_funding_txid: self.next_funding_txid.clone(),
4986+
is_holder_quiescence_initiator: self.is_holder_quiescence_initiator,
4987+
}
4988+
}
48764989
}
48774990

48784991
// Internal utility functions for channels
@@ -5052,6 +5165,7 @@ pub(super) struct FundedChannel<SP: Deref> where SP::Target: SignerProvider {
50525165
}
50535166

50545167
#[cfg(any(test, fuzzing))]
5168+
#[derive(Clone)]
50555169
struct CommitmentTxInfoCached {
50565170
fee: u64,
50575171
total_pending_htlcs: usize,
@@ -11355,7 +11469,7 @@ mod tests {
1135511469
use crate::ln::channel_keys::{RevocationKey, RevocationBasepoint};
1135611470
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
1135711471
use crate::ln::channel::InitFeatures;
11358-
use crate::ln::channel::{AwaitingChannelReadyFlags, ChannelState, FundedChannel, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, HTLCUpdateAwaitingACK, commit_tx_fee_sat};
11472+
use crate::ln::channel::{AwaitingChannelReadyFlags, ChannelContext, ChannelId, ChannelPublicKeys, ChannelState, FundedChannel, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, HTLCUpdateAwaitingACK, commit_tx_fee_sat};
1135911473
use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
1136011474
use crate::types::features::{ChannelFeatures, ChannelTypeFeatures, NodeFeatures};
1136111475
use crate::ln::msgs;
@@ -13264,6 +13378,59 @@ mod tests {
1326413378
}
1326513379
}
1326613380

13381+
#[test]
13382+
fn channel_context_clone() {
13383+
let fee_estimator = TestFeeEstimator {fee_est: 253 };
13384+
let bounded_fee_estimator = LowerBoundedFeeEstimator::new(&fee_estimator);
13385+
let seed = [42; 32];
13386+
let network = Network::Testnet;
13387+
let keys_provider = test_utils::TestKeysInterface::new(&seed, network);
13388+
let secp_ctx = Secp256k1::new();
13389+
let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
13390+
let config = UserConfig::default();
13391+
13392+
let signer_provider: &TestKeysInterface = &&keys_provider;
13393+
let channel_value_satoshis = 10000000;
13394+
let user_id = 42;
13395+
let channel_keys_id = signer_provider.generate_channel_keys_id(false, user_id);
13396+
let holder_signer = signer_provider.derive_channel_signer(channel_keys_id);
13397+
let logger = test_utils::TestLogger::new();
13398+
13399+
let temporary_channel_id_fn = Some(|pubkeys: &ChannelPublicKeys| {
13400+
ChannelId::temporary_v2_from_revocation_basepoint(&pubkeys.revocation_basepoint)
13401+
});
13402+
13403+
// Create a context
13404+
let context = ChannelContext::<&TestKeysInterface>::new_for_outbound_channel(
13405+
&bounded_fee_estimator,
13406+
&&keys_provider,
13407+
&signer_provider,
13408+
node_a_node_id,
13409+
&channelmanager::provided_init_features(&config),
13410+
channel_value_satoshis,
13411+
100000,
13412+
user_id,
13413+
&config,
13414+
0,
13415+
42,
13416+
temporary_channel_id_fn,
13417+
100000,
13418+
[42; 32],
13419+
holder_signer,
13420+
&logger,
13421+
).unwrap().1;
13422+
13423+
// Clone it
13424+
let holder_signer2 = signer_provider.derive_channel_signer(channel_keys_id);
13425+
let context_cloned = context.clone(holder_signer2);
13426+
13427+
// Compare some fields
13428+
// assert_eq!(context_cloned.channel_value_satoshis, context.channel_value_satoshis);
13429+
assert_eq!(context_cloned.channel_id, context.channel_id);
13430+
assert_eq!(context_cloned.funding_tx_broadcast_safe_event_emitted, context.funding_tx_broadcast_safe_event_emitted);
13431+
assert_eq!(context_cloned.channel_keys_id, context.channel_keys_id);
13432+
}
13433+
1326713434
#[cfg(all(test, splicing))]
1326813435
fn get_pre_and_post(pre_channel_value: u64, our_funding_contribution: i64, their_funding_contribution: i64) -> (u64, u64) {
1326913436
use crate::ln::channel::PendingSplice;

0 commit comments

Comments
 (0)