Skip to content

Commit e22fa33

Browse files
committed
wip pass funding inputs
1 parent 3d6555c commit e22fa33

File tree

2 files changed

+91
-8
lines changed

2 files changed

+91
-8
lines changed

lightning/src/ln/channel.rs

+37-2
Original file line numberDiff line numberDiff line change
@@ -4997,6 +4997,41 @@ fn get_v2_channel_reserve_satoshis(channel_value_satoshis: u64, dust_limit_satos
49974997
cmp::min(channel_value_satoshis, cmp::max(q, dust_limit_satoshis))
49984998
}
49994999

5000+
fn calculate_our_funding_satoshis(
5001+
is_initiator: bool, funding_inputs: &[(TxIn, TransactionU16LenLimited)], funding_outputs: &[TxOut],
5002+
funding_feerate_sat_per_1000_weight: u32, holder_dust_limit_satoshis: u64,
5003+
) -> Result<u64, APIError> {
5004+
let mut total_input_satoshis = 0u64;
5005+
let mut our_contributed_weight = 0u64;
5006+
5007+
for (idx, input) in funding_inputs.iter().enumerate() {
5008+
if let Some(output) = input.1.as_transaction().output.get(input.0.previous_output.vout as usize) {
5009+
total_input_satoshis = total_input_satoshis.saturating_add(output.value.to_sat());
5010+
our_contributed_weight = our_contributed_weight.saturating_add(estimate_input_weight(output).to_wu());
5011+
} else {
5012+
return Err(APIError::APIMisuseError {
5013+
err: format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn at funding_inputs[{}]",
5014+
input.1.as_transaction().txid(), input.0.previous_output.vout, idx) });
5015+
}
5016+
}
5017+
our_contributed_weight = our_contributed_weight.saturating_add(funding_outputs.iter().fold(0u64, |weight, txout| {
5018+
weight.saturating_add(get_output_weight(&txout.script_pubkey).to_wu())
5019+
}));
5020+
5021+
// If we are the initiator, we must pay for weight of all common fields in the funding transaction.
5022+
if is_initiator {
5023+
our_contributed_weight = our_contributed_weight.saturating_add(TX_COMMON_FIELDS_WEIGHT);
5024+
}
5025+
5026+
let funding_satoshis = total_input_satoshis
5027+
.saturating_sub(fee_for_weight(funding_feerate_sat_per_1000_weight, our_contributed_weight));
5028+
if funding_satoshis < holder_dust_limit_satoshis {
5029+
Ok(0)
5030+
} else {
5031+
Ok(funding_satoshis)
5032+
}
5033+
}
5034+
50005035
/// Estimate our part of the fee of the new funding transaction.
50015036
/// input_count: Number of contributed inputs.
50025037
/// witness_weight: The witness weight for contributed inputs.
@@ -10430,8 +10465,8 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
1043010465
pub fn new_inbound<ES: Deref, F: Deref, L: Deref>(
1043110466
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
1043210467
holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
10433-
their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
10434-
user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
10468+
their_features: &InitFeatures, msg: &msgs::OpenChannelV2, user_id: u128, config: &UserConfig,
10469+
current_chain_height: u32, logger: &L, funding_inputs: Vec<(TxIn, TransactionU16LenLimited, usize)>,
1043510470
) -> Result<Self, ChannelError>
1043610471
where ES::Target: EntropySource,
1043710472
F::Target: FeeEstimator,

lightning/src/ln/channelmanager.rs

+54-6
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use bitcoin::hash_types::{BlockHash, Txid};
3030

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

@@ -84,7 +84,7 @@ use crate::util::config::{ChannelConfig, ChannelConfigUpdate, ChannelConfigOverr
8484
use crate::util::wakers::{Future, Notifier};
8585
use crate::util::scid_utils::fake_scid;
8686
use crate::util::string::UntrustedString;
87-
use crate::util::ser::{BigSize, FixedLengthReader, LengthReadable, Readable, ReadableArgs, MaybeReadable, Writeable, Writer, VecWriter};
87+
use crate::util::ser::{BigSize, FixedLengthReader, LengthReadable, MaybeReadable, Readable, ReadableArgs, TransactionU16LenLimited, VecWriter, Writeable, Writer};
8888
use crate::util::logger::{Level, Logger, WithContext};
8989
use crate::util::errors::APIError;
9090
#[cfg(async_payments)] use {
@@ -7875,7 +7875,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
78757875
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
78767876
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
78777877
pub fn accept_inbound_channel(&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>) -> Result<(), APIError> {
7878-
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, false, user_channel_id, config_overrides)
7878+
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, false, user_channel_id, config_overrides, vec![])
78797879
}
78807880

78817881
/// Accepts a request to open a channel after a [`events::Event::OpenChannelRequest`], treating
@@ -7897,13 +7897,61 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
78977897
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
78987898
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
78997899
pub fn accept_inbound_channel_from_trusted_peer_0conf(&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>) -> Result<(), APIError> {
7900-
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, true, user_channel_id, config_overrides)
7900+
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, true, user_channel_id, config_overrides, vec![])
7901+
}
7902+
7903+
/// Accepts a request to open a dual-funded channel with a contribution provided by us after an
7904+
/// [`Event::OpenChannelRequest`].
7905+
///
7906+
/// The `temporary_channel_id` parameter indicates which inbound channel should be accepted,
7907+
/// and the `counterparty_node_id` parameter is the id of the peer which has requested to open
7908+
/// the channel.
7909+
///
7910+
/// The `user_channel_id` parameter will be provided back in
7911+
/// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond
7912+
/// with which `accept_inbound_channel_*` call.
7913+
///
7914+
/// The `funding_inputs` parameter provides the `txin`s along with their previous transactions, and
7915+
/// a corresponding witness weight for each input that will be used to contribute towards our
7916+
/// portion of the channel value. Our contribution will be calculated as the total value of these
7917+
/// inputs minus the fees we need to cover for the interactive funding transaction. The witness
7918+
/// weights must correspond to the witnesses you will provide through [`ChannelManager::funding_transaction_signed`]
7919+
/// after receiving [`Event::FundingTransactionReadyForSigning`].
7920+
///
7921+
/// Note that this method will return an error and reject the channel if it requires support for
7922+
/// zero confirmations.
7923+
// TODO(dual_funding): Discussion on complications with 0conf dual-funded channels where "locking"
7924+
// of UTXOs used for funding would be required and other issues.
7925+
// See https://diyhpl.us/~bryan/irc/bitcoin/bitcoin-dev/linuxfoundation-pipermail/lightning-dev/2023-May/003922.txt
7926+
///
7927+
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
7928+
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
7929+
/// [`Event::FundingTransactionReadyForSigning`]: events::Event::FundingTransactionReadyForSigning
7930+
/// [`ChannelManager::funding_transaction_signed`]: ChannelManager::funding_transaction_signed
7931+
pub fn accept_inbound_channel_with_contribution(
7932+
&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, user_channel_id: u128,
7933+
config_overrides: Option<ChannelConfigOverrides>, funding_inputs: Vec<(TxIn, Transaction, usize)>
7934+
) -> Result<(), APIError> {
7935+
let funding_inputs = Self::length_limit_holder_input_prev_txs(funding_inputs)?;
7936+
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, false, user_channel_id,
7937+
config_overrides, funding_inputs)
7938+
}
7939+
7940+
fn length_limit_holder_input_prev_txs(funding_inputs: Vec<(TxIn, Transaction, usize)>) -> Result<Vec<(TxIn, TransactionU16LenLimited, usize)>, APIError> {
7941+
funding_inputs.into_iter().map(|(txin, tx, witness_weight)| {
7942+
match TransactionU16LenLimited::new(tx) {
7943+
Ok(tx) => Ok((txin, tx, witness_weight)),
7944+
Err(err) => Err(err)
7945+
}
7946+
}).collect::<Result<Vec<(TxIn, TransactionU16LenLimited, usize)>, ()>>()
7947+
.map_err(|_| APIError::APIMisuseError { err: "One or more transactions had a serialized length exceeding 65535 bytes".into() })
79017948
}
79027949

79037950
/// TODO(dual_funding): Allow contributions, pass intended amount and inputs
79047951
fn do_accept_inbound_channel(
79057952
&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, accept_0conf: bool,
7906-
user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>
7953+
user_channel_id: u128, config_overrides: Option<ChannelConfigOverrides>,
7954+
funding_inputs: Vec<(TxIn, TransactionU16LenLimited, usize)>
79077955
) -> Result<(), APIError> {
79087956

79097957
let mut config = self.default_configuration.clone();
@@ -7962,7 +8010,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
79628010
&self.channel_type_features(), &peer_state.latest_features,
79638011
&open_channel_msg,
79648012
user_channel_id, &config, best_block_height,
7965-
&self.logger,
8013+
&self.logger, funding_inputs,
79668014
).map_err(|_| MsgHandleErrInternal::from_chan_no_close(
79678015
ChannelError::Close(
79688016
(

0 commit comments

Comments
 (0)