Skip to content

Commit 82e7df1

Browse files
committed
Add relatively simple tests of the legacy and target closing fee
This doesn't exhaustively test closing fee negotiation at all, but ensures that it is at least basically able to come to consensus and sign cooperative closing transactions.
1 parent 0b481e9 commit 82e7df1

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed

lightning/src/ln/shutdown_tests.rs

+92
Original file line numberDiff line numberDiff line change
@@ -834,3 +834,95 @@ fn test_closing_signed_reinit_timeout() {
834834
do_test_closing_signed_reinit_timeout(TimeoutStep::AfterClosingSigned);
835835
do_test_closing_signed_reinit_timeout(TimeoutStep::NoTimeout);
836836
}
837+
838+
fn do_simple_legacy_shutdown_test(high_initiator_fee: bool) {
839+
// A simpe test of the legacy shutdown fee negotiation logic.
840+
let chanmon_cfgs = create_chanmon_cfgs(2);
841+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
842+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
843+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
844+
845+
let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
846+
847+
if high_initiator_fee {
848+
// If high_initiator_fee is set, set nodes[0]'s feerate significantly higher. This
849+
// shouldn't impact the flow at all given nodes[1] will happily accept the higher fee.
850+
let mut feerate_lock = chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
851+
*feerate_lock *= 10;
852+
}
853+
854+
nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap();
855+
let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
856+
nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown);
857+
let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
858+
nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &InitFeatures::known(), &node_1_shutdown);
859+
860+
let mut node_0_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
861+
node_0_closing_signed.fee_range = None;
862+
if high_initiator_fee {
863+
assert!(node_0_closing_signed.fee_satoshis > 500);
864+
} else {
865+
assert!(node_0_closing_signed.fee_satoshis < 500);
866+
}
867+
868+
nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed);
869+
let (_, mut node_1_closing_signed) = get_closing_signed_broadcast!(nodes[1].node, nodes[0].node.get_our_node_id());
870+
node_1_closing_signed.as_mut().unwrap().fee_range = None;
871+
872+
nodes[0].node.handle_closing_signed(&nodes[1].node.get_our_node_id(), &node_1_closing_signed.unwrap());
873+
let (_, node_0_none) = get_closing_signed_broadcast!(nodes[0].node, nodes[1].node.get_our_node_id());
874+
assert!(node_0_none.is_none());
875+
}
876+
877+
#[test]
878+
fn simple_legacy_shutdown_test() {
879+
do_simple_legacy_shutdown_test(false);
880+
do_simple_legacy_shutdown_test(true);
881+
}
882+
883+
#[test]
884+
fn simple_target_feerate_shutdown() {
885+
// Simple test of target in `close_channel_with_target_feerate`.
886+
let chanmon_cfgs = create_chanmon_cfgs(2);
887+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
888+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
889+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
890+
891+
let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
892+
let chan_id = OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id();
893+
894+
nodes[0].node.close_channel_with_target_feerate(&chan_id, 253 * 10).unwrap();
895+
let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
896+
nodes[1].node.close_channel_with_target_feerate(&chan_id, 253 * 5).unwrap();
897+
let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
898+
899+
nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown);
900+
nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &InitFeatures::known(), &node_1_shutdown);
901+
902+
let node_0_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
903+
nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed);
904+
let (_, node_1_closing_signed_opt) = get_closing_signed_broadcast!(nodes[1].node, nodes[0].node.get_our_node_id());
905+
let node_1_closing_signed = node_1_closing_signed_opt.unwrap();
906+
907+
// nodes[1] was passed a target which was larger than the current channel feerate, which it
908+
// should ignore in favor of the channel fee, as there is no use demanding a minimum higher
909+
// than what will be paid on a force-close transaction. Note that we have to consider rounding,
910+
// so only check that we're within 10 sats.
911+
assert!(node_0_closing_signed.fee_range.as_ref().unwrap().min_fee_satoshis >=
912+
node_1_closing_signed.fee_range.as_ref().unwrap().min_fee_satoshis * 10 - 5);
913+
assert!(node_0_closing_signed.fee_range.as_ref().unwrap().min_fee_satoshis <=
914+
node_1_closing_signed.fee_range.as_ref().unwrap().min_fee_satoshis * 10 + 5);
915+
916+
// Further, because nodes[0]'s target fee is larger than the `Normal` fee estimation plus our
917+
// force-closure-avoidance buffer, min should equal max, and the nodes[1]-selected fee should
918+
// be the nodes[0] only available fee.
919+
assert_eq!(node_0_closing_signed.fee_range.as_ref().unwrap().min_fee_satoshis,
920+
node_0_closing_signed.fee_range.as_ref().unwrap().max_fee_satoshis);
921+
assert_eq!(node_0_closing_signed.fee_range.as_ref().unwrap().min_fee_satoshis,
922+
node_0_closing_signed.fee_satoshis);
923+
assert_eq!(node_0_closing_signed.fee_satoshis, node_1_closing_signed.fee_satoshis);
924+
925+
nodes[0].node.handle_closing_signed(&nodes[1].node.get_our_node_id(), &node_1_closing_signed);
926+
let (_, node_0_none) = get_closing_signed_broadcast!(nodes[0].node, nodes[1].node.get_our_node_id());
927+
assert!(node_0_none.is_none());
928+
}

0 commit comments

Comments
 (0)