@@ -2436,92 +2436,17 @@ impl<SP: Deref> InitialRemoteCommitmentReceiver<SP> for FundedChannel<SP> where
2436
2436
/// Can be produced by:
2437
2437
/// - [`PendingV2Channel`], at V2 channel open, and
2438
2438
/// - [`FundedChannel`], when splicing.
2439
- #[cfg(splicing)]
2440
2439
struct NegotiatingV2ChannelView<'a, SP: Deref> where SP::Target: SignerProvider {
2441
- channel_context : &'a mut ChannelContext<SP>,
2442
- funding_scope : &'a mut FundingScope,
2440
+ context : &'a mut ChannelContext<SP>,
2441
+ funding : &'a mut FundingScope,
2443
2442
funding_negotiation_context: &'a mut FundingNegotiationContext,
2444
2443
interactive_tx_constructor: &'a mut Option<InteractiveTxConstructor>,
2445
2444
interactive_tx_signing_session: &'a mut Option<InteractiveTxSigningSession>,
2446
2445
holder_commitment_transaction_number: u64,
2446
+ is_splice: bool,
2447
2447
}
2448
2448
2449
- #[cfg(splicing)]
2450
- impl<'a, SP: Deref> ChannelContextProvider<SP> for NegotiatingV2ChannelView<'a, SP> where SP::Target: SignerProvider {
2451
- #[inline]
2452
- fn context(&self) -> &ChannelContext<SP> {
2453
- &self.channel_context
2454
- }
2455
-
2456
- #[inline]
2457
- fn context_mut(&mut self) -> &mut ChannelContext<SP> {
2458
- &mut self.channel_context
2459
- }
2460
- }
2461
-
2462
- #[cfg(splicing)]
2463
- impl<'a, SP: Deref> FundingTxConstructorV2<SP> for NegotiatingV2ChannelView<'a, SP> where SP::Target: SignerProvider {
2464
- #[inline]
2465
- fn funding_scope(&self) -> &FundingScope {
2466
- &self.funding_scope
2467
- }
2468
-
2469
- #[inline]
2470
- fn funding_context_mut(&mut self) -> &mut FundingScope {
2471
- &mut self.funding_scope
2472
- }
2473
-
2474
- #[inline]
2475
- fn funding_and_context_mut(&mut self) -> (&FundingScope, &mut ChannelContext<SP>) {
2476
- (&self.funding_scope, &mut self.channel_context)
2477
- }
2478
-
2479
- #[inline]
2480
- fn funding_negotiation_context(&self) -> &FundingNegotiationContext {
2481
- &self.funding_negotiation_context
2482
- }
2483
-
2484
- #[inline]
2485
- fn funding_negotiation_context_mut(&mut self) -> &mut FundingNegotiationContext {
2486
- &mut self.funding_negotiation_context
2487
- }
2488
-
2489
- fn current_holder_transaction_number(&self) -> u64 {
2490
- self.holder_commitment_transaction_number
2491
- }
2492
-
2493
- #[inline]
2494
- fn interactive_tx_constructor(&self) -> Option<&InteractiveTxConstructor> {
2495
- self.interactive_tx_constructor.as_ref()
2496
- }
2497
-
2498
- #[inline]
2499
- fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor> {
2500
- &mut self.interactive_tx_constructor
2501
- }
2502
-
2503
- #[inline]
2504
- fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession> {
2505
- &mut self.interactive_tx_signing_session
2506
- }
2507
-
2508
- fn is_splice(&self) -> bool { true }
2509
- }
2510
-
2511
- /// A channel struct implementing this trait can perform V2 transaction negotiation,
2512
- /// either at channel open or during splicing.
2513
- pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> where SP::Target: SignerProvider {
2514
- fn funding_scope(&self) -> &FundingScope;
2515
- fn funding_context_mut(&mut self) -> &mut FundingScope;
2516
- fn funding_and_context_mut(&mut self) -> (&FundingScope, &mut ChannelContext<SP>);
2517
- fn funding_negotiation_context(&self) -> &FundingNegotiationContext;
2518
- fn funding_negotiation_context_mut(&mut self) -> &mut FundingNegotiationContext;
2519
- fn current_holder_transaction_number(&self) -> u64;
2520
- fn interactive_tx_constructor(&self) -> Option<&InteractiveTxConstructor>;
2521
- fn interactive_tx_constructor_mut(&mut self) -> &mut Option<InteractiveTxConstructor>;
2522
- fn interactive_tx_signing_session_mut(&mut self) -> &mut Option<InteractiveTxSigningSession>;
2523
- fn is_splice(&self) -> bool;
2524
-
2449
+ impl<'a, SP: Deref> NegotiatingV2ChannelView<'a, SP> where SP::Target: SignerProvider {
2525
2450
/// Prepare and start interactive transaction negotiation.
2526
2451
/// `change_destination_opt` - Optional destination for optional change; if None,
2527
2452
/// default destination address is used.
@@ -2534,17 +2459,16 @@ pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> w
2534
2459
) -> Result<Option<InteractiveTxMessageSend>, AbortReason>
2535
2460
where ES::Target: EntropySource
2536
2461
{
2537
- if self.is_splice() {
2538
- debug_assert!(matches!(self.context() .channel_state, ChannelState::ChannelReady(_)));
2462
+ if self.is_splice {
2463
+ debug_assert!(matches!(self.context.channel_state, ChannelState::ChannelReady(_)));
2539
2464
} else {
2540
- debug_assert!(matches!(self.context() .channel_state, ChannelState::NegotiatingFunding(_)));
2465
+ debug_assert!(matches!(self.context.channel_state, ChannelState::NegotiatingFunding(_)));
2541
2466
}
2542
2467
2543
- debug_assert!(self.interactive_tx_constructor() .is_none());
2468
+ debug_assert!(self.interactive_tx_constructor.is_none());
2544
2469
2545
2470
let mut funding_inputs = Vec::new();
2546
- let funding_negotiation_context_mut = self.funding_negotiation_context_mut();
2547
- mem::swap(&mut funding_negotiation_context_mut.our_funding_inputs, &mut funding_inputs);
2471
+ mem::swap(&mut self.funding_negotiation_context.our_funding_inputs, &mut funding_inputs);
2548
2472
2549
2473
if let Some(prev_funding_input) = prev_funding_input {
2550
2474
funding_inputs.push(prev_funding_input);
@@ -2556,18 +2480,15 @@ pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> w
2556
2480
let mut funding_outputs = Vec::new();
2557
2481
let mut expected_remote_shared_funding_output = None;
2558
2482
2559
- let funding_scope = self.funding_scope();
2560
-
2561
2483
let shared_funding_output = TxOut {
2562
- value: Amount::from_sat(funding_scope .get_value_satoshis()),
2563
- script_pubkey: funding_scope .get_funding_redeemscript().to_p2wsh(),
2484
+ value: Amount::from_sat(self.funding .get_value_satoshis()),
2485
+ script_pubkey: self.funding .get_funding_redeemscript().to_p2wsh(),
2564
2486
};
2565
2487
2566
- let funding_negotiation_context = &self.funding_negotiation_context();
2567
- if funding_scope.is_outbound() {
2488
+ if self.funding.is_outbound() {
2568
2489
funding_outputs.push(
2569
2490
OutputOwned::Shared(SharedOwnedOutput::new(
2570
- shared_funding_output, funding_negotiation_context.our_funding_satoshis,
2491
+ shared_funding_output, self. funding_negotiation_context.our_funding_satoshis,
2571
2492
))
2572
2493
);
2573
2494
} else {
@@ -2579,13 +2500,13 @@ pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> w
2579
2500
let change_script = if let Some(script) = change_destination_opt {
2580
2501
script
2581
2502
} else {
2582
- signer_provider.get_destination_script(self.context() .channel_keys_id)
2503
+ signer_provider.get_destination_script(self.context.channel_keys_id)
2583
2504
.map_err(|_err| AbortReason::InternalError("Error getting destination script"))?
2584
2505
};
2585
2506
let change_value_opt = calculate_change_output_value(
2586
- funding_scope. is_outbound(), funding_negotiation_context.our_funding_satoshis,
2507
+ self.funding. is_outbound(), self. funding_negotiation_context.our_funding_satoshis,
2587
2508
&funding_inputs, &funding_outputs,
2588
- funding_negotiation_context.funding_feerate_sat_per_1000_weight,
2509
+ self. funding_negotiation_context.funding_feerate_sat_per_1000_weight,
2589
2510
change_script.minimal_non_dust().to_sat(),
2590
2511
)?;
2591
2512
if let Some(change_value) = change_value_opt {
@@ -2594,10 +2515,10 @@ pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> w
2594
2515
script_pubkey: change_script,
2595
2516
};
2596
2517
let change_output_weight = get_output_weight(&change_output.script_pubkey).to_wu();
2597
- let change_output_fee = fee_for_weight(funding_negotiation_context.funding_feerate_sat_per_1000_weight, change_output_weight);
2518
+ let change_output_fee = fee_for_weight(self. funding_negotiation_context.funding_feerate_sat_per_1000_weight, change_output_weight);
2598
2519
let change_value_decreased_with_fee = change_value.saturating_sub(change_output_fee);
2599
2520
// Check dust limit again
2600
- if change_value_decreased_with_fee > self.context() .holder_dust_limit_satoshis {
2521
+ if change_value_decreased_with_fee > self.context.holder_dust_limit_satoshis {
2601
2522
change_output.value = Amount::from_sat(change_value_decreased_with_fee);
2602
2523
funding_outputs.push(OutputOwned::Single(change_output));
2603
2524
}
@@ -2606,70 +2527,69 @@ pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> w
2606
2527
let constructor_args = InteractiveTxConstructorArgs {
2607
2528
entropy_source,
2608
2529
holder_node_id,
2609
- counterparty_node_id: self.context() .counterparty_node_id,
2610
- channel_id: self.context() .channel_id(),
2611
- feerate_sat_per_kw: funding_negotiation_context.funding_feerate_sat_per_1000_weight,
2612
- is_initiator: funding_scope .is_outbound(),
2613
- funding_tx_locktime: funding_negotiation_context.funding_tx_locktime,
2530
+ counterparty_node_id: self.context.counterparty_node_id,
2531
+ channel_id: self.context.channel_id(),
2532
+ feerate_sat_per_kw: self. funding_negotiation_context.funding_feerate_sat_per_1000_weight,
2533
+ is_initiator: self.funding .is_outbound(),
2534
+ funding_tx_locktime: self. funding_negotiation_context.funding_tx_locktime,
2614
2535
inputs_to_contribute: funding_inputs,
2615
2536
outputs_to_contribute: funding_outputs,
2616
2537
expected_remote_shared_funding_output,
2617
2538
};
2618
2539
let mut tx_constructor = InteractiveTxConstructor::new(constructor_args)?;
2619
2540
let msg = tx_constructor.take_initiator_first_message();
2620
2541
2621
- *self.interactive_tx_constructor_mut() = Some(tx_constructor);
2542
+ *self.interactive_tx_constructor = Some(tx_constructor);
2622
2543
2623
2544
Ok(msg)
2624
2545
}
2625
2546
2626
2547
fn tx_add_input(&mut self, msg: &msgs::TxAddInput) -> InteractiveTxMessageSendResult {
2627
- InteractiveTxMessageSendResult(match self.interactive_tx_constructor_mut() {
2548
+ InteractiveTxMessageSendResult(match self.interactive_tx_constructor {
2628
2549
Some(ref mut tx_constructor) => tx_constructor.handle_tx_add_input(msg).map_err(
2629
- |reason| reason.into_tx_abort_msg(self.context() .channel_id())),
2550
+ |reason| reason.into_tx_abort_msg(self.context.channel_id())),
2630
2551
None => Err(msgs::TxAbort {
2631
- channel_id: self.context() .channel_id(),
2552
+ channel_id: self.context.channel_id(),
2632
2553
data: b"No interactive transaction negotiation in progress".to_vec()
2633
2554
}),
2634
2555
})
2635
2556
}
2636
2557
2637
2558
fn tx_add_output(&mut self, msg: &msgs::TxAddOutput)-> InteractiveTxMessageSendResult {
2638
- InteractiveTxMessageSendResult(match self.interactive_tx_constructor_mut() {
2559
+ InteractiveTxMessageSendResult(match self.interactive_tx_constructor {
2639
2560
Some(ref mut tx_constructor) => tx_constructor.handle_tx_add_output(msg).map_err(
2640
- |reason| reason.into_tx_abort_msg(self.context() .channel_id())),
2561
+ |reason| reason.into_tx_abort_msg(self.context.channel_id())),
2641
2562
None => Err(msgs::TxAbort {
2642
- channel_id: self.context() .channel_id(),
2563
+ channel_id: self.context.channel_id(),
2643
2564
data: b"No interactive transaction negotiation in progress".to_vec()
2644
2565
}),
2645
2566
})
2646
2567
}
2647
2568
2648
2569
fn tx_remove_input(&mut self, msg: &msgs::TxRemoveInput)-> InteractiveTxMessageSendResult {
2649
- InteractiveTxMessageSendResult(match self.interactive_tx_constructor_mut() {
2570
+ InteractiveTxMessageSendResult(match self.interactive_tx_constructor {
2650
2571
Some(ref mut tx_constructor) => tx_constructor.handle_tx_remove_input(msg).map_err(
2651
- |reason| reason.into_tx_abort_msg(self.context() .channel_id())),
2572
+ |reason| reason.into_tx_abort_msg(self.context.channel_id())),
2652
2573
None => Err(msgs::TxAbort {
2653
- channel_id: self.context() .channel_id(),
2574
+ channel_id: self.context.channel_id(),
2654
2575
data: b"No interactive transaction negotiation in progress".to_vec()
2655
2576
}),
2656
2577
})
2657
2578
}
2658
2579
2659
2580
fn tx_remove_output(&mut self, msg: &msgs::TxRemoveOutput)-> InteractiveTxMessageSendResult {
2660
- InteractiveTxMessageSendResult(match self.interactive_tx_constructor_mut() {
2581
+ InteractiveTxMessageSendResult(match self.interactive_tx_constructor {
2661
2582
Some(ref mut tx_constructor) => tx_constructor.handle_tx_remove_output(msg).map_err(
2662
- |reason| reason.into_tx_abort_msg(self.context() .channel_id())),
2583
+ |reason| reason.into_tx_abort_msg(self.context.channel_id())),
2663
2584
None => Err(msgs::TxAbort {
2664
- channel_id: self.context() .channel_id(),
2585
+ channel_id: self.context.channel_id(),
2665
2586
data: b"No interactive transaction negotiation in progress".to_vec()
2666
2587
}),
2667
2588
})
2668
2589
}
2669
2590
2670
2591
fn tx_complete(&mut self, msg: &msgs::TxComplete) -> HandleTxCompleteResult {
2671
- let interactive_tx_constructor = self.interactive_tx_constructor_mut();
2672
- let tx_constructor = match interactive_tx_constructor {
2592
+ let tx_constructor = match self.interactive_tx_constructor {
2673
2593
Some(tx_constructor) => tx_constructor,
2674
2594
None => {
2675
2595
let tx_abort = msgs::TxAbort {
@@ -2688,7 +2608,7 @@ pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> w
2688
2608
};
2689
2609
2690
2610
if let HandleTxCompleteValue::SendTxComplete(_, ref signing_session) = tx_complete {
2691
- self.context_mut() .next_funding_txid = Some(signing_session.unsigned_tx.compute_txid());
2611
+ self.context .next_funding_txid = Some(signing_session.unsigned_tx.compute_txid());
2692
2612
};
2693
2613
2694
2614
HandleTxCompleteResult(Ok(tx_complete))
@@ -2700,15 +2620,13 @@ pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> w
2700
2620
where
2701
2621
L::Target: Logger
2702
2622
{
2703
- let our_funding_satoshis = self.funding_negotiation_context()
2623
+ let our_funding_satoshis = self.funding_negotiation_context
2704
2624
.our_funding_satoshis;
2705
- let transaction_number = self.current_holder_transaction_number();
2706
- let funding_scope = self.funding_scope();
2707
2625
2708
2626
let mut output_index = None;
2709
- let expected_spk = funding_scope .get_funding_redeemscript().to_p2wsh();
2627
+ let expected_spk = self.funding .get_funding_redeemscript().to_p2wsh();
2710
2628
for (idx, outp) in signing_session.unsigned_tx.outputs().enumerate() {
2711
- if outp.script_pubkey() == &expected_spk && outp.value() == funding_scope .get_value_satoshis() {
2629
+ if outp.script_pubkey() == &expected_spk && outp.value() == self.funding .get_value_satoshis() {
2712
2630
if output_index.is_some() {
2713
2631
return Err(ChannelError::Close(
2714
2632
(
@@ -2728,36 +2646,35 @@ pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> w
2728
2646
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
2729
2647
)));
2730
2648
};
2731
- self.funding_context_mut()
2649
+ self.funding
2732
2650
.channel_transaction_parameters.funding_outpoint = Some(outpoint);
2733
2651
2734
- if self.is_splice() {
2652
+ if self.is_splice {
2735
2653
// TODO(splicing) Forced error, as the use case is not complete
2736
2654
return Err(ChannelError::Close((
2737
2655
"TODO Forced error, incomplete implementation".into(),
2738
2656
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) }
2739
2657
)));
2740
2658
}
2741
2659
2742
- self.context().assert_no_commitment_advancement(transaction_number, "initial commitment_signed");
2743
- let (funding, context_mut) = self.funding_and_context_mut();
2744
- let commitment_signed = context_mut.get_initial_commitment_signed(&funding, logger);
2660
+ self.context.assert_no_commitment_advancement(self.holder_commitment_transaction_number, "initial commitment_signed");
2661
+ let commitment_signed = self.context.get_initial_commitment_signed(&self.funding, logger);
2745
2662
let commitment_signed = match commitment_signed {
2746
2663
Ok(commitment_signed) => {
2747
- self.funding_context_mut()
2664
+ self.funding
2748
2665
.funding_transaction = Some(signing_session.unsigned_tx.build_unsigned_tx());
2749
2666
commitment_signed
2750
2667
},
2751
2668
Err(err) => {
2752
- self.funding_context_mut()
2669
+ self.funding
2753
2670
.channel_transaction_parameters.funding_outpoint = None;
2754
2671
return Err(ChannelError::Close((err.to_string(), ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) })));
2755
2672
},
2756
2673
};
2757
2674
2758
2675
let funding_ready_for_sig_event = if signing_session.local_inputs_count() == 0 {
2759
2676
debug_assert_eq!(our_funding_satoshis, 0);
2760
- if signing_session.provide_holder_witnesses(self.context() .channel_id, Vec::new()).is_err() {
2677
+ if signing_session.provide_holder_witnesses(self.context.channel_id, Vec::new()).is_err() {
2761
2678
debug_assert!(
2762
2679
false,
2763
2680
"Zero inputs were provided & zero witnesses were provided, but a count mismatch was somehow found",
@@ -2793,11 +2710,11 @@ pub(super) trait FundingTxConstructorV2<SP: Deref>: ChannelContextProvider<SP> w
2793
2710
)));
2794
2711
};
2795
2712
2796
- self.context_mut() .channel_state = ChannelState::FundingNegotiated;
2713
+ self.context .channel_state = ChannelState::FundingNegotiated;
2797
2714
2798
2715
// Clear the interactive transaction constructor
2799
- *self.interactive_tx_constructor_mut() = None;
2800
- *self.interactive_tx_signing_session_mut() = Some(signing_session);
2716
+ *self.interactive_tx_constructor = None;
2717
+ *self.interactive_tx_signing_session = Some(signing_session);
2801
2718
2802
2719
Ok((commitment_signed, funding_ready_for_sig_event))
2803
2720
}
@@ -5369,17 +5286,18 @@ impl<SP: Deref> FundedChannel<SP> where
5369
5286
{
5370
5287
/// If we are in splicing/refunding, return a short-lived [`NegotiatingV2ChannelView`].
5371
5288
#[cfg(splicing)]
5372
- fn as_renegotiating_channel<'a>(&'a mut self) -> Result<impl FundingTxConstructorV2 <SP> + 'a , &'static str> {
5289
+ fn as_renegotiating_channel(& mut self) -> Result<NegotiatingV2ChannelView <SP>, &'static str> {
5373
5290
if let Some(ref mut pending_splice) = &mut self.pending_splice {
5374
- if let Some(ref mut funding_scope ) = &mut pending_splice.funding_scope {
5291
+ if let Some(ref mut funding ) = &mut pending_splice.funding_scope {
5375
5292
if let Some(ref mut funding_negotiation_context) = &mut pending_splice.funding_negotiation_context {
5376
5293
Ok(NegotiatingV2ChannelView {
5377
- channel_context : &mut self.context,
5378
- funding_scope ,
5294
+ context : &mut self.context,
5295
+ funding ,
5379
5296
funding_negotiation_context,
5380
5297
interactive_tx_constructor: &mut pending_splice.interactive_tx_constructor,
5381
5298
interactive_tx_signing_session: &mut pending_splice.interactive_tx_signing_session,
5382
5299
holder_commitment_transaction_number: self.holder_commitment_point.transaction_number(),
5300
+ is_splice: true,
5383
5301
})
5384
5302
} else {
5385
5303
Err("Channel is not refunding")
@@ -10919,15 +10837,15 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
10919
10837
}
10920
10838
10921
10839
/// Return a short-lived [`NegotiatingV2ChannelView`].
10922
- #[cfg(splicing)]
10923
- fn as_negotiating_channel<'a>(&'a mut self) -> impl FundingTxConstructorV2<SP> + 'a {
10840
+ fn as_negotiating_channel(&mut self) -> NegotiatingV2ChannelView<SP> {
10924
10841
NegotiatingV2ChannelView {
10925
- channel_context : &mut self.context,
10926
- funding_scope : &mut self.funding,
10842
+ context : &mut self.context,
10843
+ funding : &mut self.funding,
10927
10844
funding_negotiation_context: &mut self.funding_negotiation_context,
10928
10845
interactive_tx_constructor: &mut self.interactive_tx_constructor,
10929
10846
interactive_tx_signing_session: &mut self.interactive_tx_signing_session,
10930
10847
holder_commitment_transaction_number: self.unfunded_context.transaction_number(),
10848
+ is_splice: false,
10931
10849
}
10932
10850
}
10933
10851
}
0 commit comments