Require any Router also implements MessageRouter

ChannelManager is parameterized by a Router in order to find routes when
sending and retrying payments. For the offers flow, it needs to be able
to construct blinded paths (e.g., in the offer and in reply paths).
Instead of adding yet another parameter to ChannelManager, require that
any Router also implements MessageRouter. Implement this for
DefaultRouter by delegating to a DefaultMessageRouter.
This commit is contained in:
Jeffrey Czyz 2023-12-07 15:53:15 -06:00
parent 97049daac2
commit bedc2c64fc
No known key found for this signature in database
GPG key ID: 3A4E08275D5E96D2
4 changed files with 91 additions and 10 deletions

View file

@ -30,6 +30,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
use bitcoin::hash_types::{BlockHash, WPubkeyHash};
use lightning::blinded_path::BlindedPath;
use lightning::chain;
use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, chainmonitor, channelmonitor, Confirm, Watch};
use lightning::chain::channelmonitor::{ChannelMonitor, MonitorEvent};
@ -46,6 +47,7 @@ use lightning::ln::script::ShutdownScript;
use lightning::ln::functional_test_utils::*;
use lightning::offers::invoice::UnsignedBolt12Invoice;
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
use lightning::onion_message::{Destination, MessageRouter, OnionMessagePath};
use lightning::util::test_channel_signer::{TestChannelSigner, EnforcementState};
use lightning::util::errors::APIError;
use lightning::util::logger::Logger;
@ -56,7 +58,7 @@ use lightning::routing::router::{InFlightHtlcs, Path, Route, RouteHop, RoutePara
use crate::utils::test_logger::{self, Output};
use crate::utils::test_persister::TestPersister;
use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1};
use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1, self};
use bitcoin::secp256k1::ecdh::SharedSecret;
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
use bitcoin::secp256k1::schnorr;
@ -101,6 +103,23 @@ impl Router for FuzzRouter {
}
}
impl MessageRouter for FuzzRouter {
fn find_path(
&self, _sender: PublicKey, _peers: Vec<PublicKey>, _destination: Destination
) -> Result<OnionMessagePath, ()> {
unreachable!()
}
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!()
}
}
pub struct TestBroadcaster {}
impl BroadcasterInterface for TestBroadcaster {
fn broadcast_transactions(&self, _txs: &[&Transaction]) { }

View file

@ -28,6 +28,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::sha256d::Hash as Sha256dHash;
use bitcoin::hash_types::{Txid, BlockHash, WPubkeyHash};
use lightning::blinded_path::BlindedPath;
use lightning::chain;
use lightning::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen};
use lightning::chain::chaininterface::{BroadcasterInterface, ConfirmationTarget, FeeEstimator};
@ -43,6 +44,7 @@ use lightning::ln::script::ShutdownScript;
use lightning::ln::functional_test_utils::*;
use lightning::offers::invoice::UnsignedBolt12Invoice;
use lightning::offers::invoice_request::UnsignedInvoiceRequest;
use lightning::onion_message::{Destination, MessageRouter, OnionMessagePath};
use lightning::routing::gossip::{P2PGossipSync, NetworkGraph};
use lightning::routing::utxo::UtxoLookup;
use lightning::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteParameters, Router};
@ -55,7 +57,7 @@ use lightning::util::ser::{ReadableArgs, Writeable};
use crate::utils::test_logger;
use crate::utils::test_persister::TestPersister;
use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1};
use bitcoin::secp256k1::{Message, PublicKey, SecretKey, Scalar, Secp256k1, self};
use bitcoin::secp256k1::ecdh::SharedSecret;
use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
use bitcoin::secp256k1::schnorr;
@ -144,6 +146,23 @@ impl Router for FuzzRouter {
}
}
impl MessageRouter for FuzzRouter {
fn find_path(
&self, _sender: PublicKey, _peers: Vec<PublicKey>, _destination: Destination
) -> Result<OnionMessagePath, ()> {
unreachable!()
}
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 TestBroadcaster {
txn_broadcasted: Mutex<Vec<Transaction>>,
}

View file

@ -9,7 +9,7 @@
//! The router finds paths within a [`NetworkGraph`] for a payment.
use bitcoin::secp256k1::PublicKey;
use bitcoin::secp256k1::{PublicKey, Secp256k1, self};
use bitcoin::hashes::Hash;
use bitcoin::hashes::sha256::Hash as Sha256;
@ -19,8 +19,10 @@ use crate::ln::channelmanager::{ChannelDetails, PaymentId};
use crate::ln::features::{Bolt11InvoiceFeatures, Bolt12InvoiceFeatures, ChannelFeatures, NodeFeatures};
use crate::ln::msgs::{DecodeError, ErrorAction, LightningError, MAX_VALUE_MSAT};
use crate::offers::invoice::{BlindedPayInfo, Bolt12Invoice};
use crate::onion_message::{DefaultMessageRouter, Destination, MessageRouter, OnionMessagePath};
use crate::routing::gossip::{DirectedChannelInfo, EffectiveCapacity, ReadOnlyNetworkGraph, NetworkGraph, NodeId, RoutingFees};
use crate::routing::scoring::{ChannelUsage, LockableScore, ScoreLookUp};
use crate::sign::EntropySource;
use crate::util::ser::{Writeable, Readable, ReadableArgs, Writer};
use crate::util::logger::{Level, Logger};
use crate::util::chacha20::ChaCha20;
@ -33,7 +35,7 @@ use core::{cmp, fmt};
use core::ops::Deref;
/// A [`Router`] implemented using [`find_route`].
pub struct DefaultRouter<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> where
pub struct DefaultRouter<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> where
L::Target: Logger,
S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>,
{
@ -41,21 +43,23 @@ pub struct DefaultRouter<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref,
logger: L,
random_seed_bytes: Mutex<[u8; 32]>,
scorer: S,
score_params: SP
score_params: SP,
message_router: DefaultMessageRouter<G, L>,
}
impl<G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> DefaultRouter<G, L, S, SP, Sc> where
impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> DefaultRouter<G, L, S, SP, Sc> where
L::Target: Logger,
S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>,
{
/// Creates a new router.
pub fn new(network_graph: G, logger: L, random_seed_bytes: [u8; 32], scorer: S, score_params: SP) -> Self {
let random_seed_bytes = Mutex::new(random_seed_bytes);
Self { network_graph, logger, random_seed_bytes, scorer, score_params }
let message_router = DefaultMessageRouter::new(network_graph.clone());
Self { network_graph, logger, random_seed_bytes, scorer, score_params, message_router }
}
}
impl< G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> Router for DefaultRouter<G, L, S, SP, Sc> where
impl<G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> Router for DefaultRouter<G, L, S, SP, Sc> where
L::Target: Logger,
S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>,
{
@ -80,8 +84,28 @@ impl< G: Deref<Target = NetworkGraph<L>>, L: Deref, S: Deref, SP: Sized, Sc: Sco
}
}
impl< G: Deref<Target = NetworkGraph<L>> + Clone, L: Deref, S: Deref, SP: Sized, Sc: ScoreLookUp<ScoreParams = SP>> MessageRouter for DefaultRouter<G, L, S, SP, Sc> where
L::Target: Logger,
S::Target: for <'a> LockableScore<'a, ScoreLookUp = Sc>,
{
fn find_path(
&self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
) -> Result<OnionMessagePath, ()> {
self.message_router.find_path(sender, peers, destination)
}
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>, ()> {
self.message_router.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
}
}
/// A trait defining behavior for routing a payment.
pub trait Router {
pub trait Router: MessageRouter {
/// Finds a [`Route`] for a payment between the given `payer` and a payee.
///
/// The `payee` and the payment's value are given in [`RouteParameters::payment_params`]

View file

@ -7,6 +7,7 @@
// You may not use this file except in accordance with one or both of these
// licenses.
use crate::blinded_path::BlindedPath;
use crate::chain;
use crate::chain::WatchedOutput;
use crate::chain::chaininterface;
@ -30,6 +31,7 @@ use crate::ln::msgs::LightningError;
use crate::ln::script::ShutdownScript;
use crate::offers::invoice::UnsignedBolt12Invoice;
use crate::offers::invoice_request::UnsignedInvoiceRequest;
use crate::onion_message::{Destination, MessageRouter, OnionMessagePath};
use crate::routing::gossip::{EffectiveCapacity, NetworkGraph, NodeId, RoutingFees};
use crate::routing::utxo::{UtxoLookup, UtxoLookupError, UtxoResult};
use crate::routing::router::{find_route, InFlightHtlcs, Path, Route, RouteParameters, RouteHintHop, Router, ScorerAccountingForInFlightHtlcs};
@ -51,7 +53,7 @@ use bitcoin::network::constants::Network;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::sighash::{SighashCache, EcdsaSighashType};
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, Signature};
use bitcoin::secp256k1::schnorr;
@ -191,6 +193,23 @@ impl<'a> Router for TestRouter<'a> {
}
}
impl<'a> MessageRouter for TestRouter<'a> {
fn find_path(
&self, _sender: PublicKey, _peers: Vec<PublicKey>, _destination: Destination
) -> Result<OnionMessagePath, ()> {
unreachable!()
}
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!()
}
}
impl<'a> Drop for TestRouter<'a> {
fn drop(&mut self) {
#[cfg(feature = "std")] {