Skip to content

Commit 0f0e8fa

Browse files
committed
Shakedown zero reserve channels
1 parent 35f2d4f commit 0f0e8fa

File tree

2 files changed

+373
-1
lines changed

2 files changed

+373
-1
lines changed

lightning/src/ln/functional_test_utils.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,6 +2137,129 @@ pub fn update_nodes_with_chan_announce<'a, 'b, 'c, 'd>(
21372137
}
21382138
}
21392139

2140+
pub fn handle_and_accept_open_zero_reserve_channel(
2141+
node: &Node, counterparty_id: PublicKey, msg: &OpenChannel,
2142+
) {
2143+
node.node.handle_open_channel(counterparty_id, &msg);
2144+
let events = node.node.get_and_clear_pending_events();
2145+
assert_eq!(events.len(), 1);
2146+
match &events[0] {
2147+
Event::OpenChannelRequest { temporary_channel_id, counterparty_node_id, .. } => {
2148+
node.node
2149+
.accept_inbound_channel_from_trusted_peer(
2150+
temporary_channel_id,
2151+
counterparty_node_id,
2152+
42,
2153+
false,
2154+
true,
2155+
None,
2156+
)
2157+
.unwrap();
2158+
},
2159+
_ => panic!("Unexpected event"),
2160+
};
2161+
}
2162+
2163+
pub fn exchange_open_accept_zero_reserve_chan<'a, 'b, 'c, 'd>(
2164+
node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64,
2165+
) -> ChannelId {
2166+
let node_a_id = node_a.node.get_our_node_id();
2167+
let node_b_id = node_b.node.get_our_node_id();
2168+
2169+
let create_chan_id =
2170+
node_a.node.create_channel(node_b_id, channel_value, push_msat, 42, None, None).unwrap();
2171+
let open_channel_msg = get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b_id);
2172+
assert_eq!(open_channel_msg.common_fields.temporary_channel_id, create_chan_id);
2173+
assert_eq!(
2174+
node_a
2175+
.node
2176+
.list_channels()
2177+
.iter()
2178+
.find(|channel| channel.channel_id == create_chan_id)
2179+
.unwrap()
2180+
.user_channel_id,
2181+
42
2182+
);
2183+
handle_and_accept_open_zero_reserve_channel(&node_b, node_a_id, &open_channel_msg);
2184+
2185+
let accept_channel_msg = get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a_id);
2186+
assert_eq!(accept_channel_msg.common_fields.temporary_channel_id, create_chan_id);
2187+
node_a.node.handle_accept_channel(node_b_id, &accept_channel_msg);
2188+
assert_ne!(
2189+
node_b
2190+
.node
2191+
.list_channels()
2192+
.iter()
2193+
.find(|channel| channel.channel_id == create_chan_id)
2194+
.unwrap()
2195+
.user_channel_id,
2196+
0
2197+
);
2198+
2199+
create_chan_id
2200+
}
2201+
2202+
pub fn create_zero_reserve_chan_between_nodes_with_value_init<'a, 'b, 'c>(
2203+
node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64,
2204+
) -> Transaction {
2205+
let create_chan_id =
2206+
exchange_open_accept_zero_reserve_chan(node_a, node_b, channel_value, push_msat);
2207+
sign_funding_transaction(node_a, node_b, channel_value, create_chan_id)
2208+
}
2209+
2210+
pub fn create_zero_reserve_chan_between_nodes_with_value_a<'a, 'b, 'c: 'd, 'd>(
2211+
node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64,
2212+
) -> ((msgs::ChannelReady, msgs::AnnouncementSignatures), ChannelId, Transaction) {
2213+
let tx = create_zero_reserve_chan_between_nodes_with_value_init(
2214+
node_a,
2215+
node_b,
2216+
channel_value,
2217+
push_msat,
2218+
);
2219+
let (msgs, chan_id) = create_chan_between_nodes_with_value_confirm(node_a, node_b, &tx);
2220+
(msgs, chan_id, tx)
2221+
}
2222+
2223+
pub fn create_zero_reserve_chan_between_nodes_with_value<'a, 'b, 'c: 'd, 'd>(
2224+
node_a: &'a Node<'b, 'c, 'd>, node_b: &'a Node<'b, 'c, 'd>, channel_value: u64, push_msat: u64,
2225+
) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, ChannelId, Transaction) {
2226+
let (channel_ready, channel_id, tx) = create_zero_reserve_chan_between_nodes_with_value_a(
2227+
node_a,
2228+
node_b,
2229+
channel_value,
2230+
push_msat,
2231+
);
2232+
let (announcement, as_update, bs_update) =
2233+
create_chan_between_nodes_with_value_b(node_a, node_b, &channel_ready);
2234+
(announcement, as_update, bs_update, channel_id, tx)
2235+
}
2236+
2237+
pub fn create_announced_zero_reserve_chan_between_nodes_with_value<'a, 'b, 'c: 'd, 'd>(
2238+
nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize, channel_value: u64, push_msat: u64,
2239+
) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, ChannelId, Transaction) {
2240+
let chan_announcement = create_zero_reserve_chan_between_nodes_with_value(
2241+
&nodes[a],
2242+
&nodes[b],
2243+
channel_value,
2244+
push_msat,
2245+
);
2246+
update_nodes_with_chan_announce(
2247+
nodes,
2248+
a,
2249+
b,
2250+
&chan_announcement.0,
2251+
&chan_announcement.1,
2252+
&chan_announcement.2,
2253+
);
2254+
(chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
2255+
}
2256+
2257+
pub fn create_announced_zero_reserve_chan_between_nodes<'a, 'b, 'c: 'd, 'd>(
2258+
nodes: &'a Vec<Node<'b, 'c, 'd>>, a: usize, b: usize,
2259+
) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, ChannelId, Transaction) {
2260+
create_announced_zero_reserve_chan_between_nodes_with_value(nodes, a, b, 100000, 10001)
2261+
}
2262+
21402263
pub fn do_check_spends<F: Fn(&bitcoin::transaction::OutPoint) -> Option<TxOut>>(
21412264
tx: &Transaction, get_output: F,
21422265
) {

lightning/src/ln/htlc_reserve_unit_tests.rs

Lines changed: 250 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::ln::functional_test_utils::*;
1414
use crate::ln::msgs::{self, BaseMessageHandler, ChannelMessageHandler, MessageSendEvent};
1515
use crate::ln::onion_utils::{self, AttributionData};
1616
use crate::ln::outbound_payment::RecipientOnionFields;
17-
use crate::routing::router::PaymentParameters;
17+
use crate::routing::router::{PaymentParameters, RouteParameters};
1818
use crate::sign::ecdsa::EcdsaChannelSigner;
1919
use crate::sign::tx_builder::{SpecTxBuilder, TxBuilder};
2020
use crate::types::features::ChannelTypeFeatures;
@@ -2438,3 +2438,252 @@ pub fn do_test_dust_limit_fee_accounting(can_afford: bool) {
24382438
check_added_monitors(&nodes[1], 3);
24392439
}
24402440
}
2441+
2442+
#[test]
2443+
fn test_create_channel_to_trusted_peer() {
2444+
let mut config = test_default_channel_config();
2445+
2446+
// Legacy channels
2447+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = false;
2448+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = false;
2449+
let channel_type = do_test_create_channel_to_trusted_peer(config.clone());
2450+
assert_eq!(channel_type, ChannelTypeFeatures::only_static_remote_key());
2451+
2452+
// Anchor channels
2453+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
2454+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = false;
2455+
let channel_type = do_test_create_channel_to_trusted_peer(config.clone());
2456+
assert_eq!(channel_type, ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies());
2457+
2458+
// 0FC channels
2459+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = false;
2460+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
2461+
let channel_type = do_test_create_channel_to_trusted_peer(config.clone());
2462+
assert_eq!(channel_type, ChannelTypeFeatures::anchors_zero_fee_commitments());
2463+
}
2464+
2465+
#[cfg(test)]
2466+
fn do_test_create_channel_to_trusted_peer(mut config: UserConfig) -> ChannelTypeFeatures {
2467+
let chanmon_cfgs = create_chanmon_cfgs(2);
2468+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
2469+
config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100;
2470+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]);
2471+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2472+
2473+
let node_a_id = nodes[0].node.get_our_node_id();
2474+
let node_b_id = nodes[1].node.get_our_node_id();
2475+
2476+
let channel_value_sat = 100_000;
2477+
2478+
let temp_channel_id = nodes[0]
2479+
.node
2480+
.create_channel_to_trusted_peer(node_b_id, channel_value_sat, 0, 42, None, None)
2481+
.unwrap();
2482+
let mut open_channel_message =
2483+
get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, node_b_id);
2484+
handle_and_accept_open_channel(&nodes[1], node_a_id, &open_channel_message);
2485+
let mut accept_channel_message =
2486+
get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, node_a_id);
2487+
nodes[0].node.handle_accept_channel(node_b_id, &accept_channel_message);
2488+
let funding_tx = sign_funding_transaction(&nodes[0], &nodes[1], 100_000, temp_channel_id);
2489+
let funding_msgs =
2490+
create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &funding_tx);
2491+
create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_msgs.0);
2492+
2493+
let details = &nodes[0].node.list_channels()[0];
2494+
let reserve_sat = details.unspendable_punishment_reserve.unwrap();
2495+
assert_ne!(reserve_sat, 0);
2496+
let channel_type = details.channel_type.clone().unwrap();
2497+
let feerate_per_kw = details.feerate_sat_per_1000_weight.unwrap();
2498+
let anchors_sat =
2499+
if channel_type == ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies() {
2500+
2 * 330
2501+
} else {
2502+
0
2503+
};
2504+
let spike_multiple = if channel_type == ChannelTypeFeatures::only_static_remote_key() {
2505+
FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32
2506+
} else {
2507+
1
2508+
};
2509+
let spiked_feerate = spike_multiple * feerate_per_kw;
2510+
let reserved_commit_tx_fee_sat = chan_utils::commit_tx_fee_sat(
2511+
spiked_feerate,
2512+
2, // We reserve space for two HTLCs, the next outbound non-dust HTLC, and the fee spike buffer HTLC
2513+
&channel_type,
2514+
);
2515+
2516+
let max_outbound_htlc_sat =
2517+
channel_value_sat - anchors_sat - reserved_commit_tx_fee_sat - reserve_sat;
2518+
assert_eq!(details.next_outbound_htlc_limit_msat, max_outbound_htlc_sat * 1000);
2519+
send_payment(&nodes[0], &[&nodes[1]], max_outbound_htlc_sat * 1000);
2520+
2521+
let details = &nodes[1].node.list_channels()[0];
2522+
assert_eq!(details.unspendable_punishment_reserve.unwrap(), 0);
2523+
assert_eq!(details.next_outbound_htlc_limit_msat, max_outbound_htlc_sat * 1000);
2524+
send_payment(&nodes[1], &[&nodes[0]], max_outbound_htlc_sat * 1000);
2525+
2526+
channel_type
2527+
}
2528+
2529+
#[test]
2530+
fn test_accept_inbound_channel_from_trusted_peer_0reserve() {
2531+
let mut config = test_default_channel_config();
2532+
2533+
// Legacy channels
2534+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = false;
2535+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = false;
2536+
let channel_type = do_test_accept_inbound_channel_from_trusted_peer_0reserve(config.clone());
2537+
assert_eq!(channel_type, ChannelTypeFeatures::only_static_remote_key());
2538+
2539+
// Anchor channels
2540+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
2541+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = false;
2542+
let channel_type = do_test_accept_inbound_channel_from_trusted_peer_0reserve(config.clone());
2543+
assert_eq!(channel_type, ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies());
2544+
2545+
// 0FC channels
2546+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = false;
2547+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
2548+
let channel_type = do_test_accept_inbound_channel_from_trusted_peer_0reserve(config.clone());
2549+
assert_eq!(channel_type, ChannelTypeFeatures::anchors_zero_fee_commitments());
2550+
}
2551+
2552+
#[cfg(test)]
2553+
fn do_test_accept_inbound_channel_from_trusted_peer_0reserve(
2554+
mut config: UserConfig,
2555+
) -> ChannelTypeFeatures {
2556+
let chanmon_cfgs = create_chanmon_cfgs(2);
2557+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
2558+
config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100;
2559+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]);
2560+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2561+
2562+
let channel_value_sat = 100_000;
2563+
let (_, _, _chan_id, _) = create_announced_zero_reserve_chan_between_nodes_with_value(
2564+
&nodes,
2565+
0,
2566+
1,
2567+
channel_value_sat,
2568+
0,
2569+
);
2570+
let details = &nodes[0].node.list_channels()[0];
2571+
assert_eq!(details.unspendable_punishment_reserve.unwrap(), 0);
2572+
let channel_type = details.channel_type.clone().unwrap();
2573+
let feerate_per_kw = details.feerate_sat_per_1000_weight.unwrap();
2574+
let anchors_sat =
2575+
if channel_type == ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies() {
2576+
2 * 330
2577+
} else {
2578+
0
2579+
};
2580+
let spike_multiple = if channel_type == ChannelTypeFeatures::only_static_remote_key() {
2581+
FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32
2582+
} else {
2583+
1
2584+
};
2585+
let spiked_feerate = spike_multiple * feerate_per_kw;
2586+
let reserved_commit_tx_fee_sat = chan_utils::commit_tx_fee_sat(
2587+
spiked_feerate,
2588+
2, // We reserve space for two HTLCs, the next outbound non-dust HTLC, and the fee spike buffer HTLC
2589+
&channel_type,
2590+
);
2591+
2592+
let max_outbound_htlc_sat = channel_value_sat - reserved_commit_tx_fee_sat - anchors_sat;
2593+
assert_eq!(details.next_outbound_htlc_limit_msat, max_outbound_htlc_sat * 1000);
2594+
send_payment(&nodes[0], &[&nodes[1]], max_outbound_htlc_sat * 1000);
2595+
2596+
let details = &nodes[1].node.list_channels()[0];
2597+
let reserve_sat = details.unspendable_punishment_reserve.unwrap();
2598+
assert_ne!(reserve_sat, 0);
2599+
let max_outbound_htlc_sat = max_outbound_htlc_sat - reserve_sat;
2600+
assert_eq!(details.next_outbound_htlc_limit_msat, max_outbound_htlc_sat * 1000);
2601+
send_payment(&nodes[1], &[&nodes[0]], max_outbound_htlc_sat * 1000);
2602+
2603+
channel_type
2604+
}
2605+
2606+
#[test]
2607+
fn test_zero_reserve_no_outputs() {
2608+
let chanmon_cfgs = create_chanmon_cfgs(2);
2609+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
2610+
let mut config = test_default_channel_config();
2611+
config.channel_handshake_config.max_inbound_htlc_value_in_flight_percent_of_channel = 100;
2612+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = false;
2613+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(config)]);
2614+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2615+
let channel_type = ChannelTypeFeatures::only_static_remote_key();
2616+
2617+
let node_a_id = nodes[0].node.get_our_node_id();
2618+
let node_b_id = nodes[1].node.get_our_node_id();
2619+
2620+
nodes[0].node.create_channel(node_b_id, 1000 + 2, 0, 42, None, None).unwrap();
2621+
let mut open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, node_b_id);
2622+
open_channel.common_fields.max_htlc_value_in_flight_msat = 1_000_000;
2623+
open_channel.common_fields.dust_limit_satoshis = 546;
2624+
nodes[1].node.handle_open_channel(node_a_id, &open_channel);
2625+
let events = nodes[1].node.get_and_clear_pending_events();
2626+
assert_eq!(events.len(), 1);
2627+
match events[0] {
2628+
Event::OpenChannelRequest { temporary_channel_id: chan_id, .. } => {
2629+
nodes[1]
2630+
.node
2631+
.accept_inbound_channel_from_trusted_peer(
2632+
&chan_id, &node_a_id, 0, false, true, None,
2633+
)
2634+
.unwrap();
2635+
},
2636+
_ => panic!("Unexpected event"),
2637+
};
2638+
2639+
nodes[0].node.handle_accept_channel(
2640+
node_b_id,
2641+
&get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, node_a_id),
2642+
);
2643+
2644+
let (chan_id, tx, _) = create_funding_transaction(&nodes[0], &node_b_id, 1000 + 2, 42);
2645+
2646+
{
2647+
let mut per_peer_lock;
2648+
let mut peer_state_lock;
2649+
let channel = get_channel_ref!(nodes[0], nodes[1], per_peer_lock, peer_state_lock, chan_id);
2650+
if let Some(mut chan) = channel.as_unfunded_outbound_v1_mut() {
2651+
chan.context.holder_dust_limit_satoshis = 546;
2652+
} else {
2653+
panic!("Unexpected Channel phase");
2654+
}
2655+
}
2656+
2657+
nodes[0].node.funding_transaction_generated(chan_id, node_b_id, tx.clone()).unwrap();
2658+
nodes[1].node.handle_funding_created(
2659+
node_a_id,
2660+
&get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, node_b_id),
2661+
);
2662+
check_added_monitors(&nodes[1], 1);
2663+
expect_channel_pending_event(&nodes[1], &node_a_id);
2664+
2665+
nodes[0].node.handle_funding_signed(
2666+
node_b_id,
2667+
&get_event_msg!(nodes[1], MessageSendEvent::SendFundingSigned, node_a_id),
2668+
);
2669+
check_added_monitors(&nodes[0], 1);
2670+
expect_channel_pending_event(&nodes[0], &node_b_id);
2671+
2672+
let (channel_ready, _channel_id) =
2673+
create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
2674+
let (announcement, as_update, bs_update) =
2675+
create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &channel_ready);
2676+
update_nodes_with_chan_announce(&nodes, 0, 1, &announcement, &as_update, &bs_update);
2677+
2678+
let delta = chan_utils::commit_tx_fee_sat(253 * 2, 2, &channel_type);
2679+
assert!(1000 + 2 - delta < 546); // to_local is now below dust
2680+
assert!(delta < 546); // htlc is also below dust
2681+
2682+
//let _ = send_payment(&nodes[0], &[&nodes[1]], delta * 1000);
2683+
2684+
let payment_params =
2685+
PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV);
2686+
2687+
let route_params = RouteParameters::from_payment_params_and_value(payment_params, delta * 1000);
2688+
assert!(get_route(&nodes[0], &route_params).is_err());
2689+
}

0 commit comments

Comments
 (0)