Skip to content

Commit 692052e

Browse files
committed
Add create_blinded_paths to MessageRouter
The MessageRouter trait is used to find an OnionMessagePath to a Destination (e.g., to a BlindedPath). Expand the interface with a create_blinded_paths method for creating such paths to a recipient. Provide a default implementation creating two-hop blinded paths where the recipient's peers serve as introduction nodes.
1 parent 8fef036 commit 692052e

File tree

3 files changed

+68
-6
lines changed

3 files changed

+68
-6
lines changed

fuzz/src/onion_message.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
// Imports that need to be added manually
22
use bitcoin::bech32::u5;
33
use bitcoin::blockdata::script::ScriptBuf;
4-
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey};
4+
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey, self};
55
use bitcoin::secp256k1::ecdh::SharedSecret;
66
use bitcoin::secp256k1::ecdsa::RecoverableSignature;
77
use bitcoin::secp256k1::schnorr;
88

9-
use lightning::sign::{Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
9+
use lightning::blinded_path::BlindedPath;
1010
use lightning::ln::features::InitFeatures;
1111
use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
1212
use lightning::ln::script::ShutdownScript;
1313
use lightning::offers::invoice::UnsignedBolt12Invoice;
1414
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
15+
use lightning::sign::{Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
1516
use lightning::util::test_channel_signer::TestChannelSigner;
1617
use lightning::util::logger::Logger;
1718
use lightning::util::ser::{Readable, Writeable, Writer};
@@ -82,6 +83,15 @@ impl MessageRouter for TestMessageRouter {
8283
first_node_addresses: None,
8384
})
8485
}
86+
87+
fn create_blinded_paths<
88+
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
89+
>(
90+
&self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES,
91+
_secp_ctx: &Secp256k1<T>
92+
) -> Result<Vec<BlindedPath>, ()> {
93+
unreachable!()
94+
}
8595
}
8696

8797
struct TestOffersMessageHandler {}

lightning/src/onion_message/functional_tests.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ use crate::blinded_path::BlindedPath;
1313
use crate::events::{Event, EventsProvider};
1414
use crate::ln::features::InitFeatures;
1515
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler, SocketAddress};
16-
use crate::sign::{NodeSigner, Recipient};
16+
use crate::sign::{EntropySource, NodeSigner, Recipient};
1717
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
1818
use crate::util::test_utils;
1919
use super::{CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessagePath, OnionMessenger, PendingOnionMessage, SendError};
2020

2121
use bitcoin::network::constants::Network;
2222
use bitcoin::hashes::hex::FromHex;
23-
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
23+
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey, self};
2424

2525
use crate::io;
2626
use crate::io_extras::read_to_end;
@@ -55,6 +55,15 @@ impl MessageRouter for TestMessageRouter {
5555
Some(vec![SocketAddress::TcpIpV4 { addr: [127, 0, 0, 1], port: 1000 }]),
5656
})
5757
}
58+
59+
fn create_blinded_paths<
60+
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
61+
>(
62+
&self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES,
63+
_secp_ctx: &Secp256k1<T>
64+
) -> Result<Vec<BlindedPath>, ()> {
65+
unreachable!()
66+
}
5867
}
5968

6069
struct TestOffersMessageHandler {}

lightning/src/onion_message/messenger.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ pub(super) const MAX_TIMER_TICKS: usize = 2;
6464
/// # extern crate bitcoin;
6565
/// # use bitcoin::hashes::_export::_core::time::Duration;
6666
/// # use bitcoin::hashes::hex::FromHex;
67-
/// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
67+
/// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey, self};
6868
/// # use lightning::blinded_path::BlindedPath;
69-
/// # use lightning::sign::KeysManager;
69+
/// # use lightning::sign::{EntropySource, KeysManager};
7070
/// # use lightning::ln::peer_handler::IgnoringMessageHandler;
7171
/// # use lightning::onion_message::{OnionMessageContents, Destination, MessageRouter, OnionMessagePath, OnionMessenger};
7272
/// # use lightning::util::logger::{Logger, Record};
@@ -90,6 +90,11 @@ pub(super) const MAX_TIMER_TICKS: usize = 2;
9090
/// # first_node_addresses: None,
9191
/// # })
9292
/// # }
93+
/// # fn create_blinded_paths<ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification>(
94+
/// # &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES, _secp_ctx: &Secp256k1<T>
95+
/// # ) -> Result<Vec<BlindedPath>, ()> {
96+
/// # unreachable!()
97+
/// # }
9398
/// # }
9499
/// # let seed = [42u8; 32];
95100
/// # let time = Duration::from_secs(123456);
@@ -270,6 +275,15 @@ pub trait MessageRouter {
270275
fn find_path(
271276
&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
272277
) -> Result<OnionMessagePath, ()>;
278+
279+
/// Creates [`BlindedPath`]s to the `recipient` node. The nodes in `peers` are assumed to be
280+
/// direct peers with the `recipient`.
281+
fn create_blinded_paths<
282+
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
283+
>(
284+
&self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
285+
secp_ctx: &Secp256k1<T>
286+
) -> Result<Vec<BlindedPath>, ()>;
273287
}
274288

275289
/// A [`MessageRouter`] that can only route to a directly connected [`Destination`].
@@ -321,6 +335,35 @@ where
321335
}
322336
}
323337
}
338+
339+
fn create_blinded_paths<
340+
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
341+
>(
342+
&self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
343+
secp_ctx: &Secp256k1<T>
344+
) -> Result<Vec<BlindedPath>, ()> {
345+
// Limit the number of blinded paths that are computed.
346+
const MAX_PATHS: usize = 3;
347+
348+
// Ensure peers have at least three channels so that it is more difficult to infer the
349+
// recipient's node_id.
350+
const MIN_PEER_CHANNELS: usize = 3;
351+
352+
let network_graph = self.network_graph.deref().read_only();
353+
peers.into_iter()
354+
// Limit to peers with announced channels
355+
.filter(|pubkey|
356+
network_graph
357+
.node(&NodeId::from_pubkey(&pubkey))
358+
.map(|info| &info.channels[..])
359+
.map(|channels| channels.len() >= MIN_PEER_CHANNELS)
360+
.unwrap_or(false)
361+
)
362+
.map(|pubkey| vec![pubkey, recipient])
363+
.map(|node_pks| BlindedPath::new_for_message(&node_pks, entropy_source, secp_ctx))
364+
.take(MAX_PATHS)
365+
.collect()
366+
}
324367
}
325368

326369
/// A path for sending an [`OnionMessage`].

0 commit comments

Comments
 (0)