Skip to content

Commit 8b943c4

Browse files
committed
Add test_fail_htlc_backwards_with_reason
Add a test for newly added function failing back a basic payment and ensuring the intended failure code and data are sent back to the peer.
1 parent edf279f commit 8b943c4

File tree

1 file changed

+76
-1
lines changed

1 file changed

+76
-1
lines changed

lightning/src/ln/onion_route_tests.rs

+76-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::chain::channelmonitor::{CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCK
1515
use crate::chain::keysinterface::{EntropySource, NodeSigner, Recipient};
1616
use crate::ln::{PaymentHash, PaymentSecret};
1717
use crate::ln::channel::EXPIRE_PREV_CONFIG_TICKS;
18-
use crate::ln::channelmanager::{HTLCForwardInfo, CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA, PendingAddHTLCInfo, PendingHTLCInfo, PendingHTLCRouting, PaymentId};
18+
use crate::ln::channelmanager::{HTLCForwardInfo, FailureCode, CLTV_FAR_FAR_AWAY, MIN_CLTV_EXPIRY_DELTA, PendingAddHTLCInfo, PendingHTLCInfo, PendingHTLCRouting, PaymentId};
1919
use crate::ln::onion_utils;
2020
use crate::routing::gossip::{NetworkUpdate, RoutingFees};
2121
use crate::routing::router::{get_route, PaymentParameters, Route, RouteHint, RouteHintHop};
@@ -832,6 +832,81 @@ fn test_always_create_tlv_format_onion_payloads() {
832832
}
833833
}
834834

835+
fn do_test_fail_htlc_backwards_with_reason(failure_code: FailureCode) {
836+
837+
let chanmon_cfgs = create_chanmon_cfgs(2);
838+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
839+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
840+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
841+
842+
let (_, node_1_chan_update, _, _) = create_announced_chan_between_nodes(&nodes, 0, 1);
843+
844+
let payment_amount = 100_000;
845+
let (route, payment_hash, _, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[1], payment_amount);
846+
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
847+
check_added_monitors!(nodes[0], 1);
848+
849+
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
850+
let mut payment_event = SendEvent::from_event(events.pop().unwrap());
851+
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
852+
commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
853+
854+
expect_pending_htlcs_forwardable!(nodes[1]);
855+
expect_payment_claimable!(nodes[1], payment_hash, payment_secret, payment_amount);
856+
nodes[1].node.fail_htlc_backwards_with_reason(&payment_hash, &failure_code);
857+
858+
expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[1], vec![HTLCDestination::FailedPayment { payment_hash: payment_hash }]);
859+
check_added_monitors!(nodes[1], 1);
860+
861+
let events = nodes[1].node.get_and_clear_pending_msg_events();
862+
assert_eq!(events.len(), 1);
863+
let (update_fail_htlc, commitment_signed) = match events[0] {
864+
MessageSendEvent::UpdateHTLCs { node_id: _ , updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
865+
assert!(update_add_htlcs.is_empty());
866+
assert!(update_fulfill_htlcs.is_empty());
867+
assert_eq!(update_fail_htlcs.len(), 1);
868+
assert!(update_fail_malformed_htlcs.is_empty());
869+
assert!(update_fee.is_none());
870+
(update_fail_htlcs[0].clone(), commitment_signed)
871+
},
872+
_ => panic!("Unexpected event"),
873+
};
874+
875+
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &update_fail_htlc);
876+
commitment_signed_dance!(nodes[0], nodes[1], commitment_signed, false, true);
877+
878+
let failure_data = match failure_code {
879+
FailureCode::TemporaryNodeFailure => vec![],
880+
FailureCode::RequiredNodeFeatureMissing => vec![],
881+
FailureCode::ExpiryTooSoon => {
882+
let mut channel_update_data = Vec::new();
883+
(node_1_chan_update.serialized_length() as u16 + 2).write(&mut channel_update_data).unwrap();
884+
msgs::ChannelUpdate::TYPE.write(&mut channel_update_data).unwrap();
885+
node_1_chan_update.write(&mut channel_update_data).unwrap();
886+
channel_update_data
887+
},
888+
FailureCode::IncorrectOrUnknownPaymentDetails => {
889+
let mut htlc_msat_height_data = (payment_amount as u64).to_be_bytes().to_vec();
890+
htlc_msat_height_data.extend_from_slice(&CHAN_CONFIRM_DEPTH.to_be_bytes());
891+
htlc_msat_height_data
892+
}
893+
};
894+
895+
let failure_code = failure_code as u16;
896+
let permanent_flag = 0x4000;
897+
let permanent_fail = (failure_code & permanent_flag) != 0;
898+
expect_payment_failed!(nodes[0], payment_hash, permanent_fail, failure_code, failure_data);
899+
900+
}
901+
902+
#[test]
903+
fn test_fail_htlc_backwards_with_reason() {
904+
do_test_fail_htlc_backwards_with_reason(FailureCode::TemporaryNodeFailure);
905+
do_test_fail_htlc_backwards_with_reason(FailureCode::RequiredNodeFeatureMissing);
906+
do_test_fail_htlc_backwards_with_reason(FailureCode::ExpiryTooSoon);
907+
do_test_fail_htlc_backwards_with_reason(FailureCode::IncorrectOrUnknownPaymentDetails);
908+
}
909+
835910
macro_rules! get_phantom_route {
836911
($nodes: expr, $amt: expr, $channel: expr) => {{
837912
let secp_ctx = Secp256k1::new();

0 commit comments

Comments
 (0)