Skip to content

Commit f2b52f7

Browse files
Support decoding inbound blinded onion payloads
1 parent 1913d41 commit f2b52f7

File tree

4 files changed

+146
-45
lines changed

4 files changed

+146
-45
lines changed

fuzz/src/onion_hop_data.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,22 @@
1010
// This file is auto-generated by gen_target.sh based on msg_target_template.txt
1111
// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
1212

13+
use bitcoin::secp256k1::PublicKey;
1314
use crate::utils::test_logger;
15+
use lightning::util::ser::ReadableArgs;
16+
use lightning::util::test_utils;
1417

1518
#[inline]
1619
pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
17-
use lightning::util::ser::Readable;
1820
let mut r = ::std::io::Cursor::new(data);
19-
let _ = <lightning::ln::msgs::InboundOnionPayload as Readable>::read(&mut r);
21+
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
22+
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(Option<PublicKey>, &&test_utils::TestNodeSigner)>>::read(&mut r, (None, &&node_signer));
2023
}
2124

2225
#[no_mangle]
2326
pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
24-
use lightning::util::ser::Readable;
2527
let data = unsafe { std::slice::from_raw_parts(data, datalen) };
2628
let mut r = ::std::io::Cursor::new(data);
27-
let _ = <lightning::ln::msgs::InboundOnionPayload as Readable>::read(&mut r);
29+
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
30+
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<(Option<PublicKey>, &&test_utils::TestNodeSigner)>>::read(&mut r, (None, &&node_signer));
2831
}

lightning/src/ln/channelmanager.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2736,6 +2736,7 @@ where
27362736
err_code: 0x4000 | 22,
27372737
err_data: Vec::new(),
27382738
}),
2739+
_ => todo!()
27392740
};
27402741

27412742
Ok(PendingHTLCInfo {
@@ -2762,12 +2763,13 @@ where
27622763
payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata, ..
27632764
} =>
27642765
(payment_data, keysend_preimage, custom_tlvs, amt_msat, outgoing_cltv_value, payment_metadata),
2765-
_ =>
2766+
msgs::InboundOnionPayload::Forward { .. } =>
27662767
return Err(InboundOnionErr {
27672768
err_code: 0x4000|22,
27682769
err_data: Vec::new(),
27692770
msg: "Got non final data with an HMAC of 0",
27702771
}),
2772+
_ => todo!()
27712773
};
27722774
// final_incorrect_cltv_expiry
27732775
if outgoing_cltv_value > cltv_expiry {
@@ -2907,7 +2909,10 @@ where
29072909
}
29082910
}
29092911

2910-
let next_hop = match onion_utils::decode_next_payment_hop(shared_secret, &msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac, msg.payment_hash) {
2912+
let next_hop = match onion_utils::decode_next_payment_hop(shared_secret,
2913+
&msg.onion_routing_packet.hop_data[..], msg.onion_routing_packet.hmac, msg.payment_hash,
2914+
msg.blinding_point, &self.node_signer)
2915+
{
29112916
Ok(res) => res,
29122917
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
29132918
return_malformed_err!(err_msg, err_code);
@@ -2931,7 +2936,8 @@ where
29312936
onion_utils::Hop::Receive { .. } => return Ok((next_hop, shared_secret, None)),
29322937
onion_utils::Hop::Forward { next_hop_data: msgs::InboundOnionPayload::Receive { .. }, .. } => {
29332938
return_err!("Final Node OnionHopData provided for us as an intermediary node", 0x4000 | 22, &[0; 0]);
2934-
}
2939+
},
2940+
_ => todo!()
29352941
};
29362942

29372943
// Perform outbound checks here instead of in [`Self::construct_pending_htlc_info`] because we
@@ -3897,7 +3903,11 @@ where
38973903
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
38983904
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
38993905
let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
3900-
let next_hop = match onion_utils::decode_next_payment_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
3906+
let next_hop = match
3907+
onion_utils::decode_next_payment_hop(phantom_shared_secret,
3908+
&onion_packet.hop_data, onion_packet.hmac, payment_hash, None,
3909+
&self.node_signer)
3910+
{
39013911
Ok(res) => res,
39023912
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
39033913
let sha256_of_onion = Sha256::hash(&onion_packet.hop_data).into_inner();

lightning/src/ln/msgs.rs

Lines changed: 119 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,24 @@ use bitcoin::{secp256k1, Witness};
3131
use bitcoin::blockdata::script::Script;
3232
use bitcoin::hash_types::{Txid, BlockHash};
3333

34+
use crate::blinded_path::payment::{BlindedPaymentTlvs, ForwardTlvs, ReceiveTlvs};
3435
use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
3536
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
3637
use crate::ln::onion_utils;
3738
use crate::onion_message;
39+
use crate::sign::{NodeSigner, Recipient};
3840

3941
use crate::prelude::*;
4042
use core::fmt;
4143
use core::fmt::Debug;
42-
use crate::io::{self, Read};
44+
use core::ops::Deref;
45+
use crate::io::{self, Cursor, Read};
4346
use crate::io_extras::read_to_end;
4447

4548
use crate::events::{MessageSendEventsProvider, OnionMessageProvider};
49+
use crate::util::chacha20poly1305rfc::ChaChaPolyReadAdapter;
4650
use crate::util::logger;
47-
use crate::util::ser::{LengthReadable, Readable, ReadableArgs, Writeable, Writer, WithoutLength, FixedLengthReader, HighZeroBytesDroppedBigSize, Hostname, TransactionU16LenLimited, BigSize};
51+
use crate::util::ser::{LengthReadable, LengthReadableArgs, Readable, ReadableArgs, Writeable, Writer, WithoutLength, FixedLengthReader, HighZeroBytesDroppedBigSize, Hostname, TransactionU16LenLimited, BigSize};
4852

4953
use crate::routing::gossip::{NodeAlias, NodeId};
5054

@@ -1420,8 +1424,10 @@ pub trait OnionMessageHandler : OnionMessageProvider {
14201424

14211425
mod fuzzy_internal_msgs {
14221426
use bitcoin::secp256k1::PublicKey;
1427+
use crate::blinded_path::payment::{PaymentConstraints, PaymentRelay};
14231428
use crate::prelude::*;
14241429
use crate::ln::{PaymentPreimage, PaymentSecret};
1430+
use crate::ln::features::BlindedHopFeatures;
14251431

14261432
// These types aren't intended to be pub, but are exposed for direct fuzzing (as we deserialize
14271433
// them from untrusted input):
@@ -1448,6 +1454,21 @@ mod fuzzy_internal_msgs {
14481454
amt_msat: u64,
14491455
outgoing_cltv_value: u32,
14501456
},
1457+
BlindedForward {
1458+
short_channel_id: u64,
1459+
payment_relay: PaymentRelay,
1460+
payment_constraints: PaymentConstraints,
1461+
features: BlindedHopFeatures,
1462+
intro_node_blinding_point: Option<PublicKey>,
1463+
},
1464+
BlindedReceive {
1465+
amt_msat: u64,
1466+
total_msat: u64,
1467+
outgoing_cltv_value: u32,
1468+
payment_secret: PaymentSecret,
1469+
payment_constraints: PaymentConstraints,
1470+
intro_node_blinding_point: Option<PublicKey>,
1471+
}
14511472
}
14521473

14531474
pub(crate) enum OutboundOnionPayload {
@@ -2035,24 +2056,33 @@ impl Writeable for OutboundOnionPayload {
20352056
}
20362057
}
20372058

2038-
impl Readable for InboundOnionPayload {
2039-
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
2040-
let mut amt = HighZeroBytesDroppedBigSize(0u64);
2041-
let mut cltv_value = HighZeroBytesDroppedBigSize(0u32);
2059+
impl<NS: Deref> ReadableArgs<(Option<PublicKey>, &NS)> for InboundOnionPayload where NS::Target: NodeSigner {
2060+
fn read<R: Read>(r: &mut R, args: (Option<PublicKey>, &NS)) -> Result<Self, DecodeError> {
2061+
// TODO if we are the intro node and hit an error here, we won't correctly return the malformed
2062+
// error atm
2063+
let (update_add_blinding_point, node_signer) = args;
2064+
let mut amt = None;
2065+
let mut cltv_value = None;
20422066
let mut short_id: Option<u64> = None;
20432067
let mut payment_data: Option<FinalOnionHopData> = None;
2068+
let mut encrypted_tlvs_opt: Option<WithoutLength<Vec<u8>>> = None;
2069+
let mut intro_node_blinding_point = None;
20442070
let mut payment_metadata: Option<WithoutLength<Vec<u8>>> = None;
2071+
let mut total_msat = None;
20452072
let mut keysend_preimage: Option<PaymentPreimage> = None;
20462073
let mut custom_tlvs = Vec::new();
20472074

20482075
let tlv_len = BigSize::read(r)?;
20492076
let rd = FixedLengthReader::new(r, tlv_len.0);
20502077
decode_tlv_stream_with_custom_tlv_decode!(rd, {
2051-
(2, amt, required),
2052-
(4, cltv_value, required),
2078+
(2, amt, (option, encoding: (u64, HighZeroBytesDroppedBigSize))),
2079+
(4, cltv_value, (option, encoding: (u32, HighZeroBytesDroppedBigSize))),
20532080
(6, short_id, option),
20542081
(8, payment_data, option),
2082+
(10, encrypted_tlvs_opt, option),
2083+
(12, intro_node_blinding_point, option),
20552084
(16, payment_metadata, option),
2085+
(18, total_msat, (option, encoding: (u64, HighZeroBytesDroppedBigSize))),
20562086
// See https://github.com/lightning/blips/blob/master/blip-0003.md
20572087
(5482373484, keysend_preimage, option)
20582088
}, |msg_type: u64, msg_reader: &mut FixedLengthReader<_>| -> Result<bool, DecodeError> {
@@ -2063,41 +2093,82 @@ impl Readable for InboundOnionPayload {
20632093
Ok(true)
20642094
});
20652095

2066-
if amt.0 > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
2067-
if let Some(short_channel_id) = short_id {
2068-
if payment_data.is_some() { return Err(DecodeError::InvalidValue) }
2069-
if payment_metadata.is_some() { return Err(DecodeError::InvalidValue); }
2096+
if update_add_blinding_point.is_some() && intro_node_blinding_point.is_some() {
2097+
return Err(DecodeError::InvalidValue)
2098+
}
2099+
if amt.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
2100+
2101+
if let Some(blinding_point) = update_add_blinding_point.or(intro_node_blinding_point) {
2102+
if short_id.is_some() || payment_data.is_some() || payment_metadata.is_some() {
2103+
return Err(DecodeError::InvalidValue)
2104+
}
2105+
let enc_tlvs = encrypted_tlvs_opt.ok_or(DecodeError::InvalidValue)?.0;
2106+
let enc_tlvs_ss = node_signer.ecdh(Recipient::Node, &blinding_point, None)
2107+
.map_err(|_| DecodeError::InvalidValue)?;
2108+
let rho = onion_utils::gen_rho_from_shared_secret(&enc_tlvs_ss.secret_bytes());
2109+
let mut s = Cursor::new(&enc_tlvs);
2110+
let mut reader = FixedLengthReader::new(&mut s, enc_tlvs.len() as u64);
2111+
match ChaChaPolyReadAdapter::read(&mut reader, rho)? {
2112+
ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Forward(ForwardTlvs {
2113+
short_channel_id, payment_relay, payment_constraints, features
2114+
})} => {
2115+
if amt.is_some() || cltv_value.is_some() || total_msat.is_some() {
2116+
return Err(DecodeError::InvalidValue)
2117+
}
2118+
Ok(Self::BlindedForward {
2119+
short_channel_id,
2120+
payment_relay,
2121+
payment_constraints,
2122+
features,
2123+
intro_node_blinding_point,
2124+
})
2125+
},
2126+
ChaChaPolyReadAdapter { readable: BlindedPaymentTlvs::Receive(ReceiveTlvs {
2127+
payment_secret, payment_constraints
2128+
})} => {
2129+
if total_msat.unwrap_or(0) > MAX_VALUE_MSAT { return Err(DecodeError::InvalidValue) }
2130+
Ok(Self::BlindedReceive {
2131+
amt_msat: amt.ok_or(DecodeError::InvalidValue)?,
2132+
total_msat: total_msat.ok_or(DecodeError::InvalidValue)?,
2133+
outgoing_cltv_value: cltv_value.ok_or(DecodeError::InvalidValue)?,
2134+
payment_secret,
2135+
payment_constraints,
2136+
intro_node_blinding_point,
2137+
})
2138+
},
2139+
}
2140+
} else if let Some(short_channel_id) = short_id {
2141+
if payment_data.is_some() || payment_metadata.is_some() || encrypted_tlvs_opt.is_some() ||
2142+
total_msat.is_some()
2143+
{
2144+
return Err(DecodeError::InvalidValue)
2145+
}
20702146
Ok(Self::Forward {
20712147
short_channel_id,
2072-
amt_to_forward: amt.0,
2073-
outgoing_cltv_value: cltv_value.0,
2148+
amt_to_forward: amt.ok_or(DecodeError::InvalidValue)?,
2149+
outgoing_cltv_value: cltv_value.ok_or(DecodeError::InvalidValue)?,
20742150
})
20752151
} else {
2152+
if encrypted_tlvs_opt.is_some() || total_msat.is_some() {
2153+
return Err(DecodeError::InvalidValue)
2154+
}
20762155
if let Some(data) = &payment_data {
20772156
if data.total_msat > MAX_VALUE_MSAT {
2078-
return Err(DecodeError::InvalidValue);
2157+
return Err(DecodeError::InvalidValue)
20792158
}
20802159
}
20812160
Ok(Self::Receive {
20822161
payment_data,
20832162
payment_metadata: payment_metadata.map(|w| w.0),
20842163
keysend_preimage,
2085-
amt_msat: amt.0,
2086-
outgoing_cltv_value: cltv_value.0,
2164+
amt_msat: amt.ok_or(DecodeError::InvalidValue)?,
2165+
outgoing_cltv_value: cltv_value.ok_or(DecodeError::InvalidValue)?,
20872166
custom_tlvs,
20882167
})
20892168
}
20902169
}
20912170
}
20922171

2093-
// ReadableArgs because we need onion_utils::decode_next_hop to accommodate payment packets and
2094-
// onion message packets.
2095-
impl ReadableArgs<()> for InboundOnionPayload {
2096-
fn read<R: Read>(r: &mut R, _arg: ()) -> Result<Self, DecodeError> {
2097-
<Self as Readable>::read(r)
2098-
}
2099-
}
2100-
21012172
impl Writeable for Ping {
21022173
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
21032174
self.ponglen.write(w)?;
@@ -2513,7 +2584,8 @@ mod tests {
25132584
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
25142585
use crate::ln::msgs::{self, FinalOnionHopData, OnionErrorPacket};
25152586
use crate::routing::gossip::{NodeAlias, NodeId};
2516-
use crate::util::ser::{Writeable, Readable, Hostname, TransactionU16LenLimited};
2587+
use crate::util::ser::{Writeable, Readable, ReadableArgs, Hostname, TransactionU16LenLimited};
2588+
use crate::util::test_utils;
25172589

25182590
use bitcoin::hashes::hex::FromHex;
25192591
use bitcoin::util::address::Address;
@@ -3604,8 +3676,11 @@ mod tests {
36043676
let target_value = hex::decode("1a02080badf00d010203040404ffffffff0608deadbeef1bad1dea").unwrap();
36053677
assert_eq!(encoded_value, target_value);
36063678

3607-
let inbound_msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
3608-
if let msgs::InboundOnionPayload::Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } = inbound_msg {
3679+
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
3680+
let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), (None, &&node_signer)).unwrap();
3681+
if let msgs::InboundOnionPayload::Forward {
3682+
short_channel_id, amt_to_forward, outgoing_cltv_value
3683+
} = inbound_msg {
36093684
assert_eq!(short_channel_id, 0xdeadbeef1bad1dea);
36103685
assert_eq!(amt_to_forward, 0x0badf00d01020304);
36113686
assert_eq!(outgoing_cltv_value, 0xffffffff);
@@ -3626,8 +3701,11 @@ mod tests {
36263701
let target_value = hex::decode("1002080badf00d010203040404ffffffff").unwrap();
36273702
assert_eq!(encoded_value, target_value);
36283703

3629-
let inbound_msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
3630-
if let msgs::InboundOnionPayload::Receive { payment_data: None, amt_msat, outgoing_cltv_value, .. } = inbound_msg {
3704+
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
3705+
let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), (None, &&node_signer)).unwrap();
3706+
if let msgs::InboundOnionPayload::Receive {
3707+
payment_data: None, amt_msat, outgoing_cltv_value, ..
3708+
} = inbound_msg {
36313709
assert_eq!(amt_msat, 0x0badf00d01020304);
36323710
assert_eq!(outgoing_cltv_value, 0xffffffff);
36333711
} else { panic!(); }
@@ -3651,7 +3729,8 @@ mod tests {
36513729
let target_value = hex::decode("3602080badf00d010203040404ffffffff082442424242424242424242424242424242424242424242424242424242424242421badca1f").unwrap();
36523730
assert_eq!(encoded_value, target_value);
36533731

3654-
let inbound_msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
3732+
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
3733+
let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), (None, &&node_signer)).unwrap();
36553734
if let msgs::InboundOnionPayload::Receive {
36563735
payment_data: Some(FinalOnionHopData {
36573736
payment_secret,
@@ -3686,7 +3765,8 @@ mod tests {
36863765
outgoing_cltv_value: 0xffffffff,
36873766
};
36883767
let encoded_value = msg.encode();
3689-
assert!(msgs::InboundOnionPayload::read(&mut Cursor::new(&encoded_value[..])).is_err());
3768+
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
3769+
assert!(msgs::InboundOnionPayload::read(&mut Cursor::new(&encoded_value[..]), (None, &&node_signer)).is_err());
36903770
let good_type_range_tlvs = vec![
36913771
((1 << 16) - 3, vec![42]),
36923772
((1 << 16) - 1, vec![42; 32]),
@@ -3695,7 +3775,7 @@ mod tests {
36953775
*custom_tlvs = good_type_range_tlvs.clone();
36963776
}
36973777
let encoded_value = msg.encode();
3698-
let inbound_msg = Readable::read(&mut Cursor::new(&encoded_value[..])).unwrap();
3778+
let inbound_msg = ReadableArgs::read(&mut Cursor::new(&encoded_value[..]), (None, &&node_signer)).unwrap();
36993779
match inbound_msg {
37003780
msgs::InboundOnionPayload::Receive { custom_tlvs, .. } => assert!(custom_tlvs.is_empty()),
37013781
_ => panic!(),
@@ -3719,7 +3799,8 @@ mod tests {
37193799
let encoded_value = msg.encode();
37203800
let target_value = hex::decode("2e02080badf00d010203040404ffffffffff0000000146c6616b021234ff0000000146c6616f084242424242424242").unwrap();
37213801
assert_eq!(encoded_value, target_value);
3722-
let inbound_msg: msgs::InboundOnionPayload = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
3802+
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
3803+
let inbound_msg: msgs::InboundOnionPayload = ReadableArgs::read(&mut Cursor::new(&target_value[..]), (None, &&node_signer)).unwrap();
37233804
if let msgs::InboundOnionPayload::Receive {
37243805
payment_data: None,
37253806
payment_metadata: None,
@@ -3882,7 +3963,10 @@ mod tests {
38823963
// payload length to be encoded over multiple bytes rather than a single u8.
38833964
let big_payload = encode_big_payload().unwrap();
38843965
let mut rd = Cursor::new(&big_payload[..]);
3885-
<msgs::InboundOnionPayload as Readable>::read(&mut rd).unwrap();
3966+
3967+
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
3968+
<msgs::InboundOnionPayload as ReadableArgs<(Option<PublicKey>, &&test_utils::TestKeysInterface)>>
3969+
::read(&mut rd, (None, &&node_signer)).unwrap();
38863970
}
38873971
// see above test, needs to be a separate method for use of the serialization macros.
38883972
fn encode_big_payload() -> Result<Vec<u8>, io::Error> {

lightning/src/ln/onion_utils.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::ln::msgs;
1313
use crate::ln::wire::Encode;
1414
use crate::routing::gossip::NetworkUpdate;
1515
use crate::routing::router::{BlindedTail, Path, RouteHop};
16+
use crate::sign::NodeSigner;
1617
use crate::util::chacha20::{ChaCha20, ChaChaReader};
1718
use crate::util::errors::{self, APIError};
1819
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, LengthCalculatingWriter};
@@ -883,8 +884,11 @@ pub(crate) enum OnionDecodeErr {
883884
},
884885
}
885886

886-
pub(crate) fn decode_next_payment_hop(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: PaymentHash) -> Result<Hop, OnionDecodeErr> {
887-
match decode_next_hop(shared_secret, hop_data, hmac_bytes, Some(payment_hash), ()) {
887+
pub(crate) fn decode_next_payment_hop<NS: Deref>(
888+
shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: PaymentHash,
889+
blinding_point: Option<PublicKey>, node_signer: &NS,
890+
) -> Result<Hop, OnionDecodeErr> where NS::Target: NodeSigner {
891+
match decode_next_hop(shared_secret, hop_data, hmac_bytes, Some(payment_hash), (blinding_point, node_signer)) {
888892
Ok((next_hop_data, None)) => Ok(Hop::Receive(next_hop_data)),
889893
Ok((next_hop_data, Some((next_hop_hmac, FixedSizeOnionPacket(new_packet_bytes))))) => {
890894
Ok(Hop::Forward {

0 commit comments

Comments
 (0)