forked from lightningdevkit/rust-lightning
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchaininterface.rs
More file actions
350 lines (328 loc) · 16.9 KB
/
chaininterface.rs
File metadata and controls
350 lines (328 loc) · 16.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
// This file is Copyright its original authors, visible in version control
// history.
//
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
// You may not use this file except in accordance with one or both of these
// licenses.
//! Traits and utility impls which allow other parts of rust-lightning to interact with the
//! blockchain.
//!
//! Includes traits for monitoring and receiving notifications of new blocks and block
//! disconnections, transaction broadcasting, and feerate information requests.
use core::{cmp, ops::Deref};
use crate::ln::types::ChannelId;
use crate::prelude::*;
use bitcoin::transaction::Transaction;
/// Represents the class of transaction being broadcast.
///
/// This is used to provide context about the type of transaction being broadcast, which may be
/// useful for logging, filtering, or prioritization purposes.
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum TransactionType {
/// A funding transaction establishing a new channel.
///
/// If we initiated the channel the transaction given to
/// [`ChannelManager::funding_transaction_generated`] will be broadcast with this type.
///
/// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated
Funding {
/// The IDs of the channels being funded.
///
/// A single funding transaction may establish multiple channels when using batch funding.
channel_ids: Vec<ChannelId>,
},
/// A transaction cooperatively closing a channel.
///
/// A transaction of this type will be broadcast when cooperatively closing a channel via
/// [`ChannelManager::close_channel`] or if the counterparty closes the channel.
///
/// [`ChannelManager::close_channel`]: crate::ln::channelmanager::ChannelManager::close_channel
CooperativeClose {
/// The ID of the channel being closed.
channel_id: ChannelId,
},
/// A transaction being broadcast to force-close the channel.
///
/// A transaction of this type will be broadcast when unilaterally closing a channel via
/// [`ChannelManager::force_close_broadcasting_latest_txn`] or if the counterparty force-closes
/// the channel.
///
/// [`ChannelManager::force_close_broadcasting_latest_txn`]: crate::ln::channelmanager::ChannelManager::force_close_broadcasting_latest_txn
UnilateralClose {
/// The ID of the channel being force-closed.
channel_id: ChannelId,
},
/// An anchor bumping transaction used for CPFP fee-bumping a closing transaction.
///
/// This will be broadcast after an anchor channel has been closed. See
/// [`BumpTransactionEvent`] for more information.
///
/// [`BumpTransactionEvent`]: crate::events::bump_transaction::BumpTransactionEvent
AnchorBump {
/// The ID of the channel whose closing transaction is being fee-bumped.
channel_id: ChannelId,
},
/// A transaction which is resolving an output spendable by both us and our counterparty.
///
/// When a channel closes via the unilateral close path, there may be transaction outputs which
/// are spendable by either our counterparty or us and represent some lightning state. In order
/// to resolve that state, the [`ChannelMonitor`] will spend any such outputs, ensuring funds
/// are only available to us prior to generating an [`Event::SpendableOutputs`]. This
/// transaction is one such transaction - resolving in-flight HTLCs or punishing our
/// counterparty if they broadcasted an outdated state.
///
/// [`ChannelMonitor`]: crate::chain::ChannelMonitor
/// [`Event::SpendableOutputs`]: crate::events::Event::SpendableOutputs
Claim {
/// The ID of the channel from which outputs are being claimed.
channel_id: ChannelId,
},
/// A transaction generated by the [`OutputSweeper`], sweeping [`SpendableOutputDescriptor`]s
/// to the user's wallet.
///
/// [`OutputSweeper`]: crate::util::sweep::OutputSweeper
/// [`SpendableOutputDescriptor`]: crate::sign::SpendableOutputDescriptor
Sweep {
/// The IDs of the channels from which outputs are being swept, if known.
///
/// A single sweep transaction may aggregate outputs from multiple channels.
channel_ids: Vec<ChannelId>,
},
/// A splice transaction modifying an existing channel's funding.
///
/// A transaction of this type will be broadcast as a result of a [`ChannelManager::splice_channel`] operation.
///
/// [`ChannelManager::splice_channel`]: crate::ln::channelmanager::ChannelManager::splice_channel
Splice {
/// The ID of the channel being spliced.
channel_id: ChannelId,
},
}
// TODO: Define typed abstraction over feerates to handle their conversions.
pub(crate) fn compute_feerate_sat_per_1000_weight(fee_sat: u64, weight: u64) -> u32 {
(fee_sat * 1000 / weight).try_into().unwrap_or(u32::max_value())
}
pub(crate) const fn fee_for_weight(feerate_sat_per_1000_weight: u32, weight: u64) -> u64 {
(feerate_sat_per_1000_weight as u64 * weight).div_ceil(1000)
}
/// An interface to send a transaction to the Bitcoin network.
pub trait BroadcasterInterface {
/// Sends a list of transactions out to (hopefully) be mined.
/// This only needs to handle the actual broadcasting of transactions, LDK will automatically
/// rebroadcast transactions that haven't made it into a block.
///
/// In some cases LDK may attempt to broadcast a transaction which double-spends another
/// and this isn't a bug and can be safely ignored.
///
/// If more than one transaction is given, these transactions MUST be a
/// single child and its parents and be broadcast together as a package
/// (see the [`submitpackage`](https://bitcoincore.org/en/doc/30.0.0/rpc/rawtransactions/submitpackage)
/// Bitcoin Core RPC).
///
/// Implementations MUST NOT assume any topological order on the transactions.
///
/// Bitcoin transaction packages are defined in BIP 331 and here:
/// <https://github.com/bitcoin/bitcoin/blob/master/doc/policy/packages.md>
///
/// Each transaction is paired with a [`TransactionType`] indicating the class of transaction
/// being broadcast, which may be useful for logging, filtering, or prioritization.
fn broadcast_transactions(&self, txs: &[(&Transaction, TransactionType)]);
}
impl<T: BroadcasterInterface + ?Sized, B: Deref<Target = T>> BroadcasterInterface for B {
fn broadcast_transactions(&self, txs: &[(&Transaction, TransactionType)]) {
self.deref().broadcast_transactions(txs)
}
}
/// An enum that represents the priority at which we want a transaction to confirm used for feerate
/// estimation.
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
pub enum ConfirmationTarget {
/// The most aggressive feerate estimate which we think is reasonable.
///
/// This is used to sanity-check our counterparty's feerates and should be as conservative as
/// possible to ensure that we don't confuse a peer using a very conservative estimator for one
/// trying to burn channel balance to dust. To ensure that this is never lower than an honest
/// counterparty's feerate estimate you may wish to use a value which is higher than your
/// maximum feerate estimate, for example by adding a constant few-hundred or few-thousand
/// sats-per-kW.
MaximumFeeEstimate,
/// We have some funds available on chain which we need to spend prior to some expiry time at
/// which point our counterparty may be able to steal them.
///
/// Generally we have in the high tens to low hundreds of blocks to get our transaction
/// on-chain (it doesn't have to happen in the next few blocks!), but we shouldn't risk too low
/// a fee - this should be a relatively high priority feerate.
UrgentOnChainSweep,
/// This is the lowest feerate we will allow our channel counterparty to have in an anchor
/// channel in order to close the channel if a channel party goes away.
///
/// This needs to be sufficient to get into the mempool when the channel needs to
/// be force-closed. Setting too high may result in force-closures if our counterparty attempts
/// to use a lower feerate. Because this is for anchor channels, we can always bump the feerate
/// later; the feerate here only needs to be sufficient to enter the mempool.
///
/// A good estimate is the expected mempool minimum at the time of force-closure. Obviously this
/// is not an estimate which is very easy to calculate because we do not know the future. Using
/// a simple long-term fee estimate or tracking of the mempool minimum is a good approach to
/// ensure you can always close the channel. A future change to Bitcoin's P2P network
/// (package relay) may obviate the need for this entirely.
MinAllowedAnchorChannelRemoteFee,
/// The lowest feerate we will allow our channel counterparty to have in a non-anchor channel.
///
/// This is the feerate on the transaction which we (or our counterparty) will broadcast in
/// order to close the channel if a channel party goes away. Setting this value too high will
/// cause immediate force-closures in order to avoid having an unbroadcastable state.
///
/// This feerate represents the fee we pick now, which must be sufficient to enter a block at an
/// arbitrary time in the future. Obviously this is not an estimate which is very easy to
/// calculate. This can leave channels subject to being unable to close if feerates rise, and in
/// general you should prefer anchor channels to ensure you can increase the feerate when the
/// transactions need broadcasting.
///
/// Do note some fee estimators round up to the next full sat/vbyte (ie 250 sats per kw),
/// causing occasional issues with feerate disagreements between an initiator that wants a
/// feerate of 1.1 sat/vbyte and a receiver that wants 1.1 rounded up to 2. If your fee
/// estimator rounds subtracting 250 to your desired feerate here can help avoid this issue.
///
/// [`ChannelConfig::max_dust_htlc_exposure`]: crate::util::config::ChannelConfig::max_dust_htlc_exposure
MinAllowedNonAnchorChannelRemoteFee,
/// This is the feerate on the transaction which we (or our counterparty) will broadcast in
/// order to close the channel if a channel party goes away.
///
/// This needs to be sufficient to get into the mempool when the channel needs to
/// be force-closed. Setting too low may result in force-closures. Because this is for anchor
/// channels, it can be a low value as we can always bump the feerate later.
///
/// A good estimate is the expected mempool minimum at the time of force-closure. Obviously this
/// is not an estimate which is very easy to calculate because we do not know the future. Using
/// a simple long-term fee estimate or tracking of the mempool minimum is a good approach to
/// ensure you can always close the channel. A future change to Bitcoin's P2P network
/// (package relay) may obviate the need for this entirely.
AnchorChannelFee,
/// Lightning is built around the ability to broadcast a transaction in the future to close our
/// channel and claim all pending funds. In order to do so, non-anchor channels are built with
/// transactions which we need to be able to broadcast at some point in the future.
///
/// This feerate represents the fee we pick now, which must be sufficient to enter a block at an
/// arbitrary time in the future. Obviously this is not an estimate which is very easy to
/// calculate, so most lightning nodes use some relatively high-priority feerate using the
/// current mempool. This leaves channels subject to being unable to close if feerates rise, and
/// in general you should prefer anchor channels to ensure you can increase the feerate when the
/// transactions need broadcasting.
///
/// Since this should represent the feerate of a channel close that does not need fee
/// bumping, this is also used as an upper bound for our attempted feerate when doing cooperative
/// closure of any channel.
NonAnchorChannelFee,
/// When cooperatively closing a channel, this is the minimum feerate we will accept.
/// Recommended at least within a day or so worth of blocks.
///
/// This will also be used when initiating a cooperative close of a channel. When closing a
/// channel you can override this fee by using
/// [`ChannelManager::close_channel_with_feerate_and_script`].
///
/// [`ChannelManager::close_channel_with_feerate_and_script`]: crate::ln::channelmanager::ChannelManager::close_channel_with_feerate_and_script
ChannelCloseMinimum,
/// The feerate used to claim on-chain funds when there is no particular urgency to do so.
///
/// It is used to get commitment transactions without any HTLCs confirmed in [`ChannelMonitor`]
/// and by [`OutputSweeper`] on transactions spending [`SpendableOutputDescriptor`]s after a
/// channel closure.
///
/// Generally spending these outputs is safe as long as they eventually confirm, so a value
/// (slightly above) the mempool minimum should suffice. However, as this value will influence
/// how long funds will be unavailable after channel closure, [`FeeEstimator`] implementors
/// might want to choose a higher feerate to regain control over funds faster.
///
/// [`ChannelMonitor`]: crate::chain::channelmonitor::ChannelMonitor
/// [`OutputSweeper`]: crate::util::sweep::OutputSweeper
/// [`SpendableOutputDescriptor`]: crate::sign::SpendableOutputDescriptor
OutputSpendingFee,
}
/// A trait which should be implemented to provide feerate information on a number of time
/// horizons.
///
/// If access to a local mempool is not feasible, feerate estimates should be fetched from a set of
/// third-parties hosting them. Note that this enables them to affect the propagation of your
/// pre-signed transactions at any time and therefore endangers the safety of channels funds. It
/// should be considered carefully as a deployment.
///
/// Note that all of the functions implemented here *must* be reentrant-safe (obviously - they're
/// called from inside the library in response to chain events, P2P events, or timer events).
///
/// LDK may generate a substantial number of fee-estimation calls in some cases. You should
/// pre-calculate and cache the fee estimate results to ensure you don't substantially slow HTLC
/// handling.
pub trait FeeEstimator {
/// Gets estimated satoshis of fee required per 1000 Weight-Units.
///
/// LDK will wrap this method and ensure that the value returned is no smaller than 253
/// (ie 1 satoshi-per-byte rounded up to ensure later round-downs don't put us below 1 satoshi-per-byte).
///
/// The following unit conversions can be used to convert to sats/KW:
/// * satoshis-per-byte * 250
/// * satoshis-per-kbyte / 4
fn get_est_sat_per_1000_weight(&self, confirmation_target: ConfirmationTarget) -> u32;
}
impl<T: FeeEstimator + ?Sized, F: Deref<Target = T>> FeeEstimator for F {
fn get_est_sat_per_1000_weight(&self, confirmation_target: ConfirmationTarget) -> u32 {
self.deref().get_est_sat_per_1000_weight(confirmation_target)
}
}
/// Minimum relay fee as required by bitcoin network mempool policy.
pub const INCREMENTAL_RELAY_FEE_SAT_PER_1000_WEIGHT: u64 = 253;
/// Minimum feerate that takes a sane approach to bitcoind weight-to-vbytes rounding.
/// See the following Core Lightning commit for an explanation:
/// <https://github.com/ElementsProject/lightning/commit/2e687b9b352c9092b5e8bd4a688916ac50b44af0>
pub const FEERATE_FLOOR_SATS_PER_KW: u32 = 253;
/// Wraps a [`FeeEstimator`] so that any fee estimations provided by it are bounded below by
/// `FEERATE_FLOOR_SATS_PER_KW` (253 sats/KW).
///
/// Note that this does *not* implement [`FeeEstimator`] to make it harder to accidentally mix the
/// two.
pub(crate) struct LowerBoundedFeeEstimator<F: FeeEstimator>(pub F);
impl<F: FeeEstimator> LowerBoundedFeeEstimator<F> {
/// Creates a new `LowerBoundedFeeEstimator` which wraps the provided fee_estimator
pub fn new(fee_estimator: F) -> Self {
LowerBoundedFeeEstimator(fee_estimator)
}
pub fn bounded_sat_per_1000_weight(&self, confirmation_target: ConfirmationTarget) -> u32 {
cmp::max(self.0.get_est_sat_per_1000_weight(confirmation_target), FEERATE_FLOOR_SATS_PER_KW)
}
}
#[cfg(test)]
mod tests {
use super::{
ConfirmationTarget, FeeEstimator, LowerBoundedFeeEstimator, FEERATE_FLOOR_SATS_PER_KW,
};
struct TestFeeEstimator {
sat_per_kw: u32,
}
impl FeeEstimator for TestFeeEstimator {
fn get_est_sat_per_1000_weight(&self, _: ConfirmationTarget) -> u32 {
self.sat_per_kw
}
}
#[test]
fn test_fee_estimator_less_than_floor() {
let sat_per_kw = FEERATE_FLOOR_SATS_PER_KW - 1;
let test_fee_estimator = &TestFeeEstimator { sat_per_kw };
let fee_estimator = LowerBoundedFeeEstimator::new(test_fee_estimator);
assert_eq!(
fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::AnchorChannelFee),
FEERATE_FLOOR_SATS_PER_KW
);
}
#[test]
fn test_fee_estimator_greater_than_floor() {
let sat_per_kw = FEERATE_FLOOR_SATS_PER_KW + 1;
let test_fee_estimator = &TestFeeEstimator { sat_per_kw };
let fee_estimator = LowerBoundedFeeEstimator::new(test_fee_estimator);
assert_eq!(
fee_estimator.bounded_sat_per_1000_weight(ConfirmationTarget::AnchorChannelFee),
sat_per_kw
);
}
}