Merge pull request #2249 from TheBlueMatt/2023-04-less-pm-bounds
[rust-lightning] / lightning / src / util / test_utils.rs
index e50576e1a83960d41d4ab973d8bf943e777465f7..96d934daad4f1d52bc3fe3e89df87913dc0c16f5 100644 (file)
@@ -17,6 +17,7 @@ use crate::chain::channelmonitor;
 use crate::chain::channelmonitor::MonitorEvent;
 use crate::chain::transaction::OutPoint;
 use crate::chain::keysinterface;
+use crate::events;
 use crate::ln::channelmanager;
 use crate::ln::features::{ChannelFeatures, InitFeatures, NodeFeatures};
 use crate::ln::{msgs, wire};
@@ -24,11 +25,10 @@ use crate::ln::msgs::LightningError;
 use crate::ln::script::ShutdownScript;
 use crate::routing::gossip::{EffectiveCapacity, NetworkGraph, NodeId};
 use crate::routing::utxo::{UtxoLookup, UtxoLookupError, UtxoResult};
-use crate::routing::router::{find_route, InFlightHtlcs, Route, RouteHop, RouteParameters, Router, ScorerAccountingForInFlightHtlcs};
+use crate::routing::router::{find_route, InFlightHtlcs, Path, Route, RouteParameters, Router, ScorerAccountingForInFlightHtlcs};
 use crate::routing::scoring::{ChannelUsage, Score};
 use crate::util::config::UserConfig;
 use crate::util::enforcing_trait_impls::{EnforcingSigner, EnforcementState};
-use crate::util::events;
 use crate::util::logger::{Logger, Level, Record};
 use crate::util::ser::{Readable, ReadableArgs, Writer, Writeable};
 
@@ -60,6 +60,15 @@ use crate::chain::keysinterface::{InMemorySigner, Recipient, EntropySource, Node
 use std::time::{SystemTime, UNIX_EPOCH};
 use bitcoin::Sequence;
 
+pub fn pubkey(byte: u8) -> PublicKey {
+       let secp_ctx = Secp256k1::new();
+       PublicKey::from_secret_key(&secp_ctx, &privkey(byte))
+}
+
+pub fn privkey(byte: u8) -> SecretKey {
+       SecretKey::from_slice(&[byte; 32]).unwrap()
+}
+
 pub struct TestVecWriter(pub Vec<u8>);
 impl Writer for TestVecWriter {
        fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> {
@@ -106,7 +115,7 @@ impl<'a> Router for TestRouter<'a> {
                                let scorer = ScorerAccountingForInFlightHtlcs::new(locked_scorer, inflight_htlcs);
                                for path in &route.paths {
                                        let mut aggregate_msat = 0u64;
-                                       for (idx, hop) in path.iter().rev().enumerate() {
+                                       for (idx, hop) in path.hops.iter().rev().enumerate() {
                                                aggregate_msat += hop.fee_msat;
                                                let usage = ChannelUsage {
                                                        amount_msat: aggregate_msat,
@@ -116,11 +125,11 @@ impl<'a> Router for TestRouter<'a> {
 
                                                // Since the path is reversed, the last element in our iteration is the first
                                                // hop.
-                                               if idx == path.len() - 1 {
+                                               if idx == path.hops.len() - 1 {
                                                        scorer.channel_penalty_msat(hop.short_channel_id, &NodeId::from_pubkey(payer), &NodeId::from_pubkey(&hop.pubkey), usage);
                                                } else {
-                                                       let curr_hop_path_idx = path.len() - 1 - idx;
-                                                       scorer.channel_penalty_msat(hop.short_channel_id, &NodeId::from_pubkey(&path[curr_hop_path_idx - 1].pubkey), &NodeId::from_pubkey(&hop.pubkey), usage);
+                                                       let curr_hop_path_idx = path.hops.len() - 1 - idx;
+                                                       scorer.channel_penalty_msat(hop.short_channel_id, &NodeId::from_pubkey(&path.hops[curr_hop_path_idx - 1].pubkey), &NodeId::from_pubkey(&hop.pubkey), usage);
                                                }
                                        }
                                }
@@ -137,11 +146,12 @@ impl<'a> Router for TestRouter<'a> {
        }
 }
 
-#[cfg(feature = "std")] // If we put this on the `if`, we get "attributes are not yet allowed on `if` expressions" on 1.41.1
 impl<'a> Drop for TestRouter<'a> {
        fn drop(&mut self) {
-               if std::thread::panicking() {
-                       return;
+               #[cfg(feature = "std")] {
+                       if std::thread::panicking() {
+                               return;
+                       }
                }
                assert!(self.next_routes.lock().unwrap().is_empty());
        }
@@ -160,7 +170,7 @@ impl SignerProvider for OnlyReadsKeysInterface {
        fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::Signer { unreachable!(); }
 
        fn read_chan_signer(&self, mut reader: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
-               let inner: InMemorySigner = Readable::read(&mut reader)?;
+               let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?;
                let state = Arc::new(Mutex::new(EnforcementState::new()));
 
                Ok(EnforcingSigner::new_with_revoked(
@@ -170,8 +180,8 @@ impl SignerProvider for OnlyReadsKeysInterface {
                ))
        }
 
-       fn get_destination_script(&self) -> Script { unreachable!(); }
-       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript { unreachable!(); }
+       fn get_destination_script(&self) -> Result<Script, ()> { Err(()) }
+       fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()> { Err(()) }
 }
 
 pub struct TestChainMonitor<'a> {
@@ -307,8 +317,26 @@ pub struct TestBroadcaster {
 }
 
 impl TestBroadcaster {
-       pub fn new(blocks: Arc<Mutex<Vec<(Block, u32)>>>) -> TestBroadcaster {
-               TestBroadcaster { txn_broadcasted: Mutex::new(Vec::new()), blocks }
+       pub fn new(network: Network) -> Self {
+               Self {
+                       txn_broadcasted: Mutex::new(Vec::new()),
+                       blocks: Arc::new(Mutex::new(vec![(genesis_block(network), 0)])),
+               }
+       }
+
+       pub fn with_blocks(blocks: Arc<Mutex<Vec<(Block, u32)>>>) -> Self {
+               Self { txn_broadcasted: Mutex::new(Vec::new()), blocks }
+       }
+
+       pub fn txn_broadcast(&self) -> Vec<Transaction> {
+               self.txn_broadcasted.lock().unwrap().split_off(0)
+       }
+
+       pub fn unique_txn_broadcast(&self) -> Vec<Transaction> {
+               let mut txn = self.txn_broadcasted.lock().unwrap().split_off(0);
+               let mut seen = HashSet::new();
+               txn.retain(|tx| seen.insert(tx.txid()));
+               txn
        }
 }
 
@@ -316,7 +344,7 @@ impl chaininterface::BroadcasterInterface for TestBroadcaster {
        fn broadcast_transaction(&self, tx: &Transaction) {
                let lock_time = tx.lock_time.0;
                assert!(lock_time < 1_500_000_000);
-               if lock_time > self.blocks.lock().unwrap().len() as u32 + 1 && lock_time < 500_000_000 {
+               if bitcoin::LockTime::from(tx.lock_time).is_block_height() && lock_time > self.blocks.lock().unwrap().last().unwrap().1 {
                        for inp in tx.input.iter() {
                                if inp.sequence != Sequence::MAX {
                                        panic!("We should never broadcast a transaction before its locktime ({})!", tx.lock_time);
@@ -423,10 +451,10 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
        fn handle_channel_reestablish(&self, _their_node_id: &PublicKey, msg: &msgs::ChannelReestablish) {
                self.received_msg(wire::Message::ChannelReestablish(msg.clone()));
        }
-       fn peer_disconnected(&self, their_node_id: &PublicKey, _no_connection_possible: bool) {
+       fn peer_disconnected(&self, their_node_id: &PublicKey) {
                assert!(self.connected_peers.lock().unwrap().remove(their_node_id));
        }
-       fn peer_connected(&self, their_node_id: &PublicKey, _msg: &msgs::Init) -> Result<(), ()> {
+       fn peer_connected(&self, their_node_id: &PublicKey, _msg: &msgs::Init, _inbound: bool) -> Result<(), ()> {
                assert!(self.connected_peers.lock().unwrap().insert(their_node_id.clone()));
                // Don't bother with `received_msg` for Init as its auto-generated and we don't want to
                // bother re-generating the expected Init message in all tests.
@@ -543,7 +571,7 @@ impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
                None
        }
 
-       fn peer_connected(&self, their_node_id: &PublicKey, init_msg: &msgs::Init) -> Result<(), ()> {
+       fn peer_connected(&self, their_node_id: &PublicKey, init_msg: &msgs::Init, _inbound: bool) -> Result<(), ()> {
                if !init_msg.features.supports_gossip_queries() {
                        return Ok(());
                }
@@ -641,10 +669,10 @@ impl TestLogger {
        /// 1. belongs to the specified module and
        /// 2. contains `line` in it.
        /// And asserts if the number of occurrences is the same with the given `count`
-       pub fn assert_log_contains(&self, module: String, line: String, count: usize) {
+       pub fn assert_log_contains(&self, module: &str, line: &str, count: usize) {
                let log_entries = self.lines.lock().unwrap();
                let l: usize = log_entries.iter().filter(|&(&(ref m, ref l), _c)| {
-                       m == &module && l.contains(line.as_str())
+                       m == module && l.contains(line)
                }).map(|(_, c) | { c }).sum();
                assert_eq!(l, count)
        }
@@ -653,10 +681,10 @@ impl TestLogger {
        /// 1. belong to the specified module and
        /// 2. match the given regex pattern.
        /// Assert that the number of occurrences equals the given `count`
-       pub fn assert_log_regex(&self, module: String, pattern: regex::Regex, count: usize) {
+       pub fn assert_log_regex(&self, module: &str, pattern: regex::Regex, count: usize) {
                let log_entries = self.lines.lock().unwrap();
                let l: usize = log_entries.iter().filter(|&(&(ref m, ref l), _c)| {
-                       m == &module && pattern.is_match(&l)
+                       m == module && pattern.is_match(&l)
                }).map(|(_, c) | { c }).sum();
                assert_eq!(l, count)
        }
@@ -771,7 +799,7 @@ impl SignerProvider for TestKeysInterface {
        fn read_chan_signer(&self, buffer: &[u8]) -> Result<Self::Signer, msgs::DecodeError> {
                let mut reader = io::Cursor::new(buffer);
 
-               let inner: InMemorySigner = Readable::read(&mut reader)?;
+               let inner: InMemorySigner = ReadableArgs::read(&mut reader, self)?;
                let state = self.make_enforcement_state_cell(inner.commitment_seed);
 
                Ok(EnforcingSigner::new_with_revoked(
@@ -781,14 +809,14 @@ impl SignerProvider for TestKeysInterface {
                ))
        }
 
-       fn get_destination_script(&self) -> Script { self.backing.get_destination_script() }
+       fn get_destination_script(&self) -> Result<Script, ()> { self.backing.get_destination_script() }
 
-       fn get_shutdown_scriptpubkey(&self) -> ShutdownScript {
+       fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()> {
                match &mut *self.expectations.lock().unwrap() {
                        None => self.backing.get_shutdown_scriptpubkey(),
                        Some(expectations) => match expectations.pop_front() {
                                None => panic!("Unexpected get_shutdown_scriptpubkey"),
-                               Some(expectation) => expectation.returns,
+                               Some(expectation) => Ok(expectation.returns),
                        },
                }
        }
@@ -955,13 +983,13 @@ impl Score for TestScorer {
                0
        }
 
-       fn payment_path_failed(&mut self, _actual_path: &[&RouteHop], _actual_short_channel_id: u64) {}
+       fn payment_path_failed(&mut self, _actual_path: &Path, _actual_short_channel_id: u64) {}
 
-       fn payment_path_successful(&mut self, _actual_path: &[&RouteHop]) {}
+       fn payment_path_successful(&mut self, _actual_path: &Path) {}
 
-       fn probe_failed(&mut self, _actual_path: &[&RouteHop], _: u64) {}
+       fn probe_failed(&mut self, _actual_path: &Path, _: u64) {}
 
-       fn probe_successful(&mut self, _actual_path: &[&RouteHop]) {}
+       fn probe_successful(&mut self, _actual_path: &Path) {}
 }
 
 impl Drop for TestScorer {