mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-03-15 15:39:09 +01:00
Merge pull request #3558 from optout21/funding-fee-estimation
Include base input fee in fee, in calculate_our_funding_satoshis()
This commit is contained in:
commit
7cf95e17ff
3 changed files with 83 additions and 70 deletions
|
@ -57,6 +57,7 @@ use crate::chain::transaction::{OutPoint, TransactionData};
|
||||||
use crate::sign::ecdsa::EcdsaChannelSigner;
|
use crate::sign::ecdsa::EcdsaChannelSigner;
|
||||||
use crate::sign::{EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient};
|
use crate::sign::{EntropySource, ChannelSigner, SignerProvider, NodeSigner, Recipient};
|
||||||
use crate::events::{ClosureReason, Event};
|
use crate::events::{ClosureReason, Event};
|
||||||
|
use crate::events::bump_transaction::BASE_INPUT_WEIGHT;
|
||||||
use crate::routing::gossip::NodeId;
|
use crate::routing::gossip::NodeId;
|
||||||
use crate::util::ser::{Readable, ReadableArgs, TransactionU16LenLimited, Writeable, Writer};
|
use crate::util::ser::{Readable, ReadableArgs, TransactionU16LenLimited, Writeable, Writer};
|
||||||
use crate::util::logger::{Logger, Record, WithContext};
|
use crate::util::logger::{Logger, Record, WithContext};
|
||||||
|
@ -4470,32 +4471,25 @@ fn get_v2_channel_reserve_satoshis(channel_value_satoshis: u64, dust_limit_satos
|
||||||
cmp::min(channel_value_satoshis, cmp::max(q, dust_limit_satoshis))
|
cmp::min(channel_value_satoshis, cmp::max(q, dust_limit_satoshis))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
|
/// Estimate our part of the fee of the new funding transaction.
|
||||||
pub(super) fn calculate_our_funding_satoshis(
|
/// input_count: Number of contributed inputs.
|
||||||
is_initiator: bool, funding_inputs: &[(TxIn, TransactionU16LenLimited)],
|
/// witness_weight: The witness weight for contributed inputs.
|
||||||
total_witness_weight: Weight, funding_feerate_sat_per_1000_weight: u32,
|
#[allow(dead_code)] // TODO(dual_funding): TODO(splicing): Remove allow once used.
|
||||||
holder_dust_limit_satoshis: u64,
|
fn estimate_v2_funding_transaction_fee(
|
||||||
) -> Result<u64, APIError> {
|
is_initiator: bool, input_count: usize, witness_weight: Weight,
|
||||||
let mut total_input_satoshis = 0u64;
|
funding_feerate_sat_per_1000_weight: u32,
|
||||||
let mut our_contributed_weight = 0u64;
|
) -> u64 {
|
||||||
|
// Inputs
|
||||||
|
let mut weight = (input_count as u64) * BASE_INPUT_WEIGHT;
|
||||||
|
|
||||||
for (idx, input) in funding_inputs.iter().enumerate() {
|
// Witnesses
|
||||||
if let Some(output) = input.1.as_transaction().output.get(input.0.previous_output.vout as usize) {
|
weight = weight.saturating_add(witness_weight.to_wu());
|
||||||
total_input_satoshis = total_input_satoshis.saturating_add(output.value.to_sat());
|
|
||||||
} else {
|
|
||||||
return Err(APIError::APIMisuseError {
|
|
||||||
err: format!("Transaction with txid {} does not have an output with vout of {} corresponding to TxIn at funding_inputs[{}]",
|
|
||||||
input.1.as_transaction().compute_txid(), input.0.previous_output.vout, idx) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
our_contributed_weight = our_contributed_weight.saturating_add(total_witness_weight.to_wu());
|
|
||||||
|
|
||||||
// If we are the initiator, we must pay for weight of all common fields in the funding transaction.
|
// If we are the initiator, we must pay for weight of all common fields in the funding transaction.
|
||||||
if is_initiator {
|
if is_initiator {
|
||||||
our_contributed_weight = our_contributed_weight
|
weight = weight
|
||||||
.saturating_add(TX_COMMON_FIELDS_WEIGHT)
|
.saturating_add(TX_COMMON_FIELDS_WEIGHT)
|
||||||
// The weight of a P2WSH output to be added later.
|
// The weight of the funding output, a P2WSH output
|
||||||
//
|
|
||||||
// NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
|
// NOTE: The witness script hash given here is irrelevant as it's a fixed size and we just want
|
||||||
// to calculate the contributed weight, so we use an all-zero hash.
|
// to calculate the contributed weight, so we use an all-zero hash.
|
||||||
.saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
|
.saturating_add(get_output_weight(&ScriptBuf::new_p2wsh(
|
||||||
|
@ -4503,13 +4497,7 @@ pub(super) fn calculate_our_funding_satoshis(
|
||||||
)).to_wu())
|
)).to_wu())
|
||||||
}
|
}
|
||||||
|
|
||||||
let funding_satoshis = total_input_satoshis
|
fee_for_weight(funding_feerate_sat_per_1000_weight, weight)
|
||||||
.saturating_sub(fee_for_weight(funding_feerate_sat_per_1000_weight, our_contributed_weight));
|
|
||||||
if funding_satoshis < holder_dust_limit_satoshis {
|
|
||||||
Ok(0)
|
|
||||||
} else {
|
|
||||||
Ok(funding_satoshis)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Context for dual-funded channels.
|
/// Context for dual-funded channels.
|
||||||
|
@ -9249,27 +9237,23 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
|
||||||
|
|
||||||
/// Creates a new dual-funded channel from a remote side's request for one.
|
/// Creates a new dual-funded channel from a remote side's request for one.
|
||||||
/// Assumes chain_hash has already been checked and corresponds with what we expect!
|
/// Assumes chain_hash has already been checked and corresponds with what we expect!
|
||||||
|
/// TODO(dual_funding): Allow contributions, pass intended amount and inputs
|
||||||
#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
|
#[allow(dead_code)] // TODO(dual_funding): Remove once V2 channels is enabled.
|
||||||
pub fn new_inbound<ES: Deref, F: Deref, L: Deref>(
|
pub fn new_inbound<ES: Deref, F: Deref, L: Deref>(
|
||||||
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
|
fee_estimator: &LowerBoundedFeeEstimator<F>, entropy_source: &ES, signer_provider: &SP,
|
||||||
holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
|
holder_node_id: PublicKey, counterparty_node_id: PublicKey, our_supported_features: &ChannelTypeFeatures,
|
||||||
their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
|
their_features: &InitFeatures, msg: &msgs::OpenChannelV2,
|
||||||
funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>, total_witness_weight: Weight,
|
|
||||||
user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
|
user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
|
||||||
) -> Result<Self, ChannelError>
|
) -> Result<Self, ChannelError>
|
||||||
where ES::Target: EntropySource,
|
where ES::Target: EntropySource,
|
||||||
F::Target: FeeEstimator,
|
F::Target: FeeEstimator,
|
||||||
L::Target: Logger,
|
L::Target: Logger,
|
||||||
{
|
{
|
||||||
let funding_satoshis = calculate_our_funding_satoshis(
|
// TODO(dual_funding): Take these as input once supported
|
||||||
false, &funding_inputs, total_witness_weight, msg.funding_feerate_sat_per_1000_weight,
|
let our_funding_satoshis = 0u64;
|
||||||
msg.common_fields.dust_limit_satoshis
|
let our_funding_inputs = Vec::new();
|
||||||
).map_err(|_| ChannelError::Close(
|
|
||||||
(
|
let channel_value_satoshis = our_funding_satoshis.saturating_add(msg.common_fields.funding_satoshis);
|
||||||
"Failed to accept channel".to_string(),
|
|
||||||
ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(false) },
|
|
||||||
)))?;
|
|
||||||
let channel_value_satoshis = funding_satoshis.saturating_add(msg.common_fields.funding_satoshis);
|
|
||||||
let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
|
let counterparty_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
|
||||||
channel_value_satoshis, msg.common_fields.dust_limit_satoshis);
|
channel_value_satoshis, msg.common_fields.dust_limit_satoshis);
|
||||||
let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
|
let holder_selected_channel_reserve_satoshis = get_v2_channel_reserve_satoshis(
|
||||||
|
@ -9303,7 +9287,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
|
||||||
logger,
|
logger,
|
||||||
false,
|
false,
|
||||||
|
|
||||||
funding_satoshis,
|
our_funding_satoshis,
|
||||||
|
|
||||||
counterparty_pubkeys,
|
counterparty_pubkeys,
|
||||||
channel_type,
|
channel_type,
|
||||||
|
@ -9318,10 +9302,10 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
|
||||||
context.channel_id = channel_id;
|
context.channel_id = channel_id;
|
||||||
|
|
||||||
let dual_funding_context = DualFundingChannelContext {
|
let dual_funding_context = DualFundingChannelContext {
|
||||||
our_funding_satoshis: funding_satoshis,
|
our_funding_satoshis: our_funding_satoshis,
|
||||||
funding_tx_locktime: LockTime::from_consensus(msg.locktime),
|
funding_tx_locktime: LockTime::from_consensus(msg.locktime),
|
||||||
funding_feerate_sat_per_1000_weight: msg.funding_feerate_sat_per_1000_weight,
|
funding_feerate_sat_per_1000_weight: msg.funding_feerate_sat_per_1000_weight,
|
||||||
our_funding_inputs: funding_inputs.clone(),
|
our_funding_inputs: our_funding_inputs.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let interactive_tx_constructor = Some(InteractiveTxConstructor::new(
|
let interactive_tx_constructor = Some(InteractiveTxConstructor::new(
|
||||||
|
@ -9333,7 +9317,7 @@ impl<SP: Deref> PendingV2Channel<SP> where SP::Target: SignerProvider {
|
||||||
feerate_sat_per_kw: dual_funding_context.funding_feerate_sat_per_1000_weight,
|
feerate_sat_per_kw: dual_funding_context.funding_feerate_sat_per_1000_weight,
|
||||||
funding_tx_locktime: dual_funding_context.funding_tx_locktime,
|
funding_tx_locktime: dual_funding_context.funding_tx_locktime,
|
||||||
is_initiator: false,
|
is_initiator: false,
|
||||||
inputs_to_contribute: funding_inputs,
|
inputs_to_contribute: our_funding_inputs,
|
||||||
outputs_to_contribute: Vec::new(),
|
outputs_to_contribute: Vec::new(),
|
||||||
expected_remote_shared_funding_output: Some((context.get_funding_redeemscript().to_p2wsh(), context.channel_value_satoshis)),
|
expected_remote_shared_funding_output: Some((context.get_funding_redeemscript().to_p2wsh(), context.channel_value_satoshis)),
|
||||||
}
|
}
|
||||||
|
@ -12238,4 +12222,40 @@ mod tests {
|
||||||
assert_eq!(node_a_chan.context.channel_state, ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::THEIR_CHANNEL_READY));
|
assert_eq!(node_a_chan.context.channel_state, ChannelState::AwaitingChannelReady(AwaitingChannelReadyFlags::THEIR_CHANNEL_READY));
|
||||||
assert!(node_a_chan.check_get_channel_ready(0, &&logger).is_some());
|
assert!(node_a_chan.check_get_channel_ready(0, &&logger).is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_estimate_v2_funding_transaction_fee() {
|
||||||
|
use crate::ln::channel::estimate_v2_funding_transaction_fee;
|
||||||
|
use bitcoin::Weight;
|
||||||
|
|
||||||
|
// 2 inputs with weight 300, initiator, 2000 sat/kw feerate
|
||||||
|
assert_eq!(
|
||||||
|
estimate_v2_funding_transaction_fee(true, 2, Weight::from_wu(300), 2000),
|
||||||
|
1668
|
||||||
|
);
|
||||||
|
|
||||||
|
// higher feerate
|
||||||
|
assert_eq!(
|
||||||
|
estimate_v2_funding_transaction_fee(true, 2, Weight::from_wu(300), 3000),
|
||||||
|
2502
|
||||||
|
);
|
||||||
|
|
||||||
|
// only 1 input
|
||||||
|
assert_eq!(
|
||||||
|
estimate_v2_funding_transaction_fee(true, 1, Weight::from_wu(300), 2000),
|
||||||
|
1348
|
||||||
|
);
|
||||||
|
|
||||||
|
// 0 input weight
|
||||||
|
assert_eq!(
|
||||||
|
estimate_v2_funding_transaction_fee(true, 1, Weight::from_wu(0), 2000),
|
||||||
|
748
|
||||||
|
);
|
||||||
|
|
||||||
|
// not initiator
|
||||||
|
assert_eq!(
|
||||||
|
estimate_v2_funding_transaction_fee(false, 1, Weight::from_wu(0), 2000),
|
||||||
|
320
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
//! imply it needs to fail HTLCs/payments/channels it manages).
|
//! imply it needs to fail HTLCs/payments/channels it manages).
|
||||||
|
|
||||||
use bitcoin::block::Header;
|
use bitcoin::block::Header;
|
||||||
use bitcoin::transaction::{Transaction, TxIn};
|
use bitcoin::transaction::Transaction;
|
||||||
use bitcoin::constants::ChainHash;
|
use bitcoin::constants::ChainHash;
|
||||||
use bitcoin::key::constants::SECRET_KEY_SIZE;
|
use bitcoin::key::constants::SECRET_KEY_SIZE;
|
||||||
use bitcoin::network::Network;
|
use bitcoin::network::Network;
|
||||||
|
@ -30,7 +30,7 @@ use bitcoin::hash_types::{BlockHash, Txid};
|
||||||
|
|
||||||
use bitcoin::secp256k1::{SecretKey,PublicKey};
|
use bitcoin::secp256k1::{SecretKey,PublicKey};
|
||||||
use bitcoin::secp256k1::Secp256k1;
|
use bitcoin::secp256k1::Secp256k1;
|
||||||
use bitcoin::{secp256k1, Sequence, Weight};
|
use bitcoin::{secp256k1, Sequence};
|
||||||
|
|
||||||
use crate::events::FundingInfo;
|
use crate::events::FundingInfo;
|
||||||
use crate::blinded_path::message::{AsyncPaymentsContext, MessageContext, OffersContext};
|
use crate::blinded_path::message::{AsyncPaymentsContext, MessageContext, OffersContext};
|
||||||
|
@ -83,7 +83,6 @@ use crate::util::wakers::{Future, Notifier};
|
||||||
use crate::util::scid_utils::fake_scid;
|
use crate::util::scid_utils::fake_scid;
|
||||||
use crate::util::string::UntrustedString;
|
use crate::util::string::UntrustedString;
|
||||||
use crate::util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer, VecWriter};
|
use crate::util::ser::{BigSize, FixedLengthReader, Readable, ReadableArgs, MaybeReadable, Writeable, Writer, VecWriter};
|
||||||
use crate::util::ser::TransactionU16LenLimited;
|
|
||||||
use crate::util::logger::{Level, Logger, WithContext};
|
use crate::util::logger::{Level, Logger, WithContext};
|
||||||
use crate::util::errors::APIError;
|
use crate::util::errors::APIError;
|
||||||
#[cfg(async_payments)] use {
|
#[cfg(async_payments)] use {
|
||||||
|
@ -7700,7 +7699,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
|
||||||
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
|
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
|
||||||
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
|
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
|
||||||
pub fn accept_inbound_channel(&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> {
|
pub fn accept_inbound_channel(&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> {
|
||||||
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, false, user_channel_id, vec![], Weight::from_wu(0))
|
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, false, user_channel_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Accepts a request to open a channel after a [`events::Event::OpenChannelRequest`], treating
|
/// Accepts a request to open a channel after a [`events::Event::OpenChannelRequest`], treating
|
||||||
|
@ -7722,13 +7721,13 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
|
||||||
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
|
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
|
||||||
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
|
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
|
||||||
pub fn accept_inbound_channel_from_trusted_peer_0conf(&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> {
|
pub fn accept_inbound_channel_from_trusted_peer_0conf(&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> {
|
||||||
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, true, user_channel_id, vec![], Weight::from_wu(0))
|
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, true, user_channel_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TODO(dual_funding): Allow contributions, pass intended amount and inputs
|
||||||
fn do_accept_inbound_channel(
|
fn do_accept_inbound_channel(
|
||||||
&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, accept_0conf: bool,
|
&self, temporary_channel_id: &ChannelId, counterparty_node_id: &PublicKey, accept_0conf: bool,
|
||||||
user_channel_id: u128, _funding_inputs: Vec<(TxIn, TransactionU16LenLimited)>,
|
user_channel_id: u128,
|
||||||
_total_witness_weight: Weight,
|
|
||||||
) -> Result<(), APIError> {
|
) -> Result<(), APIError> {
|
||||||
let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(*temporary_channel_id), None);
|
let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(*temporary_channel_id), None);
|
||||||
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
|
||||||
|
@ -7778,7 +7777,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
|
||||||
&self.fee_estimator, &self.entropy_source, &self.signer_provider,
|
&self.fee_estimator, &self.entropy_source, &self.signer_provider,
|
||||||
self.get_our_node_id(), *counterparty_node_id,
|
self.get_our_node_id(), *counterparty_node_id,
|
||||||
&self.channel_type_features(), &peer_state.latest_features,
|
&self.channel_type_features(), &peer_state.latest_features,
|
||||||
&open_channel_msg, _funding_inputs, _total_witness_weight,
|
&open_channel_msg,
|
||||||
user_channel_id, &self.default_configuration, best_block_height,
|
user_channel_id, &self.default_configuration, best_block_height,
|
||||||
&self.logger,
|
&self.logger,
|
||||||
).map_err(|_| MsgHandleErrInternal::from_chan_no_close(
|
).map_err(|_| MsgHandleErrInternal::from_chan_no_close(
|
||||||
|
@ -8064,7 +8063,7 @@ This indicates a bug inside LDK. Please report this error at https://github.com/
|
||||||
let channel = PendingV2Channel::new_inbound(
|
let channel = PendingV2Channel::new_inbound(
|
||||||
&self.fee_estimator, &self.entropy_source, &self.signer_provider,
|
&self.fee_estimator, &self.entropy_source, &self.signer_provider,
|
||||||
self.get_our_node_id(), *counterparty_node_id, &self.channel_type_features(),
|
self.get_our_node_id(), *counterparty_node_id, &self.channel_type_features(),
|
||||||
&peer_state.latest_features, msg, vec![], Weight::from_wu(0), user_channel_id,
|
&peer_state.latest_features, msg, user_channel_id,
|
||||||
&self.default_configuration, best_block_height, &self.logger,
|
&self.default_configuration, best_block_height, &self.logger,
|
||||||
).map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.common_fields.temporary_channel_id))?;
|
).map_err(|e| MsgHandleErrInternal::from_chan_no_close(e, msg.common_fields.temporary_channel_id))?;
|
||||||
let message_send_event = events::MessageSendEvent::SendAcceptChannelV2 {
|
let message_send_event = events::MessageSendEvent::SendAcceptChannelV2 {
|
||||||
|
|
|
@ -11,30 +11,28 @@
|
||||||
|
|
||||||
#[cfg(dual_funding)]
|
#[cfg(dual_funding)]
|
||||||
use {
|
use {
|
||||||
crate::chain::chaininterface::{ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator},
|
crate::chain::chaininterface::{ConfirmationTarget, LowerBoundedFeeEstimator},
|
||||||
crate::events::{Event, MessageSendEvent, MessageSendEventsProvider},
|
crate::events::{Event, MessageSendEvent, MessageSendEventsProvider},
|
||||||
crate::ln::chan_utils::{
|
crate::ln::chan_utils::{
|
||||||
make_funding_redeemscript, ChannelPublicKeys, ChannelTransactionParameters,
|
make_funding_redeemscript, ChannelPublicKeys, ChannelTransactionParameters,
|
||||||
CounterpartyChannelTransactionParameters,
|
CounterpartyChannelTransactionParameters,
|
||||||
},
|
},
|
||||||
crate::ln::channel::{
|
crate::ln::channel::PendingV2Channel,
|
||||||
calculate_our_funding_satoshis, PendingV2Channel, MIN_CHAN_DUST_LIMIT_SATOSHIS,
|
|
||||||
},
|
|
||||||
crate::ln::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint, RevocationBasepoint},
|
crate::ln::channel_keys::{DelayedPaymentBasepoint, HtlcBasepoint, RevocationBasepoint},
|
||||||
crate::ln::functional_test_utils::*,
|
crate::ln::functional_test_utils::*,
|
||||||
crate::ln::msgs::ChannelMessageHandler,
|
crate::ln::msgs::ChannelMessageHandler,
|
||||||
crate::ln::msgs::{CommitmentSigned, TxAddInput, TxAddOutput, TxComplete},
|
crate::ln::msgs::{CommitmentSigned, TxAddInput, TxAddOutput, TxComplete},
|
||||||
crate::ln::types::ChannelId,
|
crate::ln::types::ChannelId,
|
||||||
crate::prelude::*,
|
crate::prelude::*,
|
||||||
crate::sign::{ChannelSigner as _, P2WPKH_WITNESS_WEIGHT},
|
crate::sign::ChannelSigner as _,
|
||||||
crate::util::ser::TransactionU16LenLimited,
|
crate::util::ser::TransactionU16LenLimited,
|
||||||
crate::util::test_utils,
|
crate::util::test_utils,
|
||||||
bitcoin::Weight,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(dual_funding)]
|
#[cfg(dual_funding)]
|
||||||
// Dual-funding: V2 Channel Establishment Tests
|
// Dual-funding: V2 Channel Establishment Tests
|
||||||
struct V2ChannelEstablishmentTestSession {
|
struct V2ChannelEstablishmentTestSession {
|
||||||
|
funding_input_sats: u64,
|
||||||
initiator_input_value_satoshis: u64,
|
initiator_input_value_satoshis: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,17 +58,7 @@ fn do_test_v2_channel_establishment(
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Alice creates a dual-funded channel as initiator.
|
// Alice creates a dual-funded channel as initiator.
|
||||||
let funding_feerate = node_cfgs[0]
|
let funding_satoshis = session.funding_input_sats;
|
||||||
.fee_estimator
|
|
||||||
.get_est_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee);
|
|
||||||
let funding_satoshis = calculate_our_funding_satoshis(
|
|
||||||
true,
|
|
||||||
&initiator_funding_inputs[..],
|
|
||||||
Weight::from_wu(P2WPKH_WITNESS_WEIGHT),
|
|
||||||
funding_feerate,
|
|
||||||
MIN_CHAN_DUST_LIMIT_SATOSHIS,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
let mut channel = PendingV2Channel::new_outbound(
|
let mut channel = PendingV2Channel::new_outbound(
|
||||||
&LowerBoundedFeeEstimator(node_cfgs[0].fee_estimator),
|
&LowerBoundedFeeEstimator(node_cfgs[0].fee_estimator),
|
||||||
&nodes[0].node.entropy_source,
|
&nodes[0].node.entropy_source,
|
||||||
|
@ -263,12 +251,18 @@ fn do_test_v2_channel_establishment(
|
||||||
fn test_v2_channel_establishment() {
|
fn test_v2_channel_establishment() {
|
||||||
// Only initiator contributes, no persist pending
|
// Only initiator contributes, no persist pending
|
||||||
do_test_v2_channel_establishment(
|
do_test_v2_channel_establishment(
|
||||||
V2ChannelEstablishmentTestSession { initiator_input_value_satoshis: 100_000 },
|
V2ChannelEstablishmentTestSession {
|
||||||
|
funding_input_sats: 100_000,
|
||||||
|
initiator_input_value_satoshis: 150_000,
|
||||||
|
},
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
// Only initiator contributes, persist pending
|
// Only initiator contributes, persist pending
|
||||||
do_test_v2_channel_establishment(
|
do_test_v2_channel_establishment(
|
||||||
V2ChannelEstablishmentTestSession { initiator_input_value_satoshis: 100_000 },
|
V2ChannelEstablishmentTestSession {
|
||||||
|
funding_input_sats: 100_000,
|
||||||
|
initiator_input_value_satoshis: 150_000,
|
||||||
|
},
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue