X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fblinded_path%2Fmessage.rs;h=1a0f63d46000401cd5ffbec7a87c1dd42bf7e786;hb=d792afb08cdc20a30786728c3bfe816dd3b59e47;hp=df7f8e7ad6128ee90b1d6048c3cdef7a5875b28c;hpb=59778dac488cff735004671cdefb3f4ac1f920fd;p=rust-lightning diff --git a/lightning/src/blinded_path/message.rs b/lightning/src/blinded_path/message.rs index df7f8e7a..1a0f63d4 100644 --- a/lightning/src/blinded_path/message.rs +++ b/lightning/src/blinded_path/message.rs @@ -1,9 +1,13 @@ +//! Data structures and methods for constructing [`BlindedPath`]s to send a message over. +//! +//! [`BlindedPath`]: crate::blinded_path::BlindedPath + use bitcoin::secp256k1::{self, PublicKey, Secp256k1, SecretKey}; #[allow(unused_imports)] use crate::prelude::*; -use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode, NodeIdLookUp}; +use crate::blinded_path::{BlindedHop, BlindedPath, IntroductionNode, NextMessageHop, NodeIdLookUp}; use crate::blinded_path::utils; use crate::io; use crate::io::Cursor; @@ -16,11 +20,22 @@ use crate::util::ser::{FixedLengthReader, LengthReadableArgs, Writeable, Writer} use core::mem; use core::ops::Deref; +/// An intermediate node, and possibly a short channel id leading to the next node. +#[derive(Clone, Debug, Hash, PartialEq, Eq)] +pub struct ForwardNode { + /// This node's pubkey. + pub node_id: PublicKey, + /// The channel between `node_id` and the next hop. If set, the constructed [`BlindedHop`]'s + /// `encrypted_payload` will use this instead of the next [`ForwardNode::node_id`] for a more + /// compact representation. + pub short_channel_id: Option, +} + /// TLVs to encode in an intermediate onion message packet's hop data. When provided in a blinded /// route, they are encoded into [`BlindedHop::encrypted_payload`]. pub(crate) struct ForwardTlvs { /// The next hop in the onion message's path. - pub(crate) next_hop: NextHop, + pub(crate) next_hop: NextMessageHop, /// Senders to a blinded path use this value to concatenate the route they find to the /// introduction node with the blinded path. pub(crate) next_blinding_override: Option, @@ -34,20 +49,11 @@ pub(crate) struct ReceiveTlvs { pub(crate) path_id: Option<[u8; 32]>, } -/// The next hop to forward the onion message along its path. -#[derive(Debug)] -pub enum NextHop { - /// The node id of the next hop. - NodeId(PublicKey), - /// The short channel id leading to the next hop. - ShortChannelId(u64), -} - impl Writeable for ForwardTlvs { fn write(&self, writer: &mut W) -> Result<(), io::Error> { let (next_node_id, short_channel_id) = match self.next_hop { - NextHop::NodeId(pubkey) => (Some(pubkey), None), - NextHop::ShortChannelId(scid) => (None, Some(scid)), + NextMessageHop::NodeId(pubkey) => (Some(pubkey), None), + NextMessageHop::ShortChannelId(scid) => (None, Some(scid)), }; // TODO: write padding encode_tlv_stream!(writer, { @@ -69,17 +75,24 @@ impl Writeable for ReceiveTlvs { } } -/// Construct blinded onion message hops for the given `unblinded_path`. +/// Construct blinded onion message hops for the given `intermediate_nodes` and `recipient_node_id`. pub(super) fn blinded_hops( - secp_ctx: &Secp256k1, unblinded_path: &[PublicKey], session_priv: &SecretKey + secp_ctx: &Secp256k1, intermediate_nodes: &[ForwardNode], recipient_node_id: PublicKey, + session_priv: &SecretKey ) -> Result, secp256k1::Error> { - let blinded_tlvs = unblinded_path.iter() + let pks = intermediate_nodes.iter().map(|node| &node.node_id) + .chain(core::iter::once(&recipient_node_id)); + let tlvs = pks.clone() .skip(1) // The first node's TLVs contains the next node's pubkey - .map(|pk| ForwardTlvs { next_hop: NextHop::NodeId(*pk), next_blinding_override: None }) - .map(|tlvs| ControlTlvs::Forward(tlvs)) + .zip(intermediate_nodes.iter().map(|node| node.short_channel_id)) + .map(|(pubkey, scid)| match scid { + Some(scid) => NextMessageHop::ShortChannelId(scid), + None => NextMessageHop::NodeId(*pubkey), + }) + .map(|next_hop| ControlTlvs::Forward(ForwardTlvs { next_hop, next_blinding_override: None })) .chain(core::iter::once(ControlTlvs::Receive(ReceiveTlvs { path_id: None }))); - utils::construct_blinded_hops(secp_ctx, unblinded_path.iter(), blinded_tlvs, session_priv) + utils::construct_blinded_hops(secp_ctx, pks, tlvs, session_priv) } // Advance the blinded onion message path by one hop, so make the second hop into the new @@ -102,8 +115,8 @@ where readable: ControlTlvs::Forward(ForwardTlvs { next_hop, next_blinding_override }) }) => { let next_node_id = match next_hop { - NextHop::NodeId(pubkey) => pubkey, - NextHop::ShortChannelId(scid) => match node_id_lookup.next_node_id(scid) { + NextMessageHop::NodeId(pubkey) => pubkey, + NextMessageHop::ShortChannelId(scid) => match node_id_lookup.next_node_id(scid) { Some(pubkey) => pubkey, None => return Err(()), },