Fix blinded recipient fail on receive reqs violation

If a blinded HTLC does not satisfy the receiver's requirements, e.g. bad CLTV
or amount, they should malformed-fail backwards with error code
INVALID_ONION_BLINDING and a zeroed out onion hash per BOLt 4.
This commit is contained in:
Valentine Wallace 2023-10-24 16:45:24 -04:00
parent 52f28e63e8
commit eca4dc0799
No known key found for this signature in database
GPG key ID: FD3E106A2CE099B4
2 changed files with 22 additions and 1 deletions

View file

@ -464,12 +464,16 @@ enum ReceiveCheckFail {
RecipientFail,
// Failure to decode the recipient's onion payload.
OnionDecodeFail,
// The incoming HTLC did not satisfy our requirements; in this case it underpaid us according to
// the expected receive amount in the onion.
ReceiveRequirements,
}
#[test]
fn multi_hop_receiver_fail() {
do_multi_hop_receiver_fail(ReceiveCheckFail::RecipientFail);
do_multi_hop_receiver_fail(ReceiveCheckFail::OnionDecodeFail);
do_multi_hop_receiver_fail(ReceiveCheckFail::ReceiveRequirements);
}
fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
@ -554,7 +558,14 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), update_add);
check_added_monitors!(nodes[2], 0);
do_commitment_signed_dance(&nodes[2], &nodes[1], &payment_event_1_2.commitment_msg, true, true);
}
},
ReceiveCheckFail::ReceiveRequirements => {
let update_add = &mut payment_event_1_2.msgs[0];
update_add.amount_msat -= 1;
nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), update_add);
check_added_monitors!(nodes[2], 0);
do_commitment_signed_dance(&nodes[2], &nodes[1], &payment_event_1_2.commitment_msg, true, true);
},
}
let updates_2_1 = get_htlc_update_msgs!(nodes[2], nodes[1].node.get_our_node_id());

View file

@ -3192,6 +3192,16 @@ where
{
let logger = WithContext::from(&self.logger, Some(*counterparty_node_id), Some(msg.channel_id));
log_info!(logger, "Failed to accept/forward incoming HTLC: {}", $msg);
if msg.blinding_point.is_some() {
return PendingHTLCStatus::Fail(HTLCFailureMsg::Malformed(
msgs::UpdateFailMalformedHTLC {
channel_id: msg.channel_id,
htlc_id: msg.htlc_id,
sha256_of_onion: [0; 32],
failure_code: INVALID_ONION_BLINDING,
}
))
}
return PendingHTLCStatus::Fail(HTLCFailureMsg::Relay(msgs::UpdateFailHTLC {
channel_id: msg.channel_id,
htlc_id: msg.htlc_id,