msg: &msgs::UpdateAddHTLC, hop_data: msgs::InboundOnionPayload, hop_hmac: [u8; 32],
new_packet_bytes: [u8; onion_utils::ONION_DATA_LEN], shared_secret: [u8; 32],
next_packet_pubkey_opt: Option<Result<PublicKey, secp256k1::Error>>
msg: &msgs::UpdateAddHTLC, hop_data: msgs::InboundOnionPayload, hop_hmac: [u8; 32],
new_packet_bytes: [u8; onion_utils::ONION_DATA_LEN], shared_secret: [u8; 32],
next_packet_pubkey_opt: Option<Result<PublicKey, secp256k1::Error>>
).map_err(|()| {
// We should be returning malformed here if `msg.blinding_point` is set, but this is
// unreachable right now since we checked it in `decode_update_add_htlc_onion`.
).map_err(|()| {
// We should be returning malformed here if `msg.blinding_point` is set, but this is
// unreachable right now since we checked it in `decode_update_add_htlc_onion`.
msg: "Underflow calculating outbound amount or cltv value for blinded forward",
err_code: INVALID_ONION_BLINDING,
err_data: vec![0; 32],
msg: "Underflow calculating outbound amount or cltv value for blinded forward",
err_code: INVALID_ONION_BLINDING,
err_data: vec![0; 32],
(short_channel_id, amt_to_forward, outgoing_cltv_value, Some(intro_node_blinding_point))
},
msgs::InboundOnionPayload::Receive { .. } | msgs::InboundOnionPayload::BlindedReceive { .. } =>
(short_channel_id, amt_to_forward, outgoing_cltv_value, Some(intro_node_blinding_point))
},
msgs::InboundOnionPayload::Receive { .. } | msgs::InboundOnionPayload::BlindedReceive { .. } =>
hop_data: msgs::InboundOnionPayload, shared_secret: [u8; 32], payment_hash: PaymentHash,
amt_msat: u64, cltv_expiry: u32, phantom_shared_secret: Option<[u8; 32]>, allow_underpay: bool,
counterparty_skimmed_fee_msat: Option<u64>, current_height: u32, accept_mpp_keysend: bool,
hop_data: msgs::InboundOnionPayload, shared_secret: [u8; 32], payment_hash: PaymentHash,
amt_msat: u64, cltv_expiry: u32, phantom_shared_secret: Option<[u8; 32]>, allow_underpay: bool,
counterparty_skimmed_fee_msat: Option<u64>, current_height: u32, accept_mpp_keysend: bool,
- payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, outgoing_cltv_value,
+ payment_data, keysend_preimage, custom_tlvs, onion_amt_msat, onion_cltv_expiry,
payment_metadata, requires_blinded_error
) = match hop_data {
msgs::InboundOnionPayload::Receive {
payment_metadata, requires_blinded_error
) = match hop_data {
msgs::InboundOnionPayload::Receive {
- payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata, ..
+ payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
+ cltv_expiry_height, payment_metadata, ..
- (payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata,
- false),
+ (payment_data, keysend_preimage, custom_tlvs, sender_intended_htlc_amt_msat,
+ cltv_expiry_height, payment_metadata, false),
- amt_msat, total_msat, outgoing_cltv_value, payment_secret, intro_node_blinding_point,
- payment_constraints, ..
+ sender_intended_htlc_amt_msat, total_msat, cltv_expiry_height, payment_secret,
+ intro_node_blinding_point, payment_constraints, ..
- check_blinded_payment_constraints(amt_msat, cltv_expiry, &payment_constraints)
+ check_blinded_payment_constraints(
+ sender_intended_htlc_amt_msat, cltv_expiry, &payment_constraints
+ )
err_code: INVALID_ONION_BLINDING,
err_data: vec![0; 32],
msg: "Amount or cltv_expiry violated blinded payment constraints",
}
})?;
let payment_data = msgs::FinalOnionHopData { payment_secret, total_msat };
err_code: INVALID_ONION_BLINDING,
err_data: vec![0; 32],
msg: "Amount or cltv_expiry violated blinded payment constraints",
}
})?;
let payment_data = msgs::FinalOnionHopData { payment_secret, total_msat };
- (Some(payment_data), None, Vec::new(), amt_msat, outgoing_cltv_value, None,
- intro_node_blinding_point.is_none())
+ (Some(payment_data), None, Vec::new(), sender_intended_htlc_amt_msat, cltv_expiry_height,
+ None, intro_node_blinding_point.is_none())
err_code: 0x4000|22,
err_data: Vec::new(),
msg: "Got non final data with an HMAC of 0",
})
},
msgs::InboundOnionPayload::BlindedForward { .. } => {
err_code: 0x4000|22,
err_data: Vec::new(),
msg: "Got non final data with an HMAC of 0",
})
},
msgs::InboundOnionPayload::BlindedForward { .. } => {
err_code: INVALID_ONION_BLINDING,
err_data: vec![0; 32],
msg: "Got blinded non final data with an HMAC of 0",
err_code: INVALID_ONION_BLINDING,
err_data: vec![0; 32],
msg: "Got blinded non final data with an HMAC of 0",
msg: "Upstream node set CLTV to less than the CLTV set by the sender",
err_code: 18,
err_data: cltv_expiry.to_be_bytes().to_vec()
msg: "Upstream node set CLTV to less than the CLTV set by the sender",
err_code: 18,
err_data: cltv_expiry.to_be_bytes().to_vec()
let mut err_data = Vec::with_capacity(12);
err_data.extend_from_slice(&amt_msat.to_be_bytes());
err_data.extend_from_slice(¤t_height.to_be_bytes());
let mut err_data = Vec::with_capacity(12);
err_data.extend_from_slice(&amt_msat.to_be_bytes());
err_data.extend_from_slice(¤t_height.to_be_bytes());
err_code: 0x4000 | 15, err_data,
msg: "The final CLTV expiry is too soon to handle",
});
err_code: 0x4000 | 15, err_data,
msg: "The final CLTV expiry is too soon to handle",
});
(allow_underpay && onion_amt_msat >
amt_msat.saturating_add(counterparty_skimmed_fee_msat.unwrap_or(0)))
{
(allow_underpay && onion_amt_msat >
amt_msat.saturating_add(counterparty_skimmed_fee_msat.unwrap_or(0)))
{
err_code: 19,
err_data: amt_msat.to_be_bytes().to_vec(),
msg: "Upstream node sent less than we were supposed to receive in payment",
err_code: 19,
err_data: amt_msat.to_be_bytes().to_vec(),
msg: "Upstream node sent less than we were supposed to receive in payment",
// time discrepancies due to a hash collision with X.
let hashed_preimage = PaymentHash(Sha256::hash(&payment_preimage.0).to_byte_array());
if hashed_preimage != payment_hash {
// time discrepancies due to a hash collision with X.
let hashed_preimage = PaymentHash(Sha256::hash(&payment_preimage.0).to_byte_array());
if hashed_preimage != payment_hash {
err_code: 0x4000|22,
err_data: Vec::new(),
msg: "Payment preimage didn't match payment hash",
});
}
if !accept_mpp_keysend && payment_data.is_some() {
err_code: 0x4000|22,
err_data: Vec::new(),
msg: "Payment preimage didn't match payment hash",
});
}
if !accept_mpp_keysend && payment_data.is_some() {
err_code: 0x4000|0x2000|3,
err_data: Vec::new(),
msg: "We require payment_secrets",
err_code: 0x4000|0x2000|3,
err_data: Vec::new(),
msg: "We require payment_secrets",
incoming_shared_secret: shared_secret,
incoming_amt_msat: Some(amt_msat),
outgoing_amt_msat: onion_amt_msat,
incoming_shared_secret: shared_secret,
incoming_amt_msat: Some(amt_msat),
outgoing_amt_msat: onion_amt_msat,
pub fn peel_payment_onion<NS: Deref, L: Deref, T: secp256k1::Verification>(
msg: &msgs::UpdateAddHTLC, node_signer: &NS, logger: &L, secp_ctx: &Secp256k1<T>,
cur_height: u32, accept_mpp_keysend: bool, allow_skimmed_fees: bool,
pub fn peel_payment_onion<NS: Deref, L: Deref, T: secp256k1::Verification>(
msg: &msgs::UpdateAddHTLC, node_signer: &NS, logger: &L, secp_ctx: &Secp256k1<T>,
cur_height: u32, accept_mpp_keysend: bool, allow_skimmed_fees: bool,
HTLCFailureMsg::Relay(r) => (0x4000 | 22, r.reason.data),
};
let msg = "Failed to decode update add htlc onion";
HTLCFailureMsg::Relay(r) => (0x4000 | 22, r.reason.data),
};
let msg = "Failed to decode update add htlc onion";
} = match next_packet_details_opt {
Some(next_packet_details) => next_packet_details,
// Forward should always include the next hop details
} = match next_packet_details_opt {
Some(next_packet_details) => next_packet_details,
// Forward should always include the next hop details
if let Err((err_msg, code)) = check_incoming_htlc_cltv(
cur_height, outgoing_cltv_value, msg.cltv_expiry
) {
if let Err((err_msg, code)) = check_incoming_htlc_cltv(
cur_height, outgoing_cltv_value, msg.cltv_expiry
) {