[bindings] Mark `WithContext` log wrapper with no-export
[rust-lightning] / lightning / src / util / test_utils.rs
index 5744c89357c13ef6c7329dfce21379f10efa2d9e..02423541fb9653ebd1c88d8fa1e84dbc666c589b 100644 (file)
@@ -7,6 +7,8 @@
 // You may not use this file except in accordance with one or both of these
 // licenses.
 
+use crate::blinded_path::BlindedPath;
+use crate::blinded_path::payment::ReceiveTlvs;
 use crate::chain;
 use crate::chain::WatchedOutput;
 use crate::chain::chaininterface;
@@ -17,22 +19,23 @@ use crate::chain::chainmonitor::{MonitorUpdateId, UpdateOrigin};
 use crate::chain::channelmonitor;
 use crate::chain::channelmonitor::MonitorEvent;
 use crate::chain::transaction::OutPoint;
-use crate::routing::router::CandidateRouteHop;
+use crate::routing::router::{CandidateRouteHop, FirstHopCandidate, PublicHopCandidate, PrivateHopCandidate};
 use crate::sign;
 use crate::events;
 use crate::events::bump_transaction::{WalletSource, Utxo};
 use crate::ln::ChannelId;
-use crate::ln::channelmanager;
+use crate::ln::channelmanager::{ChannelDetails, self};
 use crate::ln::chan_utils::CommitmentTransaction;
 use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
 use crate::ln::{msgs, wire};
 use crate::ln::msgs::LightningError;
 use crate::ln::script::ShutdownScript;
-use crate::offers::invoice::UnsignedBolt12Invoice;
+use crate::offers::invoice::{BlindedPayInfo, UnsignedBolt12Invoice};
 use crate::offers::invoice_request::UnsignedInvoiceRequest;
+use crate::onion_message::messenger::{DefaultMessageRouter, 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};
+use crate::routing::router::{DefaultRouter, InFlightHtlcs, Path, Route, RouteParameters, RouteHintHop, Router, ScorerAccountingForInFlightHtlcs};
 use crate::routing::scoring::{ChannelUsage, ScoreUpdate, ScoreLookUp};
 use crate::sync::RwLock;
 use crate::util::config::UserConfig;
@@ -51,7 +54,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;
@@ -71,6 +74,7 @@ use crate::sign::{InMemorySigner, Recipient, EntropySource, NodeSigner, SignerPr
 
 #[cfg(feature = "std")]
 use std::time::{SystemTime, UNIX_EPOCH};
+use bitcoin::psbt::PartiallySignedTransaction;
 use bitcoin::Sequence;
 
 pub fn pubkey(byte: u8) -> PublicKey {
@@ -100,14 +104,29 @@ impl chaininterface::FeeEstimator for TestFeeEstimator {
 }
 
 pub struct TestRouter<'a> {
+       pub router: DefaultRouter<
+               Arc<NetworkGraph<&'a TestLogger>>,
+               &'a TestLogger,
+               &'a RwLock<TestScorer>,
+               (),
+               TestScorer,
+       >,
        pub network_graph: Arc<NetworkGraph<&'a TestLogger>>,
        pub next_routes: Mutex<VecDeque<(RouteParameters, Result<Route, LightningError>)>>,
        pub scorer: &'a RwLock<TestScorer>,
 }
 
 impl<'a> TestRouter<'a> {
-       pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>, scorer: &'a RwLock<TestScorer>) -> Self {
-               Self { network_graph, next_routes: Mutex::new(VecDeque::new()), scorer }
+       pub fn new(
+               network_graph: Arc<NetworkGraph<&'a TestLogger>>, logger: &'a TestLogger,
+               scorer: &'a RwLock<TestScorer>
+       ) -> Self {
+               Self {
+                       router: DefaultRouter::new(network_graph.clone(), logger, [42u8; 32], scorer, ()),
+                       network_graph,
+                       next_routes: Mutex::new(VecDeque::new()),
+                       scorer,
+               }
        }
 
        pub fn expect_find_route(&self, query: RouteParameters, result: Result<Route, LightningError>) {
@@ -118,7 +137,7 @@ impl<'a> TestRouter<'a> {
 
 impl<'a> Router for TestRouter<'a> {
        fn find_route(
-               &self, payer: &PublicKey, params: &RouteParameters, first_hops: Option<&[&channelmanager::ChannelDetails]>,
+               &self, payer: &PublicKey, params: &RouteParameters, first_hops: Option<&[&ChannelDetails]>,
                inflight_htlcs: InFlightHtlcs
        ) -> Result<Route, msgs::LightningError> {
                if let Some((find_route_query, find_route_res)) = self.next_routes.lock().unwrap().pop_front() {
@@ -142,10 +161,10 @@ impl<'a> Router for TestRouter<'a> {
                                                        if let Some(first_hops) = first_hops {
                                                                if let Some(idx) = first_hops.iter().position(|h| h.get_outbound_payment_scid() == Some(hop.short_channel_id)) {
                                                                        let node_id = NodeId::from_pubkey(payer);
-                                                                       let candidate = CandidateRouteHop::FirstHop {
+                                                                       let candidate = CandidateRouteHop::FirstHop(FirstHopCandidate {
                                                                                details: first_hops[idx],
                                                                                payer_node_id: &node_id,
-                                                                       };
+                                                                       });
                                                                        scorer.channel_penalty_msat(&candidate, usage, &());
                                                                        continue;
                                                                }
@@ -154,10 +173,10 @@ impl<'a> Router for TestRouter<'a> {
                                                let network_graph = self.network_graph.read_only();
                                                if let Some(channel) = network_graph.channel(hop.short_channel_id) {
                                                        let (directed, _) = channel.as_directed_to(&NodeId::from_pubkey(&hop.pubkey)).unwrap();
-                                                       let candidate = CandidateRouteHop::PublicHop {
+                                                       let candidate = CandidateRouteHop::PublicHop(PublicHopCandidate {
                                                                info: directed,
                                                                short_channel_id: hop.short_channel_id,
-                                                       };
+                                                       });
                                                        scorer.channel_penalty_msat(&candidate, usage, &());
                                                } else {
                                                        let target_node_id = NodeId::from_pubkey(&hop.pubkey);
@@ -169,10 +188,10 @@ impl<'a> Router for TestRouter<'a> {
                                                                htlc_minimum_msat: None,
                                                                htlc_maximum_msat: None,
                                                        };
-                                                       let candidate = CandidateRouteHop::PrivateHop {
+                                                       let candidate = CandidateRouteHop::PrivateHop(PrivateHopCandidate {
                                                                hint: &route_hint,
                                                                target_node_id: &target_node_id,
-                                                       };
+                                                       });
                                                        scorer.channel_penalty_msat(&candidate, usage, &());
                                                }
                                                prev_hop_node = &hop.pubkey;
@@ -181,15 +200,39 @@ impl<'a> Router for TestRouter<'a> {
                        }
                        return find_route_res;
                }
-               let logger = TestLogger::new();
-               find_route(
-                       payer, params, &self.network_graph, first_hops, &logger,
-                       &ScorerAccountingForInFlightHtlcs::new(self.scorer.read().unwrap(), &inflight_htlcs), &Default::default(),
-                       &[42; 32]
+
+               self.router.find_route(payer, params, first_hops, inflight_htlcs)
+       }
+
+       fn create_blinded_payment_paths<
+               ES: EntropySource + ?Sized, T: secp256k1::Signing + secp256k1::Verification
+       >(
+               &self, recipient: PublicKey, first_hops: Vec<ChannelDetails>, tlvs: ReceiveTlvs,
+               amount_msats: u64, entropy_source: &ES, secp_ctx: &Secp256k1<T>
+       ) -> Result<Vec<(BlindedPayInfo, BlindedPath)>, ()> {
+               self.router.create_blinded_payment_paths(
+                       recipient, first_hops, tlvs, amount_msats, entropy_source, secp_ctx
                )
        }
 }
 
+impl<'a> MessageRouter for TestRouter<'a> {
+       fn find_path(
+               &self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
+       ) -> Result<OnionMessagePath, ()> {
+               self.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.router.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
+       }
+}
+
 impl<'a> Drop for TestRouter<'a> {
        fn drop(&mut self) {
                #[cfg(feature = "std")] {
@@ -201,6 +244,33 @@ impl<'a> Drop for TestRouter<'a> {
        }
 }
 
+pub struct TestMessageRouter<'a> {
+       inner: DefaultMessageRouter<Arc<NetworkGraph<&'a TestLogger>>, &'a TestLogger>,
+}
+
+impl<'a> TestMessageRouter<'a> {
+       pub fn new(network_graph: Arc<NetworkGraph<&'a TestLogger>>) -> Self {
+               Self { inner: DefaultMessageRouter::new(network_graph) }
+       }
+}
+
+impl<'a> MessageRouter for TestMessageRouter<'a> {
+       fn find_path(
+               &self, sender: PublicKey, peers: Vec<PublicKey>, destination: Destination
+       ) -> Result<OnionMessagePath, ()> {
+               self.inner.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.inner.create_blinded_paths(recipient, peers, entropy_source, secp_ctx)
+       }
+}
+
 pub struct OnlyReadsKeysInterface {}
 
 impl EntropySource for OnlyReadsKeysInterface {
@@ -1349,15 +1419,20 @@ impl ScoreLookUp for TestScorer {
 }
 
 impl ScoreUpdate for TestScorer {
-       fn payment_path_failed(&mut self, _actual_path: &Path, _actual_short_channel_id: u64) {}
+       fn payment_path_failed(&mut self, _actual_path: &Path, _actual_short_channel_id: u64, _duration_since_epoch: Duration) {}
 
-       fn payment_path_successful(&mut self, _actual_path: &Path) {}
+       fn payment_path_successful(&mut self, _actual_path: &Path, _duration_since_epoch: Duration) {}
 
-       fn probe_failed(&mut self, _actual_path: &Path, _: u64) {}
+       fn probe_failed(&mut self, _actual_path: &Path, _: u64, _duration_since_epoch: Duration) {}
 
-       fn probe_successful(&mut self, _actual_path: &Path) {}
+       fn probe_successful(&mut self, _actual_path: &Path, _duration_since_epoch: Duration) {}
+
+       fn time_passed(&mut self, _duration_since_epoch: Duration) {}
 }
 
+#[cfg(c_bindings)]
+impl crate::routing::scoring::Score for TestScorer {}
+
 impl Drop for TestScorer {
        fn drop(&mut self) {
                #[cfg(feature = "std")] {
@@ -1417,7 +1492,8 @@ impl WalletSource for TestWalletSource {
                Ok(ScriptBuf::new_p2pkh(&public_key.pubkey_hash()))
        }
 
-       fn sign_tx(&self, mut tx: Transaction) -> Result<Transaction, ()> {
+       fn sign_psbt(&self, psbt: PartiallySignedTransaction) -> Result<Transaction, ()> {
+               let mut tx = psbt.extract_tx();
                let utxos = self.utxos.borrow();
                for i in 0..tx.input.len() {
                        if let Some(utxo) = utxos.iter().find(|utxo| utxo.outpoint == tx.input[i].previous_output) {