+ /// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
+ /// that we want to return and a channel.
+ ///
+ /// This is for failures on the channel on which the HTLC was *received*, not failures
+ /// forwarding
+ fn get_htlc_inbound_temp_fail_err_and_data(&self, desired_err_code: u16, chan: &Channel<Signer>) -> (u16, Vec<u8>) {
+ // We can't be sure what SCID was used when relaying inbound towards us, so we have to
+ // guess somewhat. If its a public channel, we figure best to just use the real SCID (as
+ // we're not leaking that we have a channel with the counterparty), otherwise we try to use
+ // an inbound SCID alias before the real SCID.
+ let scid_pref = if chan.should_announce() {
+ chan.get_short_channel_id().or(chan.latest_inbound_scid_alias())
+ } else {
+ chan.latest_inbound_scid_alias().or(chan.get_short_channel_id())
+ };
+ if let Some(scid) = scid_pref {
+ self.get_htlc_temp_fail_err_and_data(desired_err_code, scid, chan)
+ } else {
+ (0x4000|10, Vec::new())
+ }
+ }
+
+
+ /// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
+ /// that we want to return and a channel.
+ fn get_htlc_temp_fail_err_and_data(&self, desired_err_code: u16, scid: u64, chan: &Channel<Signer>) -> (u16, Vec<u8>) {
+ debug_assert_eq!(desired_err_code & 0x1000, 0x1000);
+ if let Ok(upd) = self.get_channel_update_for_onion(scid, chan) {
+ let mut enc = VecWriter(Vec::with_capacity(upd.serialized_length() + 4));
+ if desired_err_code == 0x1000 | 20 {
+ // TODO: underspecified, follow https://github.com/lightning/bolts/issues/791
+ 0u16.write(&mut enc).expect("Writes cannot fail");
+ }
+ (upd.serialized_length() as u16).write(&mut enc).expect("Writes cannot fail");
+ upd.write(&mut enc).expect("Writes cannot fail");
+ (desired_err_code, enc.0)
+ } else {
+ // If we fail to get a unicast channel_update, it implies we don't yet have an SCID,
+ // which means we really shouldn't have gotten a payment to be forwarded over this
+ // channel yet, or if we did it's from a route hint. Either way, returning an error of
+ // PERM|no_such_channel should be fine.
+ (0x4000|10, Vec::new())
+ }
+ }
+