|
15 | 15 |
|
16 | 16 | use core::{cmp, ops::Deref}; |
17 | 17 |
|
| 18 | +use crate::ln::funding::FundingContribution; |
18 | 19 | use crate::ln::types::ChannelId; |
19 | 20 | use crate::prelude::*; |
20 | 21 |
|
| 22 | +use bitcoin::hash_types::Txid; |
21 | 23 | use bitcoin::secp256k1::PublicKey; |
22 | 24 | use bitcoin::transaction::Transaction; |
23 | 25 |
|
@@ -104,19 +106,76 @@ pub enum TransactionType { |
104 | 106 | /// A single sweep transaction may aggregate outputs from multiple channels. |
105 | 107 | channels: Vec<(PublicKey, ChannelId)>, |
106 | 108 | }, |
107 | | - /// A splice transaction modifying an existing channel's funding. |
| 109 | + /// An interactively-negotiated funding transaction. |
108 | 110 | /// |
109 | | - /// A transaction of this type will be broadcast as a result of a [`ChannelManager::splice_channel`] operation. |
| 111 | + /// A transaction of this type will be broadcast as a result of a |
| 112 | + /// [`ChannelManager::splice_channel`] operation, or (once supported) V2 (dual-funded) channel |
| 113 | + /// establishment. The same variant is used for batches of either or both. |
110 | 114 | /// |
111 | 115 | /// [`ChannelManager::splice_channel`]: crate::ln::channelmanager::ChannelManager::splice_channel |
112 | | - Splice { |
113 | | - /// The `node_id` of the channel counterparty. |
114 | | - counterparty_node_id: PublicKey, |
115 | | - /// The ID of the channel being spliced. |
116 | | - channel_id: ChannelId, |
| 116 | + InteractiveFunding { |
| 117 | + /// Every negotiated candidate for this funding in order: the original negotiation |
| 118 | + /// followed by any RBF replacements. The last entry is the candidate being broadcast. |
| 119 | + candidates: Vec<FundingCandidate>, |
117 | 120 | }, |
118 | 121 | } |
119 | 122 |
|
| 123 | +/// A single negotiated candidate within a [`TransactionType::InteractiveFunding`] broadcast. |
| 124 | +/// |
| 125 | +/// The candidate is identified by its [`Txid`] and lists the channels participating in it. A |
| 126 | +/// single candidate funds more than one channel only when batching splices and/or V2 channel |
| 127 | +/// openings (not yet implemented). |
| 128 | +#[derive(Clone, Debug, Hash, PartialEq, Eq)] |
| 129 | +pub struct FundingCandidate { |
| 130 | + /// The txid of this candidate. |
| 131 | + pub txid: Txid, |
| 132 | + /// The channels participating in this candidate. |
| 133 | + pub channels: Vec<ChannelFunding>, |
| 134 | +} |
| 135 | + |
| 136 | +/// Information about a single channel's participation in a [`FundingCandidate`]. |
| 137 | +#[derive(Clone, Debug, Hash, PartialEq, Eq)] |
| 138 | +pub struct ChannelFunding { |
| 139 | + /// The `node_id` of the channel counterparty. |
| 140 | + pub counterparty_node_id: PublicKey, |
| 141 | + /// The ID of the channel. |
| 142 | + pub channel_id: ChannelId, |
| 143 | + /// Whether this channel is being newly established or is an existing channel being spliced. |
| 144 | + pub purpose: FundingPurpose, |
| 145 | + /// The local node's contribution to this channel in this candidate, or `None` if we did |
| 146 | + /// not contribute (e.g., a pure acceptor with zero value added, or a leading RBF round |
| 147 | + /// before we began contributing). |
| 148 | + pub contribution: Option<FundingContribution>, |
| 149 | +} |
| 150 | + |
| 151 | +/// The role of a channel within a [`FundingCandidate`]. |
| 152 | +#[derive(Clone, Debug, Hash, PartialEq, Eq)] |
| 153 | +pub enum FundingPurpose { |
| 154 | + /// The channel is being newly established (V2 dual-funded open). |
| 155 | + Establishment, |
| 156 | + /// An existing channel is being spliced. |
| 157 | + Splice, |
| 158 | +} |
| 159 | + |
| 160 | +// Needed so downstream consumers can persist these without needing to define wrapper types |
| 161 | +// mirroring the type structure. |
| 162 | +impl_writeable_tlv_based!(FundingCandidate, { |
| 163 | + (1, txid, required), |
| 164 | + (3, channels, required_vec), |
| 165 | +}); |
| 166 | + |
| 167 | +impl_writeable_tlv_based!(ChannelFunding, { |
| 168 | + (1, counterparty_node_id, required), |
| 169 | + (3, channel_id, required), |
| 170 | + (5, purpose, required), |
| 171 | + (7, contribution, option), |
| 172 | +}); |
| 173 | + |
| 174 | +impl_writeable_tlv_based_enum!(FundingPurpose, |
| 175 | + (0, Establishment) => {}, |
| 176 | + (2, Splice) => {}, |
| 177 | +); |
| 178 | + |
120 | 179 | // TODO: Define typed abstraction over feerates to handle their conversions. |
121 | 180 | pub(crate) fn compute_feerate_sat_per_1000_weight(fee_sat: u64, weight: u64) -> u32 { |
122 | 181 | (fee_sat * 1000 / weight).try_into().unwrap_or(u32::max_value()) |
|
0 commit comments