mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-01-19 05:43:55 +01:00
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.
This commit is contained in:
parent
ffb0d83298
commit
97049daac2
@ -1,17 +1,18 @@
|
||||
// Imports that need to be added manually
|
||||
use bitcoin::bech32::u5;
|
||||
use bitcoin::blockdata::script::ScriptBuf;
|
||||
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey};
|
||||
use bitcoin::secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey, self};
|
||||
use bitcoin::secp256k1::ecdh::SharedSecret;
|
||||
use bitcoin::secp256k1::ecdsa::RecoverableSignature;
|
||||
use bitcoin::secp256k1::schnorr;
|
||||
|
||||
use lightning::sign::{Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
|
||||
use lightning::blinded_path::BlindedPath;
|
||||
use lightning::ln::features::InitFeatures;
|
||||
use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
|
||||
use lightning::ln::script::ShutdownScript;
|
||||
use lightning::offers::invoice::UnsignedBolt12Invoice;
|
||||
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
|
||||
use lightning::sign::{Recipient, KeyMaterial, EntropySource, NodeSigner, SignerProvider};
|
||||
use lightning::util::test_channel_signer::TestChannelSigner;
|
||||
use lightning::util::logger::Logger;
|
||||
use lightning::util::ser::{Readable, Writeable, Writer};
|
||||
@ -82,6 +83,15 @@ impl MessageRouter for TestMessageRouter {
|
||||
first_node_addresses: None,
|
||||
})
|
||||
}
|
||||
|
||||
fn create_blinded_paths<
|
||||
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
|
||||
>(
|
||||
&self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES,
|
||||
_secp_ctx: &Secp256k1<T>
|
||||
) -> Result<Vec<BlindedPath>, ()> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
struct TestOffersMessageHandler {}
|
||||
|
@ -13,14 +13,14 @@ use crate::blinded_path::BlindedPath;
|
||||
use crate::events::{Event, EventsProvider};
|
||||
use crate::ln::features::InitFeatures;
|
||||
use crate::ln::msgs::{self, DecodeError, OnionMessageHandler, SocketAddress};
|
||||
use crate::sign::{NodeSigner, Recipient};
|
||||
use crate::sign::{EntropySource, NodeSigner, Recipient};
|
||||
use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
|
||||
use crate::util::test_utils;
|
||||
use super::{CustomOnionMessageHandler, Destination, MessageRouter, OffersMessage, OffersMessageHandler, OnionMessageContents, OnionMessagePath, OnionMessenger, PendingOnionMessage, SendError};
|
||||
|
||||
use bitcoin::network::constants::Network;
|
||||
use bitcoin::hashes::hex::FromHex;
|
||||
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
|
||||
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey, self};
|
||||
|
||||
use crate::io;
|
||||
use crate::io_extras::read_to_end;
|
||||
@ -55,6 +55,15 @@ impl MessageRouter for TestMessageRouter {
|
||||
Some(vec![SocketAddress::TcpIpV4 { addr: [127, 0, 0, 1], port: 1000 }]),
|
||||
})
|
||||
}
|
||||
|
||||
fn create_blinded_paths<
|
||||
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
|
||||
>(
|
||||
&self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES,
|
||||
_secp_ctx: &Secp256k1<T>
|
||||
) -> Result<Vec<BlindedPath>, ()> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
struct TestOffersMessageHandler {}
|
||||
|
@ -64,9 +64,9 @@ pub(super) const MAX_TIMER_TICKS: usize = 2;
|
||||
/// # extern crate bitcoin;
|
||||
/// # use bitcoin::hashes::_export::_core::time::Duration;
|
||||
/// # use bitcoin::hashes::hex::FromHex;
|
||||
/// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
|
||||
/// # use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey, self};
|
||||
/// # use lightning::blinded_path::BlindedPath;
|
||||
/// # use lightning::sign::KeysManager;
|
||||
/// # use lightning::sign::{EntropySource, KeysManager};
|
||||
/// # use lightning::ln::peer_handler::IgnoringMessageHandler;
|
||||
/// # use lightning::onion_message::{OnionMessageContents, Destination, MessageRouter, OnionMessagePath, OnionMessenger};
|
||||
/// # use lightning::util::logger::{Logger, Record};
|
||||
@ -90,6 +90,11 @@ pub(super) const MAX_TIMER_TICKS: usize = 2;
|
||||
/// # first_node_addresses: None,
|
||||
/// # })
|
||||
/// # }
|
||||
/// # fn create_blinded_paths<ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification>(
|
||||
/// # &self, _recipient: PublicKey, _peers: Vec<PublicKey>, _entropy_source: &ES, _secp_ctx: &Secp256k1<T>
|
||||
/// # ) -> Result<Vec<BlindedPath>, ()> {
|
||||
/// # unreachable!()
|
||||
/// # }
|
||||
/// # }
|
||||
/// # let seed = [42u8; 32];
|
||||
/// # let time = Duration::from_secs(123456);
|
||||
@ -270,6 +275,15 @@ pub trait MessageRouter {
|
||||
fn find_path(
|
||||
&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
|
||||
) -> Result<OnionMessagePath, ()>;
|
||||
|
||||
/// Creates [`BlindedPath`]s to the `recipient` node. The nodes in `peers` are assumed to be
|
||||
/// direct peers with the `recipient`.
|
||||
fn create_blinded_paths<
|
||||
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
|
||||
>(
|
||||
&self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
|
||||
secp_ctx: &Secp256k1<T>
|
||||
) -> Result<Vec<BlindedPath>, ()>;
|
||||
}
|
||||
|
||||
/// A [`MessageRouter`] that can only route to a directly connected [`Destination`].
|
||||
@ -321,6 +335,43 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_blinded_paths<
|
||||
ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
|
||||
>(
|
||||
&self, recipient: PublicKey, peers: Vec<PublicKey>, entropy_source: &ES,
|
||||
secp_ctx: &Secp256k1<T>
|
||||
) -> Result<Vec<BlindedPath>, ()> {
|
||||
// Limit the number of blinded paths that are computed.
|
||||
const MAX_PATHS: usize = 3;
|
||||
|
||||
// Ensure peers have at least three channels so that it is more difficult to infer the
|
||||
// recipient's node_id.
|
||||
const MIN_PEER_CHANNELS: usize = 3;
|
||||
|
||||
let network_graph = self.network_graph.deref().read_only();
|
||||
let paths = peers.into_iter()
|
||||
// Limit to peers with announced channels
|
||||
.filter(|pubkey|
|
||||
network_graph
|
||||
.node(&NodeId::from_pubkey(&pubkey))
|
||||
.map(|info| &info.channels[..])
|
||||
.map(|channels| channels.len() >= MIN_PEER_CHANNELS)
|
||||
.unwrap_or(false)
|
||||
)
|
||||
.map(|pubkey| vec![pubkey, recipient])
|
||||
.map(|node_pks| BlindedPath::new_for_message(&node_pks, entropy_source, secp_ctx))
|
||||
.take(MAX_PATHS)
|
||||
.collect::<Result<Vec<_>, _>>();
|
||||
|
||||
match paths {
|
||||
Ok(paths) if !paths.is_empty() => Ok(paths),
|
||||
_ => {
|
||||
BlindedPath::one_hop_for_message(recipient, entropy_source, secp_ctx)
|
||||
.map(|path| vec![path])
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A path for sending an [`OnionMessage`].
|
||||
|
Loading…
Reference in New Issue
Block a user