Skip to content

Commit b76476c

Browse files
committed
Add coverage for 0FC channels in reorg_tests
1 parent 2caaabf commit b76476c

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
@@ -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,32 @@ 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 {
827+
if keyed_anchors {
828828
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
829829
config.manually_accept_inbound_channels = true;
830+
} else if p2a_anchor {
831+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
832+
config.manually_accept_inbound_channels = true;
830833
}
831834
let persister;
832835
let new_chain_monitor;
833836
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config.clone())]);
834837
let nodes_1_deserialized;
835838
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
836839

840+
let coinbase_tx = provide_anchor_reserves(&nodes);
841+
837842
let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1);
838843

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

842847
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.
848+
// Trigger a new commitment by routing a dummy HTLC. We will have B broadcast the previous commitment.
845849
let serialized_node = nodes[1].node.encode();
846850
let serialized_monitor = get_monitor!(nodes[1], chan_id).encode();
847851

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);
852+
let _ = route_payment(&nodes[0], &[&nodes[1]], 1000);
855853

856854
reload_node!(
857855
nodes[1], config, &serialized_node, &[&serialized_monitor], persister, new_chain_monitor, nodes_1_deserialized
@@ -864,13 +862,19 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
864862
check_added_monitors(&nodes[0], 1);
865863
let reason = ClosureReason::HTLCsTimedOut { payment_hash: Some(payment_hash) };
866864
check_closed_event(&nodes[0], 1, reason, false, &[nodes[1].node.get_our_node_id()], 100_000);
867-
if anchors {
865+
if keyed_anchors || p2a_anchor {
868866
handle_bump_close_event(&nodes[0]);
869867
}
870868

871869
{
872870
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
873-
if anchors {
871+
if p2a_anchor {
872+
assert_eq!(txn.len(), 2);
873+
let anchor_tx = txn.pop().unwrap();
874+
let commitment_tx_a = txn.pop().unwrap();
875+
check_spends!(commitment_tx_a, funding_tx);
876+
check_spends!(anchor_tx, commitment_tx_a, coinbase_tx);
877+
} else if keyed_anchors {
874878
assert_eq!(txn.len(), 1);
875879
let commitment_tx_a = txn.pop().unwrap();
876880
check_spends!(commitment_tx_a, funding_tx);
@@ -893,31 +897,42 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
893897
check_added_monitors(&nodes[1], 1);
894898
let reason = ClosureReason::HolderForceClosed { broadcasted_latest_txn: Some(true), message };
895899
check_closed_event(&nodes[1], 1, reason, false, &[nodes[0].node.get_our_node_id()], 100_000);
896-
if anchors {
900+
if keyed_anchors || p2a_anchor {
897901
handle_bump_close_event(&nodes[1]);
898902
}
899903

900-
let commitment_b = {
904+
let commitment_b = if p2a_anchor {
905+
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
906+
assert_eq!(txn.len(), 2);
907+
let anchor_tx = txn.pop().unwrap();
908+
let tx = txn.pop().unwrap();
909+
check_spends!(tx, funding_tx);
910+
check_spends!(anchor_tx, tx, coinbase_tx);
911+
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
912+
mine_transactions(&nodes[0], &[&tx, &anchor_tx]);
913+
tx
914+
915+
} else {
901916
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
902917
assert_eq!(txn.len(), 1);
903918
let tx = txn.pop().unwrap();
904919
check_spends!(tx, funding_tx);
920+
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
921+
mine_transaction(&nodes[0], &tx);
905922
tx
906923
};
907924

908-
// Confirm B's commitment, A should now broadcast an HTLC timeout for commitment B.
909-
mine_transaction(&nodes[0], &commitment_b);
910925
{
911926
if nodes[0].connect_style.borrow().updates_best_block_first() {
912927
// `commitment_a` is rebroadcast because the best block was updated prior to seeing
913928
// `commitment_b`.
914-
if anchors {
929+
if keyed_anchors || p2a_anchor {
915930
handle_bump_close_event(&nodes[0]);
916931
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
917932
assert_eq!(txn.len(), 3);
918933
check_spends!(txn[0], commitment_b);
919934
check_spends!(txn[1], funding_tx);
920-
check_spends!(txn[2], txn[1]); // Anchor output spend transaction.
935+
check_spends!(txn[2], txn[1], coinbase_tx); // Anchor output spend transaction.
921936
} else {
922937
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
923938
assert_eq!(txn.len(), 2);
@@ -934,15 +949,15 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
934949
// blocks, one to get us back to the original height, and another to retry our pending claims.
935950
disconnect_blocks(&nodes[0], 1);
936951
connect_blocks(&nodes[0], 2);
937-
if anchors {
952+
if keyed_anchors || p2a_anchor {
938953
handle_bump_close_event(&nodes[0]);
939954
}
940955
{
941956
let mut txn = nodes[0].tx_broadcaster.unique_txn_broadcast();
942-
if anchors {
957+
if keyed_anchors || p2a_anchor {
943958
assert_eq!(txn.len(), 2);
944959
check_spends!(txn[0], funding_tx);
945-
check_spends!(txn[1], txn[0]); // Anchor output spend.
960+
check_spends!(txn[1], txn[0], coinbase_tx); // Anchor output spend.
946961
} else {
947962
assert_eq!(txn.len(), 2);
948963
check_spends!(txn[0], txn[1]); // HTLC timeout A
@@ -954,13 +969,15 @@ fn do_test_retries_own_commitment_broadcast_after_reorg(anchors: bool, revoked_c
954969

955970
#[test]
956971
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);
972+
do_test_retries_own_commitment_broadcast_after_reorg(false, false, false);
973+
do_test_retries_own_commitment_broadcast_after_reorg(false, false, true);
974+
do_test_retries_own_commitment_broadcast_after_reorg(true, false, false);
975+
do_test_retries_own_commitment_broadcast_after_reorg(true, false, true);
976+
do_test_retries_own_commitment_broadcast_after_reorg(false, true, false);
977+
do_test_retries_own_commitment_broadcast_after_reorg(false, true, true);
961978
}
962979

963-
fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
980+
fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool, p2a_anchor: bool) {
964981
// Previously, we had a bug where if there were two HTLCs which expired at different heights,
965982
// and a counterparty commitment transaction confirmed spending both of them, we'd continually
966983
// rebroadcast attempted HTLC claims against the higher-expiry HTLC forever.
@@ -970,8 +987,9 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
970987
// This test relies on being able to consolidate HTLC claims into a single transaction, which
971988
// requires anchors:
972989
let mut config = test_default_channel_config();
973-
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
974990
config.manually_accept_inbound_channels = true;
991+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
992+
config.channel_handshake_config.negotiate_anchor_zero_fee_commitments = p2a_anchor;
975993

976994
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config.clone()), Some(config)]);
977995
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
@@ -1020,29 +1038,58 @@ fn do_test_split_htlc_expiry_tracking(use_third_htlc: bool, reorg_out: bool) {
10201038
handle_bump_close_event(&nodes[1]);
10211039

10221040
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);
1026-
1027-
mine_transaction(&nodes[0], &commitment_tx);
1028-
check_closed_broadcast(&nodes[0], 1, false);
1029-
let reason = ClosureReason::CommitmentTxConfirmed;
1030-
check_closed_event(&nodes[0], 1, reason, false, &[node_b_id], 10_000_000);
1031-
check_added_monitors(&nodes[0], 1);
1041+
let (commitment_tx, anchor_tx) = if p2a_anchor {
1042+
assert_eq!(txn.len(), 2);
1043+
let anchor_tx = txn.pop().unwrap();
1044+
let commitment_tx = txn.pop().unwrap();
1045+
check_spends!(commitment_tx, funding_tx);
1046+
check_spends!(anchor_tx, commitment_tx, coinbase_tx);
1047+
1048+
mine_transactions(&nodes[0], &[&commitment_tx, &anchor_tx]);
1049+
check_closed_broadcast(&nodes[0], 1, false);
1050+
let reason = ClosureReason::CommitmentTxConfirmed;
1051+
check_closed_event(&nodes[0], 1, reason, false, &[node_b_id], 10_000_000);
1052+
check_added_monitors(&nodes[0], 1);
1053+
1054+
mine_transactions(&nodes[1], &[&commitment_tx, &anchor_tx]);
1055+
handle_bump_events(&nodes[1], nodes[1].connect_style.borrow().updates_best_block_first(), 1);
1056+
(commitment_tx, Some(anchor_tx))
1057+
} else {
1058+
assert_eq!(txn.len(), 1);
1059+
let commitment_tx = txn.pop().unwrap();
1060+
check_spends!(commitment_tx, funding_tx);
1061+
1062+
mine_transaction(&nodes[0], &commitment_tx);
1063+
check_closed_broadcast(&nodes[0], 1, false);
1064+
let reason = ClosureReason::CommitmentTxConfirmed;
1065+
check_closed_event(&nodes[0], 1, reason, false, &[node_b_id], 10_000_000);
1066+
check_added_monitors(&nodes[0], 1);
1067+
1068+
mine_transaction(&nodes[1], &commitment_tx);
1069+
handle_bump_events(&nodes[1], nodes[1].connect_style.borrow().updates_best_block_first(), 1);
1070+
(commitment_tx, None)
1071+
};
10321072

1033-
mine_transaction(&nodes[1], &commitment_tx);
1034-
handle_bump_events(&nodes[1], nodes[1].connect_style.borrow().updates_best_block_first(), 1);
10351073

10361074
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
10371075
if nodes[1].connect_style.borrow().updates_best_block_first() {
10381076
assert_eq!(txn.len(), 3, "{txn:?}");
1039-
check_spends!(txn[0], funding_tx);
1040-
check_spends!(txn[1], txn[0]); // Anchor output spend.
1077+
if p2a_anchor {
1078+
check_spends!(txn[0], funding_tx);
1079+
check_spends!(txn[1], txn[0], anchor_tx.as_ref().unwrap()); // Anchor output spend.
1080+
} else {
1081+
check_spends!(txn[0], funding_tx);
1082+
check_spends!(txn[1], txn[0], coinbase_tx); // Anchor output spend.
1083+
}
10411084
} else {
10421085
assert_eq!(txn.len(), 1, "{txn:?}");
10431086
}
10441087
let bs_htlc_spend_tx = txn.pop().unwrap();
1045-
check_spends!(bs_htlc_spend_tx, commitment_tx, coinbase_tx);
1088+
if p2a_anchor {
1089+
check_spends!(bs_htlc_spend_tx, commitment_tx, anchor_tx.as_ref().unwrap());
1090+
} else {
1091+
check_spends!(bs_htlc_spend_tx, commitment_tx, coinbase_tx);
1092+
}
10461093

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

11781225
#[test]
11791226
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);
1227+
do_test_split_htlc_expiry_tracking(true, true, false);
1228+
do_test_split_htlc_expiry_tracking(false, true, false);
1229+
do_test_split_htlc_expiry_tracking(true, false, false);
1230+
do_test_split_htlc_expiry_tracking(false, false, false);
1231+
1232+
do_test_split_htlc_expiry_tracking(true, true, true);
1233+
do_test_split_htlc_expiry_tracking(false, true, true);
1234+
do_test_split_htlc_expiry_tracking(true, false, true);
1235+
do_test_split_htlc_expiry_tracking(false, false, true);
11841236
}

0 commit comments

Comments
 (0)