Skip to content

Commit 9daa985

Browse files
committed
use lightning::util::anchor_channel_reserves for improved anchor reserve estimation
Replaced flat fee-based reserve logic with estimation using `get_reserve_per_channel`, following changes introduced in lightningdevkit/rust-lightning#3487.
1 parent 066c0e1 commit 9daa985

7 files changed

Lines changed: 38 additions & 46 deletions

File tree

bindings/ldk_node.udl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ dictionary Config {
1717

1818
dictionary AnchorChannelsConfig {
1919
sequence<PublicKey> trusted_peers_no_reserve;
20-
u64 per_channel_reserve_sats;
2120
};
2221

2322
dictionary BackgroundSyncConfig {

src/config.rs

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ const DEFAULT_BDK_WALLET_SYNC_INTERVAL_SECS: u64 = 80;
2727
const DEFAULT_LDK_WALLET_SYNC_INTERVAL_SECS: u64 = 30;
2828
const DEFAULT_FEE_RATE_CACHE_UPDATE_INTERVAL_SECS: u64 = 60 * 10;
2929
const DEFAULT_PROBING_LIQUIDITY_LIMIT_MULTIPLIER: u64 = 3;
30-
const DEFAULT_ANCHOR_PER_CHANNEL_RESERVE_SATS: u64 = 25_000;
3130

3231
/// The default log level.
3332
pub const DEFAULT_LOG_LEVEL: LogLevel = LogLevel::Debug;
@@ -233,7 +232,6 @@ impl Default for Config {
233232
/// | Parameter | Value |
234233
/// |----------------------------|--------|
235234
/// | `trusted_peers_no_reserve` | [] |
236-
/// | `per_channel_reserve_sats` | 25000 |
237235
///
238236
///
239237
/// [BOLT 3]: https://github.com/lightning/bolts/blob/master/03-transactions.md#htlc-timeout-and-htlc-success-transactions
@@ -249,33 +247,11 @@ pub struct AnchorChannelsConfig {
249247
/// required Anchor spending transactions confirmed on-chain is potentially insecure
250248
/// as the channel may not be closed if they refuse to do so.
251249
pub trusted_peers_no_reserve: Vec<PublicKey>,
252-
/// The amount of satoshis per anchors-negotiated channel with an untrusted peer that we keep
253-
/// as an emergency reserve in our on-chain wallet.
254-
///
255-
/// This allows for having the required Anchor output spending and HTLC transactions confirmed
256-
/// when the channel is closed.
257-
///
258-
/// If the channel peer is not marked as trusted via
259-
/// [`AnchorChannelsConfig::trusted_peers_no_reserve`], we will always try to spend the Anchor
260-
/// outputs with *any* on-chain funds available, i.e., the total reserve value as well as any
261-
/// spendable funds available in the on-chain wallet. Therefore, this per-channel multiplier is
262-
/// really a emergency reserve that we maintain at all time to reduce reduce the risk of
263-
/// insufficient funds at time of a channel closure. To this end, we will refuse to open
264-
/// outbound or accept inbound channels if we don't have sufficient on-chain funds available to
265-
/// cover the additional reserve requirement.
266-
///
267-
/// **Note:** Depending on the fee market at the time of closure, this reserve amount might or
268-
/// might not suffice to successfully spend the Anchor output and have the HTLC transactions
269-
/// confirmed on-chain, i.e., you may want to adjust this value accordingly.
270-
pub per_channel_reserve_sats: u64,
271250
}
272251

273252
impl Default for AnchorChannelsConfig {
274253
fn default() -> Self {
275-
Self {
276-
trusted_peers_no_reserve: Vec::new(),
277-
per_channel_reserve_sats: DEFAULT_ANCHOR_PER_CHANNEL_RESERVE_SATS,
278-
}
254+
Self { trusted_peers_no_reserve: Vec::new() }
279255
}
280256
}
281257

src/event.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ use lightning::impl_writeable_tlv_based_enum;
2222
use lightning::ln::channelmanager::PaymentId;
2323
use lightning::ln::types::ChannelId;
2424
use lightning::routing::gossip::NodeId;
25+
use lightning::util::anchor_channel_reserves::{
26+
get_reserve_per_channel, AnchorChannelReserveContext,
27+
};
2528
use lightning::util::config::{
2629
ChannelConfigOverrides, ChannelConfigUpdate, ChannelHandshakeConfigUpdate,
2730
};
@@ -1177,7 +1180,8 @@ where
11771180
{
11781181
0
11791182
} else {
1180-
anchor_channels_config.per_channel_reserve_sats
1183+
get_reserve_per_channel(&AnchorChannelReserveContext::default())
1184+
.to_sat()
11811185
};
11821186

11831187
if spendable_amount_sats < required_amount_sats {

src/lib.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ use lightning::ln::channelmanager::PaymentId;
146146
use lightning::ln::funding::SpliceContribution;
147147
use lightning::ln::msgs::SocketAddress;
148148
use lightning::routing::gossip::NodeAlias;
149+
use lightning::util::anchor_channel_reserves::{
150+
get_reserve_per_channel, AnchorChannelReserveContext,
151+
};
149152
use lightning::util::persist::KVStoreSync;
150153
use lightning_background_processor::process_events_async;
151154
use liquidity::{LSPS1Liquidity, LiquiditySource};
@@ -1181,7 +1184,7 @@ impl Node {
11811184
if init_features.requires_anchors_zero_fee_htlc_tx()
11821185
&& !c.trusted_peers_no_reserve.contains(peer_node_id)
11831186
{
1184-
c.per_channel_reserve_sats
1187+
get_reserve_per_channel(&AnchorChannelReserveContext::default()).to_sat()
11851188
} else {
11861189
0
11871190
}
@@ -1208,13 +1211,11 @@ impl Node {
12081211
/// channel counterparty on channel open. This can be useful to start out with the balance not
12091212
/// entirely shifted to one side, therefore allowing to receive payments from the getgo.
12101213
///
1211-
/// If Anchor channels are enabled, this will ensure the configured
1212-
/// [`AnchorChannelsConfig::per_channel_reserve_sats`] is available and will be retained before
1213-
/// opening the channel.
1214+
/// If Anchor channels are enabled, this will ensure the reserved amount per
1215+
/// channel is available and will be retained before opening the channel.
12141216
///
12151217
/// Returns a [`UserChannelId`] allowing to locally keep track of the channel.
12161218
///
1217-
/// [`AnchorChannelsConfig::per_channel_reserve_sats`]: crate::config::AnchorChannelsConfig::per_channel_reserve_sats
12181219
pub fn open_channel(
12191220
&self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64,
12201221
push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
@@ -1243,13 +1244,11 @@ impl Node {
12431244
/// channel counterparty on channel open. This can be useful to start out with the balance not
12441245
/// entirely shifted to one side, therefore allowing to receive payments from the getgo.
12451246
///
1246-
/// If Anchor channels are enabled, this will ensure the configured
1247-
/// [`AnchorChannelsConfig::per_channel_reserve_sats`] is available and will be retained before
1248-
/// opening the channel.
1247+
/// If Anchor channels are enabled, this will ensure the reserved amount per
1248+
/// channel is available and will be retained before opening the channel.
12491249
///
12501250
/// Returns a [`UserChannelId`] allowing to locally keep track of the channel.
12511251
///
1252-
/// [`AnchorChannelsConfig::per_channel_reserve_sats`]: crate::config::AnchorChannelsConfig::per_channel_reserve_sats
12531252
pub fn open_announced_channel(
12541253
&self, node_id: PublicKey, address: SocketAddress, channel_amount_sats: u64,
12551254
push_to_counterparty_msat: Option<u64>, channel_config: Option<ChannelConfig>,
@@ -1862,6 +1861,8 @@ impl_writeable_tlv_based!(NodeMetrics, {
18621861
pub(crate) fn total_anchor_channels_reserve_sats(
18631862
channel_manager: &ChannelManager, config: &Config,
18641863
) -> u64 {
1864+
let reserve_sat_per_channel = get_anchor_reserve_per_channel();
1865+
18651866
config.anchor_channels_config.as_ref().map_or(0, |anchor_channels_config| {
18661867
channel_manager
18671868
.list_channels()
@@ -1875,6 +1876,12 @@ pub(crate) fn total_anchor_channels_reserve_sats(
18751876
.map_or(false, |t| t.requires_anchors_zero_fee_htlc_tx())
18761877
})
18771878
.count() as u64
1878-
* anchor_channels_config.per_channel_reserve_sats
1879+
* reserve_sat_per_channel
18791880
})
18801881
}
1882+
1883+
/// Returns the configured anchor channel reserve per channel in satoshis.
1884+
pub fn get_anchor_reserve_per_channel() -> u64 {
1885+
let context = AnchorChannelReserveContext::default();
1886+
get_reserve_per_channel(&context).to_sat()
1887+
}

src/liquidity.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ use lightning::ln::channelmanager::{InterceptId, MIN_FINAL_CLTV_EXPIRY_DELTA};
2121
use lightning::ln::msgs::SocketAddress;
2222
use lightning::ln::types::ChannelId;
2323
use lightning::routing::router::{RouteHint, RouteHintHop};
24+
use lightning::util::anchor_channel_reserves::{
25+
get_reserve_per_channel, AnchorChannelReserveContext,
26+
};
2427
use lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription, InvoiceBuilder, RoutingFees};
2528
use lightning_liquidity::events::LiquidityEvent;
2629
use lightning_liquidity::lsps0::ser::{LSPSDateTime, LSPSRequestId};
@@ -752,7 +755,8 @@ where
752755
if init_features.requires_anchors_zero_fee_htlc_tx()
753756
&& !c.trusted_peers_no_reserve.contains(&their_network_key)
754757
{
755-
c.per_channel_reserve_sats
758+
get_reserve_per_channel(&AnchorChannelReserveContext::default())
759+
.to_sat()
756760
} else {
757761
0
758762
}

tests/common/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,9 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
687687
let addr_a = node_a.onchain_payment().new_address().unwrap();
688688
let addr_b = node_b.onchain_payment().new_address().unwrap();
689689

690-
let premine_amount_sat = if expect_anchor_channel { 2_125_000 } else { 2_100_000 };
690+
let anchor_reserve = if expect_anchor_channel { get_anchor_reserve_per_channel() } else { 0 };
691691

692+
let premine_amount_sat = 2_100_000 + anchor_reserve;
692693
premine_and_distribute_funds(
693694
&bitcoind,
694695
electrsd,
@@ -773,7 +774,8 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
773774
);
774775

775776
let onchain_fee_buffer_sat = 5000;
776-
let node_a_anchor_reserve_sat = if expect_anchor_channel { 25_000 } else { 0 };
777+
let node_a_anchor_reserve_sat =
778+
if expect_anchor_channel { get_anchor_reserve_per_channel() } else { 0 };
777779
let node_a_upper_bound_sat =
778780
premine_amount_sat - node_a_anchor_reserve_sat - funding_amount_sat;
779781
let node_a_lower_bound_sat = premine_amount_sat
@@ -794,7 +796,7 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
794796
{
795797
0
796798
} else {
797-
25_000
799+
get_anchor_reserve_per_channel()
798800
};
799801
assert_eq!(
800802
node_b.list_balances().spendable_onchain_balance_sats,

tests/integration_tests_rust.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use ldk_node::payment::{
3333
ConfirmationStatus, PaymentDetails, PaymentDirection, PaymentKind, PaymentStatus,
3434
UnifiedPaymentResult,
3535
};
36-
use ldk_node::{Builder, Event, NodeError};
36+
use ldk_node::{get_anchor_reserve_per_channel, Builder, Event, NodeError};
3737
use lightning::ln::channelmanager::PaymentId;
3838
use lightning::routing::gossip::{NodeAlias, NodeId};
3939
use lightning::routing::router::RouteParametersConfig;
@@ -331,7 +331,7 @@ async fn onchain_send_receive() {
331331
let unchecked_address = Address::<NetworkUnchecked>::from_str(static_address).unwrap();
332332
let addr_c = unchecked_address.assume_checked();
333333

334-
let premine_amount_sat = 1_100_000;
334+
let premine_amount_sat = 2_100_000;
335335
premine_and_distribute_funds(
336336
&bitcoind.client,
337337
&electrsd.client,
@@ -364,7 +364,7 @@ async fn onchain_send_receive() {
364364
}
365365

366366
let channel_amount_sat = 1_000_000;
367-
let reserve_amount_sat = 25_000;
367+
let reserve_amount_sat = get_anchor_reserve_per_channel();
368368
open_channel(&node_b, &node_a, channel_amount_sat, true, &electrsd).await;
369369
generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await;
370370

@@ -529,8 +529,8 @@ async fn onchain_send_all_retains_reserve() {
529529
let addr_a = node_a.onchain_payment().new_address().unwrap();
530530
let addr_b = node_b.onchain_payment().new_address().unwrap();
531531

532-
let premine_amount_sat = 1_000_000;
533-
let reserve_amount_sat = 25_000;
532+
let premine_amount_sat = 2_000_000;
533+
let reserve_amount_sat = get_anchor_reserve_per_channel();
534534
let onchain_fee_buffer_sat = 1000;
535535
premine_and_distribute_funds(
536536
&bitcoind.client,

0 commit comments

Comments
 (0)