Skip to content

Commit 80f9944

Browse files
committed
Allow passing funding inputs when manually accepting a dual-funded channel
We introduce a `ChannelManager::accept_inbound_channel_with_contribution` method allowing contributing to the overall channel capacity of an inbound dual-funded channel by contributing inputs.
1 parent 9ff296f commit 80f9944

File tree

4 files changed

+157
-49
lines changed

4 files changed

+157
-49
lines changed

lightning/src/ln/channel.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5603,7 +5603,7 @@ pub(super) struct DualFundingChannelContext {
56035603
///
56045604
/// Note that this field may be emptied once the interactive negotiation has been started.
56055605
#[allow(dead_code)] // TODO(dual_funding): Remove once contribution to V2 channels is enabled.
5606-
pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
5606+
pub our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited, Weight)>,
56075607
}
56085608

56095609
// Holder designates channel data owned for the benefit of the user client.
@@ -10895,7 +10895,7 @@ where
1089510895
pub fn new_outbound<ES: Deref, F: Deref, L: Deref>(
1089610896
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
1089710897
counterparty_node_id: PublicKey, their_features: &InitFeatures, funding_satoshis: u64,
10898-
funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>, user_id: u128, config: &UserConfig,
10898+
funding_inputs: Vec<(TxIn, TransactionU16LenLimited, Weight)>, user_id: u128, config: &UserConfig,
1089910899
current_chain_height: u32, outbound_scid_alias: u64, funding_confirmation_target: ConfirmationTarget,
1090010900
logger: L,
1090110901
) -> Result<Self, APIError>
@@ -11037,23 +11037,19 @@ where
1103711037

1103811038
/// Creates a new dual-funded channel from a remote side's request for one.
1103911039
/// Assumes chain_hash has already been checked and corresponds with what we expect!
11040-
/// TODO(dual_funding): Allow contributions, pass intended amount and inputs
1104111040
#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
1104211041
#[rustfmt::skip]
1104311042
pub fn new_inbound<ES: Deref, F: Deref, L: Deref>(
1104411043
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
1104511044
holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
11046-
their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
11047-
user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
11045+
their_features: &InitFeatures, msg: &msgs::OpenChannelV2, user_id: u128, config: &UserConfig,
11046+
current_chain_height: u32, logger: &L, our_funding_satoshis: u64,
11047+
our_funding_inputs: Vec<(TxIn, TransactionU16LenLimited, Weight)>,
1104811048
) -> Result<Self, ChannelError>
1104911049
where ES::Target: EntropySource,
1105011050
F::Target: FeeEstimator,
1105111051
L::Target: Logger,
1105211052
{
11053-
// TODO(dual_funding): Take these as input once supported
11054-
let our_funding_satoshis = 0u64;
11055-
let our_funding_inputs = Vec::new();
11056-
1105711053
let channel_value_satoshis = our_funding_satoshis.saturating_add(msg.common_fields.funding_satoshis);
1105811054
let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
1105911055
channel_value_satoshis, msg.common_fields.dust_limit_satoshis);
@@ -11103,7 +11099,7 @@ where
1110311099
context.channel_id = channel_id;
1110411100

1110511101
let dual_funding_context = DualFundingChannelContext {
11106-
our_funding_satoshis: our_funding_satoshis,
11102+
our_funding_satoshis,
1110711103
their_funding_satoshis: Some(msg.common_fields.funding_satoshis),
1110811104
funding_tx_locktime: LockTime::from_consensus(msg.locktime),
1110911105
funding_feerate_sat_per_1000_weight: msg.funding_feerate_sat_per_1000_weight,

lightning/src/ln/channelmanager.rs

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ use bitcoin::hashes::{Hash, HashEngine, HmacEngine};
3030

3131
use bitcoin::secp256k1::Secp256k1;
3232
use bitcoin::secp256k1::{PublicKey, SecretKey};
33-
use bitcoin::{secp256k1, Sequence};
34-
#[cfg(splicing)]
35-
use bitcoin::{TxIn, Weight};
33+
use bitcoin::{secp256k1, Sequence, TxIn, Weight};
3634

3735
use crate::blinded_path::message::MessageForwardNode;
3836
use crate::blinded_path::message::{AsyncPaymentsContext, OffersContext};
@@ -122,8 +120,8 @@ use crate::util::errors::APIError;
122120
use crate::util::logger::{Level, Logger, WithContext};
123121
use crate::util::scid_utils::fake_scid;
124122
use crate::util::ser::{
125-
BigSize, FixedLengthReader, LengthReadable, MaybeReadable, Readable, ReadableArgs, VecWriter,
126-
Writeable, Writer,
123+
BigSize, FixedLengthReader, LengthReadable, MaybeReadable, Readable, ReadableArgs,
124+
TransactionU16LenLimited, VecWriter, Writeable, Writer,
127125
};
128126
use crate::util::string::UntrustedString;
129127
use crate::util::wakers::{Future, Notifier};
@@ -8290,6 +8288,8 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
82908288
false,
82918289
user_channel_id,
82928290
config_overrides,
8291+
0,
8292+
vec![],
82938293
)
82948294
}
82958295

@@ -8321,14 +8321,82 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
83218321
true,
83228322
user_channel_id,
83238323
config_overrides,
8324+
0,
8325+
vec![],
83248326
)
83258327
}
83268328

8329+
/// Accepts a request to open a dual-funded channel with a contribution provided by us after an
8330+
/// [`Event::OpenChannelRequest`].
8331+
///
8332+
/// The [`Event::OpenChannelRequest::channel_negotiation_type`] field will indicate the open channel
8333+
/// request is for a dual-funded channel when the variant is `InboundChannelFunds::DualFunded`.
8334+
///
8335+
/// The `temporary_channel_id` parameter indicates which inbound channel should be accepted,
8336+
/// and the `counterparty_node_id` parameter is the id of the peer which has requested to open
8337+
/// the channel.
8338+
///
8339+
/// The `user_channel_id` parameter will be provided back in
8340+
/// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
8341+
/// with which `accept_inbound_channel_*` call.
8342+
///
8343+
/// The `funding_inputs` parameter provides the `txin`s along with their previous transactions, and
8344+
/// a corresponding witness weight for each input that will be used to contribute towards our
8345+
/// portion of the channel value. Our contribution will be calculated as the total value of these
8346+
/// inputs minus the fees we need to cover for the interactive funding transaction. The witness
8347+
/// weights must correspond to the witnesses you will provide through [`ChannelManager::funding_transaction_signed`]
8348+
/// after receiving [`Event::FundingTransactionReadyForSigning`].
8349+
///
8350+
/// Note that this method will return an error and reject the channel if it requires support for
8351+
/// zero confirmations.
8352+
// TODO(dual_funding): Discussion on complications with 0conf dual-funded channels where "locking"
8353+
// of UTXOs used for funding would be required and other issues.
8354+
// See https://diyhpl.us/~bryan/irc/bitcoin/bitcoin-dev/linuxfoundation-pipermail/lightning-dev/2023-May/003922.txt
8355+
///
8356+
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
8357+
/// [`Event::OpenChannelRequest::channel_negotiation_type`]: events::Event::OpenChannelRequest::channel_negotiation_type
8358+
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
8359+
/// [`Event::FundingTransactionReadyForSigning`]: events::Event::FundingTransactionReadyForSigning
8360+
/// [`ChannelManager::funding_transaction_signed`]: ChannelManager::funding_transaction_signed
8361+
pub fn accept_inbound_channel_with_contribution(
8362+
&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey,
8363+
user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>,
8364+
our_funding_satoshis: u64, funding_inputs: Vec<(TxIn, Transaction, Weight)>,
8365+
) -> Result<(), APIError> {
8366+
let funding_inputs = Self::length_limit_holder_input_prev_txs(funding_inputs)?;
8367+
self.do_accept_inbound_channel(
8368+
temporary_channel_id,
8369+
counterparty_node_id,
8370+
false,
8371+
user_channel_id,
8372+
config_overrides,
8373+
our_funding_satoshis,
8374+
funding_inputs,
8375+
)
8376+
}
8377+
8378+
fn length_limit_holder_input_prev_txs(
8379+
funding_inputs: Vec<(TxIn, Transaction, Weight)>,
8380+
) -> Result<Vec<(TxIn, TransactionU16LenLimited, Weight)>, APIError> {
8381+
funding_inputs
8382+
.into_iter()
8383+
.map(|(txin, tx, witness_weight)| match TransactionU16LenLimited::new(tx) {
8384+
Ok(tx) => Ok((txin, tx, witness_weight)),
8385+
Err(err) => Err(err),
8386+
})
8387+
.collect::<Result<Vec<(TxIn, TransactionU16LenLimited, Weight)>, ()>>()
8388+
.map_err(|_| APIError::APIMisuseError {
8389+
err: "One or more transactions had a serialized length exceeding 65535 bytes"
8390+
.into(),
8391+
})
8392+
}
8393+
83278394
/// TODO(dual_funding): Allow contributions, pass intended amount and inputs
83288395
#[rustfmt::skip]
83298396
fn do_accept_inbound_channel(
83308397
&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, accept_0conf: bool,
8331-
user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>
8398+
user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>, our_funding_satoshis: u64,
8399+
funding_inputs: Vec<(TxIn, TransactionU16LenLimited, Weight)>
83328400
) -> Result<(), APIError> {
83338401

83348402
let mut config = self.default_configuration.clone();
@@ -8387,7 +8455,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
83878455
&self.channel_type_features(), &peer_state.latest_features,
83888456
&open_channel_msg,
83898457
user_channel_id, &config, best_block_height,
8390-
&self.logger,
8458+
&self.logger, our_funding_satoshis, funding_inputs,
83918459
).map_err(|_| MsgHandleErrInternal::from_chan_no_close(
83928460
ChannelError::Close(
83938461
(
@@ -8674,7 +8742,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
86748742
&self.fee_estimator, &self.entropy_source, &self.signer_provider,
86758743
self.get_our_node_id(), *counterparty_node_id, &self.channel_type_features(),
86768744
&peer_state.latest_features, msg, user_channel_id,
8677-
&self.default_configuration, best_block_height, &self.logger,
8745+
&self.default_configuration, best_block_height, &self.logger, 0, vec![],
86788746
).map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.common_fields.temporary_channel_id))?;
86798747
let message_send_event = MessageSendEvent::SendAcceptChannelV2 {
86808748
node_id: *counterparty_node_id,

lightning/src/ln/dual_funding_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fn do_test_v2_channel_establishment(session: V2ChannelEstablishmentTestSession)
5151
&[session.initiator_input_value_satoshis],
5252
)
5353
.into_iter()
54-
.map(|(txin, tx, _)| (txin, TransactionU16LenLimited::new(tx).unwrap()))
54+
.map(|(txin, tx, weight)| (txin, TransactionU16LenLimited::new(tx).unwrap(), weight))
5555
.collect();
5656

5757
// Alice creates a dual-funded channel as initiator.

0 commit comments

Comments
 (0)