Skip to content

Commit 1abe056

Browse files
committed
Define V2 channel structs & move out some shared methods as utils
1 parent e099cba commit 1abe056

File tree

1 file changed

+88
-27
lines changed

1 file changed

+88
-27
lines changed

lightning/src/ln/channel.rs

Lines changed: 88 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use bitcoin::hash_types::{Txid, BlockHash};
2020
use bitcoin::secp256k1::constants::PUBLIC_KEY_SIZE;
2121
use bitcoin::secp256k1::{PublicKey,SecretKey};
2222
use bitcoin::secp256k1::{Secp256k1,ecdsa::Signature};
23-
use bitcoin::secp256k1;
23+
use bitcoin::{secp256k1, TxOut};
2424

2525
use crate::ln::{PaymentPreimage, PaymentHash};
2626
use crate::ln::features::{ChannelTypeFeatures, InitFeatures};
@@ -257,9 +257,11 @@ enum HTLCUpdateAwaitingACK {
257257
/// ChannelReady can then get all remaining flags set on it, until we finish shutdown, then we
258258
/// move on to ShutdownComplete, at which point most calls into this channel are disallowed.
259259
enum ChannelState {
260-
/// Implies we have (or are prepared to) send our open_channel/accept_channel message
260+
/// Implies we have (or are prepared to) send our open_channel/accept_channel message or in the
261+
/// case of V2 establishment, our open_channel2/accept_channel2 message
261262
OurInitSent = 1 << 0,
262-
/// Implies we have received their open_channel/accept_channel message
263+
/// Implies we have received their open_channel/accept_channel message or in the case of
264+
/// V2 establishment, their open_channel2/accept_channel2 message
263265
TheirInitSent = 1 << 1,
264266
/// We have sent funding_created and are awaiting a funding_signed to advance to FundingSent.
265267
/// Note that this is nonsense for an inbound channel as we immediately generate funding_signed
@@ -2009,6 +2011,20 @@ pub(crate) fn get_legacy_default_holder_selected_channel_reserve_satoshis(channe
20092011
cmp::min(channel_value_satoshis, cmp::max(q, 1000))
20102012
}
20112013

2014+
/// Returns a minimum channel reserve value each party needs to maintain, fixed in the spec to a
2015+
/// default of 1% of the total channel value.
2016+
///
2017+
/// Guaranteed to return a value no larger than `channel_value_satoshis`
2018+
///
2019+
/// This is used both for outbound and inbound channels and has lower bound
2020+
/// of `dust_limit_satoshis`.
2021+
fn get_v2_channel_reserve_satoshis(channel_value_satoshis: u64, dust_limit_satoshis: u64) -> u64 {
2022+
let channel_reserve_proportional_millionths = 10_000; // Fixed at 1% in spec.
2023+
let calculated_reserve =
2024+
channel_value_satoshis.saturating_mul(channel_reserve_proportional_millionths) / 1_000_000;
2025+
cmp::min(channel_value_satoshis, cmp::max(calculated_reserve, dust_limit_satoshis))
2026+
}
2027+
20122028
// Get the fee cost in SATS of a commitment tx with a given number of HTLC outputs.
20132029
// Note that num_htlcs should not include dust HTLCs.
20142030
#[inline]
@@ -2024,6 +2040,39 @@ fn commit_tx_fee_msat(feerate_per_kw: u32, num_htlcs: usize, channel_type_featur
20242040
(commitment_tx_base_weight(channel_type_features) + num_htlcs as u64 * COMMITMENT_TX_WEIGHT_PER_HTLC) * feerate_per_kw as u64 / 1000 * 1000
20252041
}
20262042

2043+
/// Used when supplying inputs to contribute to an outbound or inbound dual-funded channel.
2044+
/// It will be included in an interactively constructed funding transaction which must then
2045+
/// be signed by the user.
2046+
#[derive(Clone, Debug, PartialEq, Eq)]
2047+
pub struct DualFundingUtxo {
2048+
/// The outpoint which is spendable.
2049+
pub outpoint: OutPoint,
2050+
/// The output which is referenced by the given outpoint.
2051+
pub output: TxOut,
2052+
}
2053+
2054+
/// A wrapper for the common [`ChannelContext`] that includes dual-funding-specific fields.
2055+
pub(super) struct DualFundingChannelContext<Signer: ChannelSigner> {
2056+
/// The common channel context, not specific to a particular channel establishment version.
2057+
pub common: ChannelContext<Signer>,
2058+
2059+
/// The amount in satoshis we will be contributing to the channel.
2060+
pub our_funding_satoshis: u64,
2061+
/// The UTXOs we will be adding in interactive transaction construction.
2062+
pub our_funding_inputs: Vec<DualFundingUtxo>,
2063+
/// Flag indicating that we require our counterparty to use confirmed inputs for the construction
2064+
/// of the funding transaction.
2065+
pub we_require_confirmed_inputs: bool,
2066+
/// Flag indicating that our counterparty requires us to use confirmed inputs for the construction
2067+
/// of the funding transaction.
2068+
pub counterparty_requires_confirmed_inputs: bool,
2069+
/// The funding transaction locktime suggested by the initiator. If set by us, it is always set
2070+
/// to the current block height to align incentives against fee-sniping.
2071+
pub funding_tx_locktime: u32,
2072+
/// The destination for our change output, if one needs to be added.
2073+
pub our_change_script_pubkey: Script,
2074+
}
2075+
20272076
// TODO: We should refactor this to be an Inbound/OutboundChannel until initial setup handshaking
20282077
// has been completed, and then turn into a Channel to get compiler-time enforcement of things like
20292078
// calling channel_id() before we're set up or things like get_outbound_funding_signed on an
@@ -5499,7 +5548,7 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
54995548
return Err(APIError::APIMisuseError { err: format!("Holder selected channel reserve below implemention limit dust_limit_satoshis {}", holder_selected_channel_reserve_satoshis) });
55005549
}
55015550

5502-
let channel_type = Self::get_initial_channel_type(&config, their_features);
5551+
let channel_type = get_initial_channel_type(&config, their_features);
55035552
debug_assert!(channel_type.is_subset(&channelmanager::provided_channel_type_features(&config)));
55045553

55055554
let feerate = fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::Normal);
@@ -5727,29 +5776,6 @@ impl<Signer: WriteableEcdsaChannelSigner> OutboundV1Channel<Signer> {
57275776
}))
57285777
}
57295778

5730-
fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures {
5731-
// The default channel type (ie the first one we try) depends on whether the channel is
5732-
// public - if it is, we just go with `only_static_remotekey` as it's the only option
5733-
// available. If it's private, we first try `scid_privacy` as it provides better privacy
5734-
// with no other changes, and fall back to `only_static_remotekey`.
5735-
let mut ret = ChannelTypeFeatures::only_static_remote_key();
5736-
if !config.channel_handshake_config.announced_channel &&
5737-
config.channel_handshake_config.negotiate_scid_privacy &&
5738-
their_features.supports_scid_privacy() {
5739-
ret.set_scid_privacy_required();
5740-
}
5741-
5742-
// Optionally, if the user would like to negotiate the `anchors_zero_fee_htlc_tx` option, we
5743-
// set it now. If they don't understand it, we'll fall back to our default of
5744-
// `only_static_remotekey`.
5745-
if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
5746-
their_features.supports_anchors_zero_fee_htlc_tx() {
5747-
ret.set_anchors_zero_fee_htlc_tx_required();
5748-
}
5749-
5750-
ret
5751-
}
5752-
57535779
/// If we receive an error message, it may only be a rejection of the channel type we tried,
57545780
/// not of our ability to open any channel at all. Thus, on error, we should first call this
57555781
/// and see if we get a new `OpenChannel` message, otherwise the channel is failed.
@@ -6498,6 +6524,41 @@ impl<Signer: WriteableEcdsaChannelSigner> InboundV1Channel<Signer> {
64986524
}
64996525
}
65006526

6527+
// A not-yet-funded outbound (from holder) channel using V2 channel establishment.
6528+
pub(super) struct OutboundV2Channel<Signer: ChannelSigner> {
6529+
pub context: DualFundingChannelContext<Signer>,
6530+
}
6531+
6532+
// A not-yet-funded inbound (from counterparty) channel using V2 channel establishment.
6533+
pub(super) struct InboundV2Channel<Signer: ChannelSigner> {
6534+
pub context: DualFundingChannelContext<Signer>,
6535+
}
6536+
6537+
// Prefunded channel utilities
6538+
6539+
fn get_initial_channel_type(config: &UserConfig, their_features: &InitFeatures) -> ChannelTypeFeatures {
6540+
// The default channel type (ie the first one we try) depends on whether the channel is
6541+
// public - if it is, we just go with `only_static_remotekey` as it's the only option
6542+
// available. If it's private, we first try `scid_privacy` as it provides better privacy
6543+
// with no other changes, and fall back to `only_static_remotekey`.
6544+
let mut ret = ChannelTypeFeatures::only_static_remote_key();
6545+
if !config.channel_handshake_config.announced_channel &&
6546+
config.channel_handshake_config.negotiate_scid_privacy &&
6547+
their_features.supports_scid_privacy() {
6548+
ret.set_scid_privacy_required();
6549+
}
6550+
6551+
// Optionally, if the user would like to negotiate the `anchors_zero_fee_htlc_tx` option, we
6552+
// set it now. If they don't understand it, we'll fall back to our default of
6553+
// `only_static_remotekey`.
6554+
if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
6555+
their_features.supports_anchors_zero_fee_htlc_tx() {
6556+
ret.set_anchors_zero_fee_htlc_tx_required();
6557+
}
6558+
6559+
ret
6560+
}
6561+
65016562
const SERIALIZATION_VERSION: u8 = 3;
65026563
const MIN_SERIALIZATION_VERSION: u8 = 2;
65036564

0 commit comments

Comments
 (0)