From d2859f419f118964c5db70031d0fcba2ec083c88 Mon Sep 17 00:00:00 2001 From: Evan Feenstra Date: Sat, 28 Oct 2023 15:10:00 -0700 Subject: [PATCH] public onion utils, create/peel payment --- lightning/src/ln/mod.rs | 1 + lightning/src/ln/msgs.rs | 14 +++++++++----- lightning/src/ln/onion_utils.rs | 23 +++++++++++++++++++++++ lightning/src/onion_message/mod.rs | 1 + 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lightning/src/ln/mod.rs b/lightning/src/ln/mod.rs index beefd2d463b..041c196f637 100644 --- a/lightning/src/ln/mod.rs +++ b/lightning/src/ln/mod.rs @@ -39,6 +39,7 @@ pub(crate) mod onion_utils; mod outbound_payment; pub mod wire; +pub use onion_utils::create_payment_onion; // Older rustc (which we support) refuses to let us call the get_payment_preimage_hash!() macro // without the node parameter being mut. This is incorrect, and thus newer rustcs will complain // about an unnecessary mut. Thus, we silence the unused_mut warning in two test modules below. diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 6043bf35b99..fac1b68d9a3 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -1674,17 +1674,21 @@ pub use self::fuzzy_internal_msgs::*; #[cfg(not(fuzzing))] pub(crate) use self::fuzzy_internal_msgs::*; +/// Bolt04 OnionPacket including hop data for the next peer #[derive(Clone)] -pub(crate) struct OnionPacket { - pub(crate) version: u8, +pub struct OnionPacket { + /// Bolt 04 version number + pub version: u8, /// In order to ensure we always return an error on onion decode in compliance with [BOLT /// #4](https://github.com/lightning/bolts/blob/master/04-onion-routing.md), we have to /// deserialize `OnionPacket`s contained in [`UpdateAddHTLC`] messages even if the ephemeral /// public key (here) is bogus, so we hold a [`Result`] instead of a [`PublicKey`] as we'd /// like. - pub(crate) public_key: Result, - pub(crate) hop_data: [u8; 20*65], - pub(crate) hmac: [u8; 32], + pub public_key: Result, + /// 1300 bytes encrypted payload for the next hop + pub hop_data: [u8; 20*65], + /// HMAC to verify the integrity of hop_data + pub hmac: [u8; 32], } impl onion_utils::Packet for OnionPacket { diff --git a/lightning/src/ln/onion_utils.rs b/lightning/src/ln/onion_utils.rs index 9af3de07ff4..e098a541a51 100644 --- a/lightning/src/ln/onion_utils.rs +++ b/lightning/src/ln/onion_utils.rs @@ -935,6 +935,29 @@ pub(crate) fn decode_next_payment_hop( } } +/// Build a payment onion, returning the first hop msat and cltv values as well. +pub fn create_payment_onion( + secp_ctx: &Secp256k1, path: &Path, session_priv: &SecretKey, total_msat: u64, + recipient_onion: RecipientOnionFields, best_block_height: u32, payment_hash: PaymentHash, + keysend_preimage: Option, prng_seed: [u8; 32] +) -> Result<(u64, u32, msgs::OnionPacket), ()> +where + T: secp256k1::Signing +{ + let onion_keys = construct_onion_keys(&secp_ctx, &path, &session_priv).map_err(|_| ())?; + let (onion_payloads, htlc_msat, htlc_cltv) = build_onion_payloads( + &path, + total_msat, + recipient_onion, + best_block_height + 1, + &keysend_preimage, + ).map_err(|_| ())?; + let onion_packet = construct_onion_packet( + onion_payloads, onion_keys, prng_seed, &payment_hash + )?; + Ok((htlc_msat, htlc_cltv, onion_packet)) +} + pub(crate) fn decode_next_untagged_hop, N: NextPacketBytes>(shared_secret: [u8; 32], hop_data: &[u8], hmac_bytes: [u8; 32], read_args: T) -> Result<(R, Option<([u8; 32], N)>), OnionDecodeErr> { decode_next_hop(shared_secret, hop_data, hmac_bytes, None, read_args) } diff --git a/lightning/src/onion_message/mod.rs b/lightning/src/onion_message/mod.rs index ff6e0cd8e5d..d106a542fd3 100644 --- a/lightning/src/onion_message/mod.rs +++ b/lightning/src/onion_message/mod.rs @@ -28,6 +28,7 @@ mod functional_tests; // Re-export structs so they can be imported with just the `onion_message::` module prefix. pub use self::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, MessageRouter, OnionMessageContents, OnionMessagePath, OnionMessenger, PeeledOnion, PendingOnionMessage, SendError}; +pub use self::messenger::{create_onion_message, peel_onion_message}; #[cfg(not(c_bindings))] pub use self::messenger::{SimpleArcOnionMessenger, SimpleRefOnionMessenger}; pub use self::offers::{OffersMessage, OffersMessageHandler};