Skip to content

Commit 6957fb6

Browse files
authored
Merge pull request #1809 from valentinewallace/2022-10-custom-om-self
Give us a self when reading a custom onion message
2 parents 4ec4e89 + 150c87a commit 6957fb6

File tree

7 files changed

+44
-89
lines changed

7 files changed

+44
-89
lines changed

fuzz/src/onion_message.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
1010
use lightning::ln::script::ShutdownScript;
1111
use lightning::util::enforcing_trait_impls::EnforcingSigner;
1212
use lightning::util::logger::Logger;
13-
use lightning::util::ser::{MaybeReadableArgs, Readable, Writeable, Writer};
13+
use lightning::util::ser::{Readable, Writeable, Writer};
1414
use lightning::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OnionMessenger};
1515

1616
use crate::utils::test_logger;
@@ -67,19 +67,16 @@ impl Writeable for TestCustomMessage {
6767
}
6868
}
6969

70-
impl MaybeReadableArgs<u64> for TestCustomMessage {
71-
fn read<R: io::Read>(buffer: &mut R, _message_type: u64,) -> Result<Option<Self>, DecodeError> where Self: Sized {
72-
let mut buf = Vec::new();
73-
buffer.read_to_end(&mut buf)?;
74-
return Ok(Some(TestCustomMessage {}))
75-
}
76-
}
77-
7870
struct TestCustomMessageHandler {}
7971

8072
impl CustomOnionMessageHandler for TestCustomMessageHandler {
8173
type CustomMessage = TestCustomMessage;
8274
fn handle_custom_message(&self, _msg: Self::CustomMessage) {}
75+
fn read_custom_message<R: io::Read>(&self, _message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError> {
76+
let mut buf = Vec::new();
77+
buffer.read_to_end(&mut buf)?;
78+
return Ok(Some(TestCustomMessage {}))
79+
}
8380
}
8481

8582
pub struct VecWriter(pub Vec<u8>);

lightning/src/ln/onion_utils.rs

+9-30
Original file line numberDiff line numberDiff line change
@@ -589,31 +589,6 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
589589
} else { unreachable!(); }
590590
}
591591

592-
/// An input used when decoding an onion packet.
593-
pub(crate) trait DecodeInput {
594-
type Arg;
595-
/// If Some, this is the input when checking the hmac of the onion packet.
596-
fn payment_hash(&self) -> Option<&PaymentHash>;
597-
/// Read argument when decrypting our hop payload.
598-
fn read_arg(self) -> Self::Arg;
599-
}
600-
601-
impl DecodeInput for PaymentHash {
602-
type Arg = ();
603-
fn payment_hash(&self) -> Option<&PaymentHash> {
604-
Some(self)
605-
}
606-
fn read_arg(self) -> Self::Arg { () }
607-
}
608-
609-
impl DecodeInput for SharedSecret {
610-
type Arg = SharedSecret;
611-
fn payment_hash(&self) -> Option<&PaymentHash> {
612-
None
613-
}
614-
fn read_arg(self) -> Self::Arg { self }
615-
}
616-
617592
/// Allows `decode_next_hop` to return the next hop packet bytes for either payments or onion
618593
/// message forwards.
619594
pub(crate) trait NextPacketBytes: AsMut<[u8]> {
@@ -664,7 +639,7 @@ pub(crate) enum OnionDecodeErr {
664639
}
665640

666641
pub(crate) fn decode_next_payment_hop(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: PaymentHash) -> Result<Hop, OnionDecodeErr> {
667-
match decode_next_hop(shared_secret, hop_data, hmac_bytes, payment_hash) {
642+
match decode_next_hop(shared_secret, hop_data, hmac_bytes, Some(payment_hash), ()) {
668643
Ok((next_hop_data, None)) => Ok(Hop::Receive(next_hop_data)),
669644
Ok((next_hop_data, Some((next_hop_hmac, FixedSizeOnionPacket(new_packet_bytes))))) => {
670645
Ok(Hop::Forward {
@@ -677,12 +652,16 @@ pub(crate) fn decode_next_payment_hop(shared_secret: [u8; 32], hop_data: &[u8],
677652
}
678653
}
679654

680-
pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], decode_input: D) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> {
655+
pub(crate) fn decode_next_untagged_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], read_args: T) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> {
656+
decode_next_hop(shared_secret, hop_data, hmac_bytes, None, read_args)
657+
}
658+
659+
fn decode_next_hop<T, R: ReadableArgs<T>, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], payment_hash: Option<PaymentHash>, read_args: T) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> {
681660
let (rho, mu) = gen_rho_mu_from_shared_secret(&shared_secret);
682661
let mut hmac = HmacEngine::<Sha256>::new(&mu);
683662
hmac.input(hop_data);
684-
if let Some(payment_hash) = decode_input.payment_hash() {
685-
hmac.input(&payment_hash.0[..]);
663+
if let Some(tag) = payment_hash {
664+
hmac.input(&tag.0[..]);
686665
}
687666
if !fixed_time_eq(&Hmac::from_engine(hmac).into_inner(), &hmac_bytes) {
688667
return Err(OnionDecodeErr::Malformed {
@@ -693,7 +672,7 @@ pub(crate) fn decode_next_hop<D: DecodeInput, R: ReadableArgs<D::Arg>, N: NextPa
693672

694673
let mut chacha = ChaCha20::new(&rho, &[0u8; 8]);
695674
let mut chacha_stream = ChaChaReader { chacha: &mut chacha, read: Cursor::new(&hop_data[..]) };
696-
match R::read(&mut chacha_stream, decode_input.read_arg()) {
675+
match R::read(&mut chacha_stream, read_args) {
697676
Err(err) => {
698677
let error_code = match err {
699678
msgs::DecodeError::UnknownVersion => 0x4000 | 1, // unknown realm byte

lightning/src/ln/peer_handler.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::ln::features::{InitFeatures, NodeFeatures};
2121
use crate::ln::msgs;
2222
use crate::ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, OnionMessageHandler, RoutingMessageHandler};
2323
use crate::ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager};
24-
use crate::util::ser::{MaybeReadableArgs, VecWriter, Writeable, Writer};
24+
use crate::util::ser::{VecWriter, Writeable, Writer};
2525
use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
2626
use crate::ln::wire;
2727
use crate::ln::wire::Encode;
@@ -97,13 +97,11 @@ impl OnionMessageHandler for IgnoringMessageHandler {
9797
}
9898
impl CustomOnionMessageHandler for IgnoringMessageHandler {
9999
type CustomMessage = Infallible;
100-
fn handle_custom_message(&self, _msg: Self::CustomMessage) {
100+
fn handle_custom_message(&self, _msg: Infallible) {
101101
// Since we always return `None` in the read the handle method should never be called.
102102
unreachable!();
103103
}
104-
}
105-
impl MaybeReadableArgs<u64> for Infallible {
106-
fn read<R: io::Read>(_buffer: &mut R, _msg_type: u64) -> Result<Option<Self>, msgs::DecodeError> where Self: Sized {
104+
fn read_custom_message<R: io::Read>(&self, _msg_type: u64, _buffer: &mut R) -> Result<Option<Infallible>, msgs::DecodeError> where Self: Sized {
107105
Ok(None)
108106
}
109107
}

lightning/src/onion_message/functional_tests.rs

+7-16
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use crate::ln::features::InitFeatures;
1414
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
1515
use super::{BlindedRoute, CustomOnionMessageContents, CustomOnionMessageHandler, Destination, OnionMessageContents, OnionMessenger, SendError};
1616
use crate::util::enforcing_trait_impls::EnforcingSigner;
17-
use crate::util::ser::{MaybeReadableArgs, Writeable, Writer};
17+
use crate::util::ser::{ Writeable, Writer};
1818
use crate::util::test_utils;
1919

2020
use bitcoin::network::constants::Network;
@@ -54,8 +54,12 @@ impl Writeable for TestCustomMessage {
5454
}
5555
}
5656

57-
impl MaybeReadableArgs<u64> for TestCustomMessage {
58-
fn read<R: io::Read>(buffer: &mut R, message_type: u64) -> Result<Option<Self>, DecodeError> where Self: Sized {
57+
struct TestCustomMessageHandler {}
58+
59+
impl CustomOnionMessageHandler for TestCustomMessageHandler {
60+
type CustomMessage = TestCustomMessage;
61+
fn handle_custom_message(&self, _msg: Self::CustomMessage) {}
62+
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, DecodeError> where Self: Sized {
5963
if message_type == CUSTOM_MESSAGE_TYPE {
6064
let mut buf = Vec::new();
6165
buffer.read_to_end(&mut buf)?;
@@ -66,13 +70,6 @@ impl MaybeReadableArgs<u64> for TestCustomMessage {
6670
}
6771
}
6872

69-
struct TestCustomMessageHandler {}
70-
71-
impl CustomOnionMessageHandler for TestCustomMessageHandler {
72-
type CustomMessage = TestCustomMessage;
73-
fn handle_custom_message(&self, _msg: Self::CustomMessage) {}
74-
}
75-
7673
fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
7774
let mut nodes = Vec::new();
7875
for i in 0..num_messengers {
@@ -233,12 +230,6 @@ fn invalid_custom_message_type() {
233230
fn write<W: Writer>(&self, _w: &mut W) -> Result<(), io::Error> { unreachable!() }
234231
}
235232

236-
impl MaybeReadableArgs<u64> for InvalidCustomMessage {
237-
fn read<R: io::Read>(_buffer: &mut R, _message_type: u64) -> Result<Option<Self>, DecodeError> where Self: Sized {
238-
unreachable!()
239-
}
240-
}
241-
242233
let test_msg = OnionMessageContents::Custom(InvalidCustomMessage {});
243234
let err = nodes[0].messenger.send_onion_message(&[], Destination::Node(nodes[1].get_node_pk()), test_msg, None).unwrap_err();
244235
assert_eq!(err, SendError::InvalidMessage);

lightning/src/onion_message/messenger.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use crate::util::logger::Logger;
2929
use crate::util::ser::Writeable;
3030

3131
use core::ops::Deref;
32+
use crate::io;
3233
use crate::sync::{Arc, Mutex};
3334
use crate::prelude::*;
3435

@@ -47,7 +48,7 @@ use crate::prelude::*;
4748
/// # use lightning::ln::peer_handler::IgnoringMessageHandler;
4849
/// # use lightning::onion_message::{BlindedRoute, CustomOnionMessageContents, Destination, OnionMessageContents, OnionMessenger};
4950
/// # use lightning::util::logger::{Logger, Record};
50-
/// # use lightning::util::ser::{MaybeReadableArgs, Writeable, Writer};
51+
/// # use lightning::util::ser::{Writeable, Writer};
5152
/// # use lightning::io;
5253
/// # use std::sync::Arc;
5354
/// # struct FakeLogger {};
@@ -81,13 +82,6 @@ use crate::prelude::*;
8182
/// your_custom_message_type
8283
/// }
8384
/// }
84-
/// impl MaybeReadableArgs<u64> for YourCustomMessage {
85-
/// fn read<R: io::Read>(r: &mut R, message_type: u64) -> Result<Option<Self>, DecodeError> {
86-
/// # unreachable!()
87-
/// // Read your custom onion message of type `message_type` from `r`, or return `None`
88-
/// // if the message type is unknown
89-
/// }
90-
/// }
9185
/// // Send a custom onion message to a node id.
9286
/// let intermediate_hops = [hop_node_id1, hop_node_id2];
9387
/// let reply_path = None;
@@ -178,6 +172,9 @@ pub trait CustomOnionMessageHandler {
178172
type CustomMessage: CustomOnionMessageContents;
179173
/// Called with the custom message that was received.
180174
fn handle_custom_message(&self, msg: Self::CustomMessage);
175+
/// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
176+
/// message type is unknown.
177+
fn read_custom_message<R: io::Read>(&self, message_type: u64, buffer: &mut R) -> Result<Option<Self::CustomMessage>, msgs::DecodeError>;
181178
}
182179

183180
impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessenger<Signer, K, L, CMH>
@@ -279,7 +276,7 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, Ve
279276
impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessageHandler for OnionMessenger<Signer, K, L, CMH>
280277
where K::Target: KeysInterface<Signer = Signer>,
281278
L::Target: Logger,
282-
CMH::Target: CustomOnionMessageHandler,
279+
CMH::Target: CustomOnionMessageHandler + Sized,
283280
{
284281
/// Handle an incoming onion message. Currently, if a message was destined for us we will log, but
285282
/// soon we'll delegate the onion message to a handler that can generate invoices or send
@@ -308,8 +305,8 @@ impl<Signer: Sign, K: Deref, L: Deref, CMH: Deref> OnionMessageHandler for Onion
308305
}
309306
}
310307
};
311-
match onion_utils::decode_next_hop(onion_decode_ss, &msg.onion_routing_packet.hop_data[..],
312-
msg.onion_routing_packet.hmac, control_tlvs_ss)
308+
match onion_utils::decode_next_untagged_hop(onion_decode_ss, &msg.onion_routing_packet.hop_data[..],
309+
msg.onion_routing_packet.hmac, (control_tlvs_ss, &*self.custom_handler))
313310
{
314311
Ok((Payload::Receive::<<<CMH as Deref>::Target as CustomOnionMessageHandler>::CustomMessage> {
315312
message, control_tlvs: ReceiveControlTlvs::Unblinded(ReceiveTlvs { path_id }), reply_path,

lightning/src/onion_message/packet.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ use bitcoin::secp256k1::ecdh::SharedSecret;
1515
use crate::ln::msgs::DecodeError;
1616
use crate::ln::onion_utils;
1717
use super::blinded_route::{BlindedRoute, ForwardTlvs, ReceiveTlvs};
18+
use super::messenger::CustomOnionMessageHandler;
1819
use crate::util::chacha20poly1305rfc::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter};
19-
use crate::util::ser::{BigSize, FixedLengthReader, LengthRead, LengthReadable, LengthReadableArgs, MaybeReadableArgs, Readable, ReadableArgs, Writeable, Writer};
20+
use crate::util::ser::{BigSize, FixedLengthReader, LengthRead, LengthReadable, LengthReadableArgs, Readable, ReadableArgs, Writeable, Writer};
2021

2122
use core::cmp;
2223
use crate::io::{self, Read};
@@ -106,7 +107,7 @@ pub(super) enum Payload<T: CustomOnionMessageContents> {
106107
#[derive(Debug)]
107108
/// The contents of an onion message. In the context of offers, this would be the invoice, invoice
108109
/// request, or invoice error.
109-
pub enum OnionMessageContents<T> where T: CustomOnionMessageContents {
110+
pub enum OnionMessageContents<T: CustomOnionMessageContents> {
110111
// Coming soon:
111112
// Invoice,
112113
// InvoiceRequest,
@@ -115,7 +116,7 @@ pub enum OnionMessageContents<T> where T: CustomOnionMessageContents {
115116
Custom(T),
116117
}
117118

118-
impl<T> OnionMessageContents<T> where T: CustomOnionMessageContents {
119+
impl<T: CustomOnionMessageContents> OnionMessageContents<T> {
119120
/// Returns the type that was used to decode the message payload.
120121
pub fn tlv_type(&self) -> u64 {
121122
match self {
@@ -132,9 +133,8 @@ impl<T: CustomOnionMessageContents> Writeable for OnionMessageContents<T> {
132133
}
133134
}
134135

135-
/// The contents of a custom onion message. Must implement `MaybeReadableArgs<u64>` where the `u64`
136-
/// is the custom TLV type attempting to be read, and return `Ok(None)` if the TLV type is unknown.
137-
pub trait CustomOnionMessageContents: Writeable + MaybeReadableArgs<u64> {
136+
/// The contents of a custom onion message.
137+
pub trait CustomOnionMessageContents: Writeable {
138138
/// Returns the TLV type identifying the message contents. MUST be >= 64.
139139
fn tlv_type(&self) -> u64;
140140
}
@@ -198,8 +198,10 @@ impl<T: CustomOnionMessageContents> Writeable for (Payload<T>, [u8; 32]) {
198198
}
199199

200200
// Uses the provided secret to simultaneously decode and decrypt the control TLVs and data TLV.
201-
impl<T: CustomOnionMessageContents> ReadableArgs<SharedSecret> for Payload<T> {
202-
fn read<R: Read>(r: &mut R, encrypted_tlvs_ss: SharedSecret) -> Result<Self, DecodeError> {
201+
impl<H: CustomOnionMessageHandler> ReadableArgs<(SharedSecret, &H)> for Payload<<H as CustomOnionMessageHandler>::CustomMessage> {
202+
fn read<R: Read>(r: &mut R, args: (SharedSecret, &H)) -> Result<Self, DecodeError> {
203+
let (encrypted_tlvs_ss, handler) = args;
204+
203205
let v: BigSize = Readable::read(r)?;
204206
let mut rd = FixedLengthReader::new(r, v.0);
205207
let mut reply_path: Option<BlindedRoute> = None;
@@ -216,7 +218,7 @@ impl<T: CustomOnionMessageContents> ReadableArgs<SharedSecret> for Payload<T> {
216218
if message_type.is_some() { return Err(DecodeError::InvalidValue) }
217219

218220
message_type = Some(msg_type);
219-
match T::read(msg_reader, msg_type) {
221+
match handler.read_custom_message(msg_type, msg_reader) {
220222
Ok(Some(msg)) => {
221223
message = Some(msg);
222224
Ok(true)

lightning/src/util/ser.rs

-9
Original file line numberDiff line numberDiff line change
@@ -269,15 +269,6 @@ impl<T: Readable> MaybeReadable for T {
269269
}
270270
}
271271

272-
/// A trait that various rust-lightning types implement allowing them to (maybe) be read in from a
273-
/// Read, given some additional set of arguments which is required to deserialize.
274-
///
275-
/// (C-not exported) as we only export serialization to/from byte arrays instead
276-
pub trait MaybeReadableArgs<P> {
277-
/// Reads a Self in from the given Read
278-
fn read<R: Read>(reader: &mut R, params: P) -> Result<Option<Self>, DecodeError> where Self: Sized;
279-
}
280-
281272
pub(crate) struct OptionDeserWrapper<T: Readable>(pub Option<T>);
282273
impl<T: Readable> Readable for OptionDeserWrapper<T> {
283274
#[inline]

0 commit comments

Comments
 (0)