mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-01-19 05:43:55 +01:00
Parameterize InboundPayload reads with NodeSigner
This will be used in the next commit to deserialize encrypted TLVs for receiving to 1-hop blinded paths.
This commit is contained in:
parent
7b1e09134a
commit
154841b234
@ -11,18 +11,21 @@
|
||||
// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
|
||||
|
||||
use crate::utils::test_logger;
|
||||
use lightning::util::test_utils;
|
||||
|
||||
#[inline]
|
||||
pub fn onion_hop_data_test<Out: test_logger::Output>(data: &[u8], _out: Out) {
|
||||
use lightning::util::ser::Readable;
|
||||
use lightning::util::ser::ReadableArgs;
|
||||
let mut r = ::std::io::Cursor::new(data);
|
||||
let _ = <lightning::ln::msgs::InboundOnionPayload as Readable>::read(&mut r);
|
||||
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
|
||||
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<&&test_utils::TestNodeSigner>>::read(&mut r, &&node_signer);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn onion_hop_data_run(data: *const u8, datalen: usize) {
|
||||
use lightning::util::ser::Readable;
|
||||
use lightning::util::ser::ReadableArgs;
|
||||
let data = unsafe { std::slice::from_raw_parts(data, datalen) };
|
||||
let mut r = ::std::io::Cursor::new(data);
|
||||
let _ = <lightning::ln::msgs::InboundOnionPayload as Readable>::read(&mut r);
|
||||
let node_signer = test_utils::TestNodeSigner::new(test_utils::privkey(42));
|
||||
let _ = <lightning::ln::msgs::InboundOnionPayload as ReadableArgs<&&test_utils::TestNodeSigner>>::read(&mut r, &&node_signer);
|
||||
}
|
||||
|
@ -2915,7 +2915,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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, &self.node_signer
|
||||
) {
|
||||
Ok(res) => res,
|
||||
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
|
||||
return_malformed_err!(err_msg, err_code);
|
||||
@ -3924,7 +3927,10 @@ where
|
||||
let phantom_pubkey_res = self.node_signer.get_node_id(Recipient::PhantomNode);
|
||||
if phantom_pubkey_res.is_ok() && fake_scid::is_valid_phantom(&self.fake_scid_rand_bytes, short_chan_id, &self.genesis_hash) {
|
||||
let phantom_shared_secret = self.node_signer.ecdh(Recipient::PhantomNode, &onion_packet.public_key.unwrap(), None).unwrap().secret_bytes();
|
||||
let next_hop = match onion_utils::decode_next_payment_hop(phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac, payment_hash) {
|
||||
let next_hop = match onion_utils::decode_next_payment_hop(
|
||||
phantom_shared_secret, &onion_packet.hop_data, onion_packet.hmac,
|
||||
payment_hash, &self.node_signer
|
||||
) {
|
||||
Ok(res) => res,
|
||||
Err(onion_utils::OnionDecodeErr::Malformed { err_msg, err_code }) => {
|
||||
let sha256_of_onion = Sha256::hash(&onion_packet.hop_data).into_inner();
|
||||
|
@ -35,11 +35,13 @@ use crate::ln::{ChannelId, PaymentPreimage, PaymentHash, PaymentSecret};
|
||||
use crate::ln::features::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, NodeFeatures};
|
||||
use crate::ln::onion_utils;
|
||||
use crate::onion_message;
|
||||
use crate::sign::NodeSigner;
|
||||
|
||||
use crate::prelude::*;
|
||||
use core::convert::TryFrom;
|
||||
use core::fmt;
|
||||
use core::fmt::Debug;
|
||||
use core::ops::Deref;
|
||||
use core::str::FromStr;
|
||||
use crate::io::{self, Read};
|
||||
use crate::io_extras::read_to_end;
|
||||
@ -2132,8 +2134,8 @@ impl Writeable for OutboundOnionPayload {
|
||||
}
|
||||
}
|
||||
|
||||
impl Readable for InboundOnionPayload {
|
||||
fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
|
||||
impl<NS: Deref> ReadableArgs<&NS> for InboundOnionPayload where NS::Target: NodeSigner {
|
||||
fn read<R: Read>(r: &mut R, node_signer: &NS) -> Result<Self, DecodeError> {
|
||||
let mut amt = HighZeroBytesDroppedBigSize(0u64);
|
||||
let mut cltv_value = HighZeroBytesDroppedBigSize(0u32);
|
||||
let mut short_id: Option<u64> = None;
|
||||
@ -2187,14 +2189,6 @@ impl Readable for InboundOnionPayload {
|
||||
}
|
||||
}
|
||||
|
||||
// ReadableArgs because we need onion_utils::decode_next_hop to accommodate payment packets and
|
||||
// onion message packets.
|
||||
impl ReadableArgs<()> for InboundOnionPayload {
|
||||
fn read<R: Read>(r: &mut R, _arg: ()) -> Result<Self, DecodeError> {
|
||||
<Self as Readable>::read(r)
|
||||
}
|
||||
}
|
||||
|
||||
impl Writeable for Ping {
|
||||
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
|
||||
self.ponglen.write(w)?;
|
||||
@ -2612,7 +2606,8 @@ mod tests {
|
||||
use crate::ln::msgs::{self, FinalOnionHopData, OnionErrorPacket};
|
||||
use crate::ln::msgs::SocketAddress;
|
||||
use crate::routing::gossip::{NodeAlias, NodeId};
|
||||
use crate::util::ser::{Writeable, Readable, Hostname, TransactionU16LenLimited};
|
||||
use crate::util::ser::{Writeable, Readable, ReadableArgs, Hostname, TransactionU16LenLimited};
|
||||
use crate::util::test_utils;
|
||||
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::util::address::Address;
|
||||
@ -3704,8 +3699,11 @@ mod tests {
|
||||
let target_value = hex::decode("1a02080badf00d010203040404ffffffff0608deadbeef1bad1dea").unwrap();
|
||||
assert_eq!(encoded_value, target_value);
|
||||
|
||||
let inbound_msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
|
||||
if let msgs::InboundOnionPayload::Forward { short_channel_id, amt_to_forward, outgoing_cltv_value } = inbound_msg {
|
||||
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
|
||||
let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
|
||||
if let msgs::InboundOnionPayload::Forward {
|
||||
short_channel_id, amt_to_forward, outgoing_cltv_value
|
||||
} = inbound_msg {
|
||||
assert_eq!(short_channel_id, 0xdeadbeef1bad1dea);
|
||||
assert_eq!(amt_to_forward, 0x0badf00d01020304);
|
||||
assert_eq!(outgoing_cltv_value, 0xffffffff);
|
||||
@ -3726,8 +3724,11 @@ mod tests {
|
||||
let target_value = hex::decode("1002080badf00d010203040404ffffffff").unwrap();
|
||||
assert_eq!(encoded_value, target_value);
|
||||
|
||||
let inbound_msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
|
||||
if let msgs::InboundOnionPayload::Receive { payment_data: None, amt_msat, outgoing_cltv_value, .. } = inbound_msg {
|
||||
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
|
||||
let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
|
||||
if let msgs::InboundOnionPayload::Receive {
|
||||
payment_data: None, amt_msat, outgoing_cltv_value, ..
|
||||
} = inbound_msg {
|
||||
assert_eq!(amt_msat, 0x0badf00d01020304);
|
||||
assert_eq!(outgoing_cltv_value, 0xffffffff);
|
||||
} else { panic!(); }
|
||||
@ -3751,7 +3752,8 @@ mod tests {
|
||||
let target_value = hex::decode("3602080badf00d010203040404ffffffff082442424242424242424242424242424242424242424242424242424242424242421badca1f").unwrap();
|
||||
assert_eq!(encoded_value, target_value);
|
||||
|
||||
let inbound_msg = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
|
||||
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
|
||||
let inbound_msg = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
|
||||
if let msgs::InboundOnionPayload::Receive {
|
||||
payment_data: Some(FinalOnionHopData {
|
||||
payment_secret,
|
||||
@ -3786,7 +3788,8 @@ mod tests {
|
||||
outgoing_cltv_value: 0xffffffff,
|
||||
};
|
||||
let encoded_value = msg.encode();
|
||||
assert!(msgs::InboundOnionPayload::read(&mut Cursor::new(&encoded_value[..])).is_err());
|
||||
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
|
||||
assert!(msgs::InboundOnionPayload::read(&mut Cursor::new(&encoded_value[..]), &&node_signer).is_err());
|
||||
let good_type_range_tlvs = vec![
|
||||
((1 << 16) - 3, vec![42]),
|
||||
((1 << 16) - 1, vec![42; 32]),
|
||||
@ -3795,7 +3798,7 @@ mod tests {
|
||||
*custom_tlvs = good_type_range_tlvs.clone();
|
||||
}
|
||||
let encoded_value = msg.encode();
|
||||
let inbound_msg = Readable::read(&mut Cursor::new(&encoded_value[..])).unwrap();
|
||||
let inbound_msg = ReadableArgs::read(&mut Cursor::new(&encoded_value[..]), &&node_signer).unwrap();
|
||||
match inbound_msg {
|
||||
msgs::InboundOnionPayload::Receive { custom_tlvs, .. } => assert!(custom_tlvs.is_empty()),
|
||||
_ => panic!(),
|
||||
@ -3819,7 +3822,8 @@ mod tests {
|
||||
let encoded_value = msg.encode();
|
||||
let target_value = hex::decode("2e02080badf00d010203040404ffffffffff0000000146c6616b021234ff0000000146c6616f084242424242424242").unwrap();
|
||||
assert_eq!(encoded_value, target_value);
|
||||
let inbound_msg: msgs::InboundOnionPayload = Readable::read(&mut Cursor::new(&target_value[..])).unwrap();
|
||||
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
|
||||
let inbound_msg: msgs::InboundOnionPayload = ReadableArgs::read(&mut Cursor::new(&target_value[..]), &&node_signer).unwrap();
|
||||
if let msgs::InboundOnionPayload::Receive {
|
||||
payment_data: None,
|
||||
payment_metadata: None,
|
||||
@ -3982,7 +3986,10 @@ mod tests {
|
||||
// payload length to be encoded over multiple bytes rather than a single u8.
|
||||
let big_payload = encode_big_payload().unwrap();
|
||||
let mut rd = Cursor::new(&big_payload[..]);
|
||||
<msgs::InboundOnionPayload as Readable>::read(&mut rd).unwrap();
|
||||
|
||||
let node_signer = test_utils::TestKeysInterface::new(&[42; 32], Network::Testnet);
|
||||
<msgs::InboundOnionPayload as ReadableArgs<&&test_utils::TestKeysInterface>>
|
||||
::read(&mut rd, &&node_signer).unwrap();
|
||||
}
|
||||
// see above test, needs to be a separate method for use of the serialization macros.
|
||||
fn encode_big_payload() -> Result<Vec<u8>, io::Error> {
|
||||
|
@ -13,6 +13,7 @@ use crate::ln::msgs;
|
||||
use crate::ln::wire::Encode;
|
||||
use crate::routing::gossip::NetworkUpdate;
|
||||
use crate::routing::router::{BlindedTail, Path, RouteHop};
|
||||
use crate::sign::NodeSigner;
|
||||
use crate::util::chacha20::{ChaCha20, ChaChaReader};
|
||||
use crate::util::errors::{self, APIError};
|
||||
use crate::util::ser::{Readable, ReadableArgs, Writeable, Writer, LengthCalculatingWriter};
|
||||
@ -885,8 +886,11 @@ pub(crate) enum OnionDecodeErr {
|
||||
},
|
||||
}
|
||||
|
||||
pub(crate) fn decode_next_payment_hop(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: PaymentHash) -> Result<Hop, OnionDecodeErr> {
|
||||
match decode_next_hop(shared_secret, hop_data, hmac_bytes, Some(payment_hash), ()) {
|
||||
pub(crate) fn decode_next_payment_hop<NS: Deref>(
|
||||
shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: PaymentHash,
|
||||
node_signer: &NS,
|
||||
) -> Result<Hop, OnionDecodeErr> where NS::Target: NodeSigner {
|
||||
match decode_next_hop(shared_secret, hop_data, hmac_bytes, Some(payment_hash), node_signer) {
|
||||
Ok((next_hop_data, None)) => Ok(Hop::Receive(next_hop_data)),
|
||||
Ok((next_hop_data, Some((next_hop_hmac, FixedSizeOnionPacket(new_packet_bytes))))) => {
|
||||
Ok(Hop::Forward {
|
||||
|
Loading…
Reference in New Issue
Block a user