Skip to content

Commit 25fce0a

Browse files
committed
Add coverage for 0FC channels in reorg_tests
1 parent 175a3e3 commit 25fce0a

File tree

1 file changed

+89
-43
lines changed

1 file changed

+89
-43
lines changed

lightning/src/ln/reorg_tests.rs

Lines changed: 89 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ fn test_htlc_preimage_claim_prev_counterparty_commitment_after_current_counterpa
815815
assert_eq!(htlc_preimage_tx.input[0].witness.second_to_last().unwrap(), &payment_preimage.0[..]);
816816
}
817817

818-
fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_counterparty_commitment: bool) {
818+
fn do_test_retries_own_commitment_broadcast_after_reorg(keyed_anchors: bool, p2a_anchor: bool, revoked_counterparty_commitment: bool) {
819819
// Tests that a node will retry broadcasting its own commitment after seeing a confirmed
820820
// counterparty commitment be reorged out.
821821
let mut chanmon_cfgs = create_chanmon_cfgs(2);
@@ -824,34 +824,28 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
824824
}
825825
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
826826
let mut config = test_default_channel_config();
827-
if anchors {
828-
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
829-
config.manually_accept_inbound_channels = true;
830-
}
827+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = keyed_anchors;
828+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = p2a_anchor;
829+
config.manually_accept_inbound_channels = keyed_anchors || p2a_anchor;
831830
let persister;
832831
let new_chain_monitor;
833832
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config.clone())]);
834833
let nodes_1_deserialized;
835834
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
836835

836+
let coinbase_tx = provide_anchor_reserves(&nodes);
837+
837838
let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1);
838839

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

842843
if revoked_counterparty_commitment {
843-
// Trigger a fee update such that we advance the state. We will have B broadcast its state
844-
// without the fee update.
844+
// Trigger a new commitment by routing a dummy HTLC. We will have B broadcast the previous commitment.
845845
let serialized_node = nodes[1].node.encode();
846846
let serialized_monitor = get_monitor!(nodes[1], chan_id).encode();
847847

848-
*chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap() += 1;
849-
nodes[0].node.timer_tick_occurred();
850-
check_added_monitors!(nodes[0], 1);
851-
852-
let fee_update = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
853-
nodes[1].node.handle_update_fee(nodes[0].node.get_our_node_id(), &fee_update.update_fee.unwrap());
854-
commitment_signed_dance!(nodes[1], nodes[0], fee_update.commitment_signed, false);
848+
let _ = route_payment(&nodes[0], &[&nodes[1]], 1000);
855849

856850
reload_node!(
857851
nodes[1], config, &serialized_node, &[&serialized_monitor], persister, new_chain_monitor, nodes_1_deserialized
@@ -864,13 +858,19 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
864858
check_added_monitors(&nodes[0], 1);
865859
let reason = ClosureReason::HTLCsTimedOut { payment_hash: Some(payment_hash) };
866860
check_closed_event(&nodes[0], 1, reason, false, &[nodes[1].node.get_our_node_id()], 100_000);
867-
if anchors {
861+
if keyed_anchors || p2a_anchor {
868862
handle_bump_close_event(&nodes[0]);
869863
}
870864

871865
{
872866
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
873-
if anchors {
867+
if p2a_anchor {
868+
assert_eq!(txn.len(), 2);
869+
let anchor_tx = txn.pop().unwrap();
870+
let commitment_tx_a = txn.pop().unwrap();
871+
check_spends!(commitment_tx_a, funding_tx);
872+
check_spends!(anchor_tx, commitment_tx_a, coinbase_tx);
873+
} else if keyed_anchors {
874874
assert_eq!(txn.len(), 1);
875875
let commitment_tx_a = txn.pop().unwrap();
876876
check_spends!(commitment_tx_a, funding_tx);
@@ -893,31 +893,42 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
893893
check_added_monitors(&nodes[1], 1);
894894
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
895895
check_closed_event(&nodes[1], 1, reason, false, &[nodes[0].node.get_our_node_id()], 100_000);
896-
if anchors {
896+
if keyed_anchors || p2a_anchor {
897897
handle_bump_close_event(&nodes[1]);
898898
}
899899

900-
let commitment_b = {
900+
let commitment_b = if p2a_anchor {
901+
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
902+
assert_eq!(txn.len(), 2);
903+
let anchor_tx = txn.pop().unwrap();
904+
let tx = txn.pop().unwrap();
905+
check_spends!(tx, funding_tx);
906+
check_spends!(anchor_tx, tx, coinbase_tx);
907+
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
908+
mine_transactions(&nodes[0], &[&tx, &anchor_tx]);
909+
tx
910+
911+
} else {
901912
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
902913
assert_eq!(txn.len(), 1);
903914
let tx = txn.pop().unwrap();
904915
check_spends!(tx, funding_tx);
916+
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
917+
mine_transaction(&nodes[0], &tx);
905918
tx
906919
};
907920

908-
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
909-
mine_transaction(&nodes[0], &commitment_b);
910921
{
911922
if nodes[0].connect_style.borrow().updates_best_block_first() {
912923
// `commitment_a` is rebroadcast because the best block was updated prior to seeing
913924
// `commitment_b`.
914-
if anchors {
925+
if keyed_anchors || p2a_anchor {
915926
handle_bump_close_event(&nodes[0]);
916927
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
917928
assert_eq!(txn.len(), 3);
918929
check_spends!(txn[0], commitment_b);
919930
check_spends!(txn[1], funding_tx);
920-
check_spends!(txn[2], txn[1]); // Anchor output spend transaction.
931+
check_spends!(txn[2], txn[1], coinbase_tx); // Anchor output spend transaction.
921932
} else {
922933
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
923934
assert_eq!(txn.len(), 2);
@@ -934,15 +945,15 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
934945
// blocks, one to get us back to the original height, and another to retry our pending claims.
935946
disconnect_blocks(&nodes[0], 1);
936947
connect_blocks(&nodes[0], 2);
937-
if anchors {
948+
if keyed_anchors || p2a_anchor {
938949
handle_bump_close_event(&nodes[0]);
939950
}
940951
{
941952
let mut txn = nodes[0].tx_broadcaster.unique_txn_broadcast();
942-
if anchors {
953+
if keyed_anchors || p2a_anchor {
943954
assert_eq!(txn.len(), 2);
944955
check_spends!(txn[0], funding_tx);
945-
check_spends!(txn[1], txn[0]); // Anchor output spend.
956+
check_spends!(txn[1], txn[0], coinbase_tx); // Anchor output spend.
946957
} else {
947958
assert_eq!(txn.len(), 2);
948959
check_spends!(txn[0], txn[1]); // HTLC timeout A
@@ -954,13 +965,15 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
954965

955966
#[test]
956967
fn test_retries_own_commitment_broadcast_after_reorg() {
957-
do_test_retries_own_commitment_broadcast_after_reorg(false, false);
958-
do_test_retries_own_commitment_broadcast_after_reorg(false, true);
959-
do_test_retries_own_commitment_broadcast_after_reorg(true, false);
960-
do_test_retries_own_commitment_broadcast_after_reorg(true, true);
968+
do_test_retries_own_commitment_broadcast_after_reorg(false, false, false);
969+
do_test_retries_own_commitment_broadcast_after_reorg(false, false, true);
970+
do_test_retries_own_commitment_broadcast_after_reorg(true, false, false);
971+
do_test_retries_own_commitment_broadcast_after_reorg(true, false, true);
972+
do_test_retries_own_commitment_broadcast_after_reorg(false, true, false);
973+
do_test_retries_own_commitment_broadcast_after_reorg(false, true, true);
961974
}
962975

963-
fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
976+
fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool, p2a_anchor: bool) {
964977
// Previously, we had a bug where if there were two HTLCs which expired at different heights,
965978
// and a counterparty commitment transaction confirmed spending both of them, we'd continually
966979
// rebroadcast attempted HTLC claims against the higher-expiry HTLC forever.
@@ -970,8 +983,9 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
970983
// This test relies on being able to consolidate HTLC claims into a single transaction, which
971984
// requires anchors:
972985
let mut config = test_default_channel_config();
973-
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
974986
config.manually_accept_inbound_channels = true;
987+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
988+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = p2a_anchor;
975989

976990
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]);
977991
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -1020,29 +1034,56 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
10201034
handle_bump_close_event(&nodes[1]);
10211035

10221036
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
1023-
assert_eq!(txn.len(), 1);
1024-
let commitment_tx = txn.pop().unwrap();
1025-
check_spends!(commitment_tx, funding_tx);
1037+
let (commitment_tx, anchor_tx) = if p2a_anchor {
1038+
assert_eq!(txn.len(), 2);
1039+
let anchor_tx = txn.pop().unwrap();
1040+
let commitment_tx = txn.pop().unwrap();
1041+
check_spends!(commitment_tx, funding_tx);
1042+
check_spends!(anchor_tx, commitment_tx, coinbase_tx);
1043+
(commitment_tx, Some(anchor_tx))
1044+
} else {
1045+
assert_eq!(txn.len(), 1);
1046+
let commitment_tx = txn.pop().unwrap();
1047+
check_spends!(commitment_tx, funding_tx);
1048+
(commitment_tx, None)
1049+
};
10261050

1027-
mine_transaction(&nodes[0], &commitment_tx);
1051+
if let Some(ref a_tx) = anchor_tx {
1052+
mine_transactions(&nodes[0], &[&commitment_tx, a_tx]);
1053+
} else {
1054+
mine_transaction(&nodes[0], &commitment_tx);
1055+
}
10281056
check_closed_broadcast(&nodes[0], 1, false);
10291057
let reason = ClosureReason::CommitmentTxConfirmed;
10301058
check_closed_event(&nodes[0], 1, reason, false, &[node_b_id], 10_000_000);
10311059
check_added_monitors(&nodes[0], 1);
10321060

1033-
mine_transaction(&nodes[1], &commitment_tx);
1061+
if let Some(ref a_tx) = anchor_tx {
1062+
mine_transactions(&nodes[1], &[&commitment_tx, a_tx]);
1063+
} else {
1064+
mine_transaction(&nodes[1], &commitment_tx);
1065+
}
10341066
handle_bump_events(&nodes[1], nodes[1].connect_style.borrow().updates_best_block_first(), 1);
10351067

10361068
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
10371069
if nodes[1].connect_style.borrow().updates_best_block_first() {
10381070
assert_eq!(txn.len(), 3, "{txn:?}");
1039-
check_spends!(txn[0], funding_tx);
1040-
check_spends!(txn[1], txn[0]); // Anchor output spend.
1071+
if p2a_anchor {
1072+
check_spends!(txn[0], funding_tx);
1073+
check_spends!(txn[1], txn[0], anchor_tx.as_ref().unwrap()); // Anchor output spend.
1074+
} else {
1075+
check_spends!(txn[0], funding_tx);
1076+
check_spends!(txn[1], txn[0], coinbase_tx); // Anchor output spend.
1077+
}
10411078
} else {
10421079
assert_eq!(txn.len(), 1, "{txn:?}");
10431080
}
10441081
let bs_htlc_spend_tx = txn.pop().unwrap();
1045-
check_spends!(bs_htlc_spend_tx, commitment_tx, coinbase_tx);
1082+
if p2a_anchor {
1083+
check_spends!(bs_htlc_spend_tx, commitment_tx, anchor_tx.as_ref().unwrap());
1084+
} else {
1085+
check_spends!(bs_htlc_spend_tx, commitment_tx, coinbase_tx);
1086+
}
10461087

10471088
// Now connect blocks until the first HTLC expires
10481089
assert_eq!(nodes[0].tx_broadcaster.txn_broadcast().len(), 0);
@@ -1177,8 +1218,13 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
11771218

11781219
#[test]
11791220
fn test_split_htlc_expiry_tracking() {
1180-
do_test_split_htlc_expiry_tracking(true, true);
1181-
do_test_split_htlc_expiry_tracking(false, true);
1182-
do_test_split_htlc_expiry_tracking(true, false);
1183-
do_test_split_htlc_expiry_tracking(false, false);
1221+
do_test_split_htlc_expiry_tracking(true, true, false);
1222+
do_test_split_htlc_expiry_tracking(false, true, false);
1223+
do_test_split_htlc_expiry_tracking(true, false, false);
1224+
do_test_split_htlc_expiry_tracking(false, false, false);
1225+
1226+
do_test_split_htlc_expiry_tracking(true, true, true);
1227+
do_test_split_htlc_expiry_tracking(false, true, true);
1228+
do_test_split_htlc_expiry_tracking(true, false, true);
1229+
do_test_split_htlc_expiry_tracking(false, false, true);
11841230
}

0 commit comments

Comments
 (0)