Skip to content

Commit 67841ec

Browse files
committed
Add coverage for 0FC channels in reorg_tests
1 parent e180b46 commit 67841ec

File tree

1 file changed

+98
-46
lines changed

1 file changed

+98
-46
lines changed

lightning/src/ln/reorg_tests.rs

Lines changed: 98 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ fn test_htlc_preimage_claim_prev_counterparty_commitment_after_current_counterpa
805805
assert_eq!(htlc_preimage_tx.input[0].witness.second_to_last().unwrap(), &payment_preimage.0[..]);
806806
}
807807

808-
fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_counterparty_commitment: bool) {
808+
fn do_test_retries_own_commitment_broadcast_after_reorg(keyed_anchors: bool, p2a_anchor: bool, revoked_counterparty_commitment: bool) {
809809
// Tests that a node will retry broadcasting its own commitment after seeing a confirmed
810810
// counterparty commitment be reorged out.
811811
let mut chanmon_cfgs = create_chanmon_cfgs(2);
@@ -814,34 +814,32 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
814814
}
815815
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
816816
let mut config = test_default_channel_config();
817-
if anchors {
817+
if keyed_anchors {
818818
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
819819
config.manually_accept_inbound_channels = true;
820+
} else if p2a_anchor {
821+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
822+
config.manually_accept_inbound_channels = true;
820823
}
821824
let persister;
822825
let new_chain_monitor;
823826
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config.clone())]);
824827
let nodes_1_deserialized;
825828
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
826829

830+
let coinbase_tx = provide_anchor_reserves(&nodes);
831+
827832
let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1);
828833

829834
// Route a payment so we have an HTLC to claim as well.
830835
let (_, payment_hash, ..) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
831836

832837
if revoked_counterparty_commitment {
833-
// Trigger a fee update such that we advance the state. We will have B broadcast its state
834-
// without the fee update.
838+
// Trigger a new commitment by routing a dummy HTLC. We will have B broadcast the previous commitment.
835839
let serialized_node = nodes[1].node.encode();
836840
let serialized_monitor = get_monitor!(nodes[1], chan_id).encode();
837841

838-
*chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap() += 1;
839-
nodes[0].node.timer_tick_occurred();
840-
check_added_monitors!(nodes[0], 1);
841-
842-
let fee_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
843-
nodes[1].node.handle_update_fee(nodes[0].node.get_our_node_id(), &fee_update.update_fee.unwrap());
844-
commitment_signed_dance!(nodes[1], nodes[0], fee_update.commitment_signed, false);
842+
let _ = route_payment(&nodes[0], &[&nodes[1]], 1000);
845843

846844
reload_node!(
847845
nodes[1], config, &serialized_node, &[&serialized_monitor], persister, new_chain_monitor, nodes_1_deserialized
@@ -854,13 +852,19 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
854852
check_added_monitors(&nodes[0], 1);
855853
let reason = ClosureReason::HTLCsTimedOut { payment_hash: Some(payment_hash) };
856854
check_closed_event(&nodes[0], 1, reason, false, &[nodes[1].node.get_our_node_id()], 100_000);
857-
if anchors {
855+
if keyed_anchors || p2a_anchor {
858856
handle_bump_close_event(&nodes[0]);
859857
}
860858

861859
{
862860
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
863-
if anchors {
861+
if p2a_anchor {
862+
assert_eq!(txn.len(), 2);
863+
let anchor_tx = txn.pop().unwrap();
864+
let commitment_tx_a = txn.pop().unwrap();
865+
check_spends!(commitment_tx_a, funding_tx);
866+
check_spends!(anchor_tx, commitment_tx_a, coinbase_tx);
867+
} else if keyed_anchors {
864868
assert_eq!(txn.len(), 1);
865869
let commitment_tx_a = txn.pop().unwrap();
866870
check_spends!(commitment_tx_a, funding_tx);
@@ -883,31 +887,42 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
883887
check_added_monitors(&nodes[1], 1);
884888
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
885889
check_closed_event(&nodes[1], 1, reason, false, &[nodes[0].node.get_our_node_id()], 100_000);
886-
if anchors {
890+
if keyed_anchors || p2a_anchor {
887891
handle_bump_close_event(&nodes[1]);
888892
}
889893

890-
let commitment_b = {
894+
let commitment_b = if p2a_anchor {
895+
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
896+
assert_eq!(txn.len(), 2);
897+
let anchor_tx = txn.pop().unwrap();
898+
let tx = txn.pop().unwrap();
899+
check_spends!(tx, funding_tx);
900+
check_spends!(anchor_tx, tx, coinbase_tx);
901+
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
902+
mine_transactions(&nodes[0], &[&tx, &anchor_tx]);
903+
tx
904+
905+
} else {
891906
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
892907
assert_eq!(txn.len(), 1);
893908
let tx = txn.pop().unwrap();
894909
check_spends!(tx, funding_tx);
910+
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
911+
mine_transaction(&nodes[0], &tx);
895912
tx
896913
};
897914

898-
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
899-
mine_transaction(&nodes[0], &commitment_b);
900915
{
901916
if nodes[0].connect_style.borrow().updates_best_block_first() {
902917
// `commitment_a` is rebroadcast because the best block was updated prior to seeing
903918
// `commitment_b`.
904-
if anchors {
919+
if keyed_anchors || p2a_anchor {
905920
handle_bump_close_event(&nodes[0]);
906921
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
907922
assert_eq!(txn.len(), 3);
908923
check_spends!(txn[0], commitment_b);
909924
check_spends!(txn[1], funding_tx);
910-
check_spends!(txn[2], txn[1]); // Anchor output spend transaction.
925+
check_spends!(txn[2], txn[1], coinbase_tx); // Anchor output spend transaction.
911926
} else {
912927
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
913928
assert_eq!(txn.len(), 2);
@@ -924,15 +939,15 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
924939
// blocks, one to get us back to the original height, and another to retry our pending claims.
925940
disconnect_blocks(&nodes[0], 1);
926941
connect_blocks(&nodes[0], 2);
927-
if anchors {
942+
if keyed_anchors || p2a_anchor {
928943
handle_bump_close_event(&nodes[0]);
929944
}
930945
{
931946
let mut txn = nodes[0].tx_broadcaster.unique_txn_broadcast();
932-
if anchors {
947+
if keyed_anchors || p2a_anchor {
933948
assert_eq!(txn.len(), 2);
934949
check_spends!(txn[0], funding_tx);
935-
check_spends!(txn[1], txn[0]); // Anchor output spend.
950+
check_spends!(txn[1], txn[0], coinbase_tx); // Anchor output spend.
936951
} else {
937952
assert_eq!(txn.len(), 2);
938953
check_spends!(txn[0], txn[1]); // HTLC timeout A
@@ -944,13 +959,15 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
944959

945960
#[test]
946961
fn test_retries_own_commitment_broadcast_after_reorg() {
947-
do_test_retries_own_commitment_broadcast_after_reorg(false, false);
948-
do_test_retries_own_commitment_broadcast_after_reorg(false, true);
949-
do_test_retries_own_commitment_broadcast_after_reorg(true, false);
950-
do_test_retries_own_commitment_broadcast_after_reorg(true, true);
962+
do_test_retries_own_commitment_broadcast_after_reorg(false, false, false);
963+
do_test_retries_own_commitment_broadcast_after_reorg(false, false, true);
964+
do_test_retries_own_commitment_broadcast_after_reorg(true, false, false);
965+
do_test_retries_own_commitment_broadcast_after_reorg(true, false, true);
966+
do_test_retries_own_commitment_broadcast_after_reorg(false, true, false);
967+
do_test_retries_own_commitment_broadcast_after_reorg(false, true, true);
951968
}
952969

953-
fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
970+
fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool, p2a_anchor: bool) {
954971
// Previously, we had a bug where if there were two HTLCs which expired at different heights,
955972
// and a counterparty commitment transaction confirmed spending both of them, we'd continually
956973
// rebroadcast attempted HTLC claims against the higher-expiry HTLC forever.
@@ -960,8 +977,9 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
960977
// This test relies on being able to consolidate HTLC claims into a single transaction, which
961978
// requires anchors:
962979
let mut config = test_default_channel_config();
963-
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
964980
config.manually_accept_inbound_channels = true;
981+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
982+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = p2a_anchor;
965983

966984
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]);
967985
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -1010,29 +1028,58 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
10101028
handle_bump_close_event(&nodes[1]);
10111029

10121030
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
1013-
assert_eq!(txn.len(), 1);
1014-
let commitment_tx = txn.pop().unwrap();
1015-
check_spends!(commitment_tx, funding_tx);
1016-
1017-
mine_transaction(&nodes[0], &commitment_tx);
1018-
check_closed_broadcast(&nodes[0], 1, true);
1019-
let reason = ClosureReason::CommitmentTxConfirmed;
1020-
check_closed_event(&nodes[0], 1, reason, false, &[node_b_id], 10_000_000);
1021-
check_added_monitors(&nodes[0], 1);
1031+
let (commitment_tx, anchor_tx) = if p2a_anchor {
1032+
assert_eq!(txn.len(), 2);
1033+
let anchor_tx = txn.pop().unwrap();
1034+
let commitment_tx = txn.pop().unwrap();
1035+
check_spends!(commitment_tx, funding_tx);
1036+
check_spends!(anchor_tx, commitment_tx, coinbase_tx);
1037+
1038+
mine_transactions(&nodes[0], &[&commitment_tx, &anchor_tx]);
1039+
check_closed_broadcast(&nodes[0], 1, true);
1040+
let reason = ClosureReason::CommitmentTxConfirmed;
1041+
check_closed_event(&nodes[0], 1, reason, false, &[node_b_id], 10_000_000);
1042+
check_added_monitors(&nodes[0], 1);
1043+
1044+
mine_transactions(&nodes[1], &[&commitment_tx, &anchor_tx]);
1045+
handle_bump_events(&nodes[1], nodes[1].connect_style.borrow().updates_best_block_first(), 1);
1046+
(commitment_tx, Some(anchor_tx))
1047+
} else {
1048+
assert_eq!(txn.len(), 1);
1049+
let commitment_tx = txn.pop().unwrap();
1050+
check_spends!(commitment_tx, funding_tx);
1051+
1052+
mine_transaction(&nodes[0], &commitment_tx);
1053+
check_closed_broadcast(&nodes[0], 1, true);
1054+
let reason = ClosureReason::CommitmentTxConfirmed;
1055+
check_closed_event(&nodes[0], 1, reason, false, &[node_b_id], 10_000_000);
1056+
check_added_monitors(&nodes[0], 1);
1057+
1058+
mine_transaction(&nodes[1], &commitment_tx);
1059+
handle_bump_events(&nodes[1], nodes[1].connect_style.borrow().updates_best_block_first(), 1);
1060+
(commitment_tx, None)
1061+
};
10221062

1023-
mine_transaction(&nodes[1], &commitment_tx);
1024-
handle_bump_events(&nodes[1], nodes[1].connect_style.borrow().updates_best_block_first(), 1);
10251063

10261064
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
10271065
if nodes[1].connect_style.borrow().updates_best_block_first() {
10281066
assert_eq!(txn.len(), 3, "{txn:?}");
1029-
check_spends!(txn[0], funding_tx);
1030-
check_spends!(txn[1], txn[0]); // Anchor output spend.
1067+
if p2a_anchor {
1068+
check_spends!(txn[0], funding_tx);
1069+
check_spends!(txn[1], txn[0], anchor_tx.as_ref().unwrap()); // Anchor output spend.
1070+
} else {
1071+
check_spends!(txn[0], funding_tx);
1072+
check_spends!(txn[1], txn[0], coinbase_tx); // Anchor output spend.
1073+
}
10311074
} else {
10321075
assert_eq!(txn.len(), 1, "{txn:?}");
10331076
}
10341077
let bs_htlc_spend_tx = txn.pop().unwrap();
1035-
check_spends!(bs_htlc_spend_tx, commitment_tx, coinbase_tx);
1078+
if p2a_anchor {
1079+
check_spends!(bs_htlc_spend_tx, commitment_tx, anchor_tx.as_ref().unwrap());
1080+
} else {
1081+
check_spends!(bs_htlc_spend_tx, commitment_tx, coinbase_tx);
1082+
}
10361083

10371084
// Now connect blocks until the first HTLC expires
10381085
assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
@@ -1167,8 +1214,13 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
11671214

11681215
#[test]
11691216
fn test_split_htlc_expiry_tracking() {
1170-
do_test_split_htlc_expiry_tracking(true, true);
1171-
do_test_split_htlc_expiry_tracking(false, true);
1172-
do_test_split_htlc_expiry_tracking(true, false);
1173-
do_test_split_htlc_expiry_tracking(false, false);
1217+
do_test_split_htlc_expiry_tracking(true, true, false);
1218+
do_test_split_htlc_expiry_tracking(false, true, false);
1219+
do_test_split_htlc_expiry_tracking(true, false, false);
1220+
do_test_split_htlc_expiry_tracking(false, false, false);
1221+
1222+
do_test_split_htlc_expiry_tracking(true, true, true);
1223+
do_test_split_htlc_expiry_tracking(false, true, true);
1224+
do_test_split_htlc_expiry_tracking(true, false, true);
1225+
do_test_split_htlc_expiry_tracking(false, false, true);
11741226
}

0 commit comments

Comments
 (0)