Merge pull request #1370 from TheBlueMatt/2022-03-pref-first-hop-chans
authorMatt Corallo <649246+TheBlueMatt@users.noreply.github.com>
Wed, 23 Mar 2022 22:44:37 +0000 (22:44 +0000)
committerGitHub <noreply@github.com>
Wed, 23 Mar 2022 22:44:37 +0000 (22:44 +0000)
Avoid needless MPP on multiple channels to the same first-hop

21 files changed:
.github/workflows/build.yml
fuzz/src/chanmon_consistency.rs
fuzz/src/full_stack.rs
lightning-background-processor/src/lib.rs
lightning-net-tokio/src/lib.rs
lightning/src/debug_sync.rs
lightning/src/ln/chanmon_update_fail_tests.rs
lightning/src/ln/channelmanager.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/functional_tests.rs
lightning/src/ln/msgs.rs
lightning/src/ln/payment_tests.rs
lightning/src/ln/peer_handler.rs
lightning/src/ln/priv_short_conf_tests.rs
lightning/src/ln/shutdown_tests.rs
lightning/src/ln/wire.rs
lightning/src/routing/network_graph.rs
lightning/src/routing/router.rs
lightning/src/routing/scoring.rs
lightning/src/util/events.rs
lightning/src/util/test_utils.rs

index d25e9a43c19ab4682e4ab75105c372d3ab35b9df..aaccb76a40e98b6eb7a585f81d99eb41ca511b31 100644 (file)
@@ -211,7 +211,7 @@ jobs:
           profile: minimal
       - name: Cache routing graph snapshot
         id: cache-graph
-        uses: actions/cache@v2
+        uses: actions/cache@v3
         with:
           path: lightning/net_graph-2021-05-31.bin
           key: ldk-net_graph-v0.0.15-2021-05-31.bin
index 79faba901581190742232aafe994fd969a5e0332..8c4f5adcb64ae64abbbc03b0956c556f3abbf44c 100644 (file)
@@ -411,8 +411,8 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
        let mut channel_txn = Vec::new();
        macro_rules! make_channel {
                ($source: expr, $dest: expr, $chan_id: expr) => { {
-                       $source.peer_connected(&$dest.get_our_node_id(), &Init { features: InitFeatures::known() });
-                       $dest.peer_connected(&$source.get_our_node_id(), &Init { features: InitFeatures::known() });
+                       $source.peer_connected(&$dest.get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
+                       $dest.peer_connected(&$source.get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
 
                        $source.create_channel($dest.get_our_node_id(), 100_000, 42, 0, None).unwrap();
                        let open_channel = {
@@ -921,15 +921,15 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
                        },
                        0x0e => {
                                if chan_a_disconnected {
-                                       nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
-                                       nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known() });
+                                       nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
+                                       nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
                                        chan_a_disconnected = false;
                                }
                        },
                        0x0f => {
                                if chan_b_disconnected {
-                                       nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known() });
-                                       nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
+                                       nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
+                                       nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
                                        chan_b_disconnected = false;
                                }
                        },
@@ -1124,13 +1124,13 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out) {
 
                                // Next, make sure peers are all connected to each other
                                if chan_a_disconnected {
-                                       nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
-                                       nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known() });
+                                       nodes[0].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
+                                       nodes[1].peer_connected(&nodes[0].get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
                                        chan_a_disconnected = false;
                                }
                                if chan_b_disconnected {
-                                       nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known() });
-                                       nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known() });
+                                       nodes[1].peer_connected(&nodes[2].get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
+                                       nodes[2].peer_connected(&nodes[1].get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
                                        chan_b_disconnected = false;
                                }
 
index a4e1a08648f3aac50413659f0a2bcea7985ca006..0412547a0089a150db7f8038d7c4454a8bf05b02 100644 (file)
@@ -422,7 +422,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                        }
                                }
                                if new_id == 0 { return; }
-                               loss_detector.handler.new_outbound_connection(get_pubkey!(), Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
+                               loss_detector.handler.new_outbound_connection(get_pubkey!(), Peer{id: (new_id - 1) as u8, peers_connected: &peers}, None).unwrap();
                                peers.borrow_mut()[new_id - 1] = true;
                        },
                        1 => {
@@ -434,7 +434,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
                                        }
                                }
                                if new_id == 0 { return; }
-                               loss_detector.handler.new_inbound_connection(Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
+                               loss_detector.handler.new_inbound_connection(Peer{id: (new_id - 1) as u8, peers_connected: &peers}, None).unwrap();
                                peers.borrow_mut()[new_id - 1] = true;
                        },
                        2 => {
index 084ea62efb6faf51f0ff67b0b5fb01fc61f965ef..22fef2661fa661d82884c047bb09697959841a15 100644 (file)
@@ -435,8 +435,8 @@ mod tests {
 
                for i in 0..num_nodes {
                        for j in (i+1)..num_nodes {
-                               nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &Init { features: InitFeatures::known() });
-                               nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &Init { features: InitFeatures::known() });
+                               nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
+                               nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
                        }
                }
 
index 2582cc597f20d361906271811e8d523f5977516e..a9fd861bc846e440fd8ff54ab31deedf622aa8e6 100644 (file)
@@ -81,10 +81,11 @@ use tokio::io::{AsyncReadExt, AsyncWrite, AsyncWriteExt};
 use lightning::ln::peer_handler;
 use lightning::ln::peer_handler::SocketDescriptor as LnSocketTrait;
 use lightning::ln::peer_handler::CustomMessageHandler;
-use lightning::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler};
+use lightning::ln::msgs::{ChannelMessageHandler, RoutingMessageHandler, NetAddress};
 use lightning::util::logger::Logger;
 
 use std::task;
+use std::net::IpAddr;
 use std::net::SocketAddr;
 use std::net::TcpStream as StdTcpStream;
 use std::sync::{Arc, Mutex};
@@ -222,11 +223,21 @@ pub fn setup_inbound<CMH, RMH, L, UMH>(peer_manager: Arc<peer_handler::PeerManag
                RMH: RoutingMessageHandler + 'static + Send + Sync,
                L: Logger + 'static + ?Sized + Send + Sync,
                UMH: CustomMessageHandler + 'static + Send + Sync {
+       let ip_addr = stream.peer_addr().unwrap();
        let (reader, write_receiver, read_receiver, us) = Connection::new(stream);
        #[cfg(debug_assertions)]
        let last_us = Arc::clone(&us);
 
-       let handle_opt = if let Ok(_) = peer_manager.new_inbound_connection(SocketDescriptor::new(us.clone())) {
+       let handle_opt = if let Ok(_) = peer_manager.new_inbound_connection(SocketDescriptor::new(us.clone()), match ip_addr.ip() {
+               IpAddr::V4(ip) => Some(NetAddress::IPv4 {
+                       addr: ip.octets(),
+                       port: ip_addr.port(),
+               }),
+               IpAddr::V6(ip) => Some(NetAddress::IPv6 {
+                       addr: ip.octets(),
+                       port: ip_addr.port(),
+               }),
+       }) {
                Some(tokio::spawn(Connection::schedule_read(peer_manager, us, reader, read_receiver, write_receiver)))
        } else {
                // Note that we will skip socket_disconnected here, in accordance with the PeerManager
@@ -263,11 +274,20 @@ pub fn setup_outbound<CMH, RMH, L, UMH>(peer_manager: Arc<peer_handler::PeerMana
                RMH: RoutingMessageHandler + 'static + Send + Sync,
                L: Logger + 'static + ?Sized + Send + Sync,
                UMH: CustomMessageHandler + 'static + Send + Sync {
+       let ip_addr = stream.peer_addr().unwrap();
        let (reader, mut write_receiver, read_receiver, us) = Connection::new(stream);
        #[cfg(debug_assertions)]
        let last_us = Arc::clone(&us);
-
-       let handle_opt = if let Ok(initial_send) = peer_manager.new_outbound_connection(their_node_id, SocketDescriptor::new(us.clone())) {
+       let handle_opt = if let Ok(initial_send) = peer_manager.new_outbound_connection(their_node_id, SocketDescriptor::new(us.clone()), match ip_addr.ip() {
+               IpAddr::V4(ip) => Some(NetAddress::IPv4 {
+                       addr: ip.octets(),
+                       port: ip_addr.port(),
+               }),
+               IpAddr::V6(ip) => Some(NetAddress::IPv6 {
+                       addr: ip.octets(),
+                       port: ip_addr.port(),
+               }),
+       }) {
                Some(tokio::spawn(async move {
                        // We should essentially always have enough room in a TCP socket buffer to send the
                        // initial 10s of bytes. However, tokio running in single-threaded mode will always
@@ -496,7 +516,7 @@ mod tests {
                fn handle_channel_update(&self, _msg: &ChannelUpdate) -> Result<bool, LightningError> { Ok(false) }
                fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) -> Vec<(ChannelAnnouncement, Option<ChannelUpdate>, Option<ChannelUpdate>)> { Vec::new() }
                fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec<NodeAnnouncement> { Vec::new() }
-               fn sync_routing_table(&self, _their_node_id: &PublicKey, _init_msg: &Init) { }
+               fn peer_connected(&self, _their_node_id: &PublicKey, _init_msg: &Init) { }
                fn handle_reply_channel_range(&self, _their_node_id: &PublicKey, _msg: ReplyChannelRange) -> Result<(), LightningError> { Ok(()) }
                fn handle_reply_short_channel_ids_end(&self, _their_node_id: &PublicKey, _msg: ReplyShortChannelIdsEnd) -> Result<(), LightningError> { Ok(()) }
                fn handle_query_channel_range(&self, _their_node_id: &PublicKey, _msg: QueryChannelRange) -> Result<(), LightningError> { Ok(()) }
index 7ee5ee521bc55e37fe578180c25f8d58e647bf53..b31ceacea15852def4203b037d8e36216094f5c4 100644 (file)
@@ -43,30 +43,90 @@ impl Condvar {
 }
 
 thread_local! {
-       /// We track the set of locks currently held by a reference to their `MutexMetadata`
-       static MUTEXES_HELD: RefCell<HashSet<Arc<MutexMetadata>>> = RefCell::new(HashSet::new());
+       /// We track the set of locks currently held by a reference to their `LockMetadata`
+       static LOCKS_HELD: RefCell<HashSet<Arc<LockMetadata>>> = RefCell::new(HashSet::new());
 }
-static MUTEX_IDX: AtomicUsize = AtomicUsize::new(0);
+static LOCK_IDX: AtomicUsize = AtomicUsize::new(0);
 
-/// Metadata about a single mutex, by id, the set of things locked-before it, and the backtrace of
+/// Metadata about a single lock, by id, the set of things locked-before it, and the backtrace of
 /// when the Mutex itself was constructed.
-struct MutexMetadata {
-       mutex_idx: u64,
-       locked_before: StdMutex<HashSet<Arc<MutexMetadata>>>,
+struct LockMetadata {
+       lock_idx: u64,
+       locked_before: StdMutex<HashSet<Arc<LockMetadata>>>,
        #[cfg(feature = "backtrace")]
-       mutex_construction_bt: Backtrace,
+       lock_construction_bt: Backtrace,
 }
-impl PartialEq for MutexMetadata {
-       fn eq(&self, o: &MutexMetadata) -> bool { self.mutex_idx == o.mutex_idx }
+impl PartialEq for LockMetadata {
+       fn eq(&self, o: &LockMetadata) -> bool { self.lock_idx == o.lock_idx }
 }
-impl Eq for MutexMetadata {}
-impl std::hash::Hash for MutexMetadata {
-       fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) { hasher.write_u64(self.mutex_idx); }
+impl Eq for LockMetadata {}
+impl std::hash::Hash for LockMetadata {
+       fn hash<H: std::hash::Hasher>(&self, hasher: &mut H) { hasher.write_u64(self.lock_idx); }
+}
+
+impl LockMetadata {
+       fn new() -> LockMetadata {
+               LockMetadata {
+                       locked_before: StdMutex::new(HashSet::new()),
+                       lock_idx: LOCK_IDX.fetch_add(1, Ordering::Relaxed) as u64,
+                       #[cfg(feature = "backtrace")]
+                       lock_construction_bt: Backtrace::new(),
+               }
+       }
+
+       // Returns whether we were a recursive lock (only relevant for read)
+       fn _pre_lock(this: &Arc<LockMetadata>, read: bool) -> bool {
+               let mut inserted = false;
+               LOCKS_HELD.with(|held| {
+                       // For each lock which is currently locked, check that no lock's locked-before
+                       // set includes the lock we're about to lock, which would imply a lockorder
+                       // inversion.
+                       for locked in held.borrow().iter() {
+                               if read && *locked == *this {
+                                       // Recursive read locks are explicitly allowed
+                                       return;
+                               }
+                       }
+                       for locked in held.borrow().iter() {
+                               if !read && *locked == *this {
+                                       panic!("Tried to lock a lock while it was held!");
+                               }
+                               for locked_dep in locked.locked_before.lock().unwrap().iter() {
+                                       if *locked_dep == *this {
+                                               #[cfg(feature = "backtrace")]
+                                               panic!("Tried to violate existing lockorder.\nMutex that should be locked after the current lock was created at the following backtrace.\nNote that to get a backtrace for the lockorder violation, you should set RUST_BACKTRACE=1\n{:?}", locked.lock_construction_bt);
+                                               #[cfg(not(feature = "backtrace"))]
+                                               panic!("Tried to violate existing lockorder. Build with the backtrace feature for more info.");
+                                       }
+                               }
+                               // Insert any already-held locks in our locked-before set.
+                               this.locked_before.lock().unwrap().insert(Arc::clone(locked));
+                       }
+                       held.borrow_mut().insert(Arc::clone(this));
+                       inserted = true;
+               });
+               inserted
+       }
+
+       fn pre_lock(this: &Arc<LockMetadata>) { Self::_pre_lock(this, false); }
+       fn pre_read_lock(this: &Arc<LockMetadata>) -> bool { Self::_pre_lock(this, true) }
+
+       fn try_locked(this: &Arc<LockMetadata>) {
+               LOCKS_HELD.with(|held| {
+                       // Since a try-lock will simply fail if the lock is held already, we do not
+                       // consider try-locks to ever generate lockorder inversions. However, if a try-lock
+                       // succeeds, we do consider it to have created lockorder dependencies.
+                       for locked in held.borrow().iter() {
+                               this.locked_before.lock().unwrap().insert(Arc::clone(locked));
+                       }
+                       held.borrow_mut().insert(Arc::clone(this));
+               });
+       }
 }
 
 pub struct Mutex<T: Sized> {
        inner: StdMutex<T>,
-       deps: Arc<MutexMetadata>,
+       deps: Arc<LockMetadata>,
 }
 
 #[must_use = "if unused the Mutex will immediately unlock"]
@@ -88,7 +148,7 @@ impl<'a, T: Sized> MutexGuard<'a, T> {
 
 impl<T: Sized> Drop for MutexGuard<'_, T> {
        fn drop(&mut self) {
-               MUTEXES_HELD.with(|held| {
+               LOCKS_HELD.with(|held| {
                        held.borrow_mut().remove(&self.mutex.deps);
                });
        }
@@ -110,104 +170,195 @@ impl<T: Sized> DerefMut for MutexGuard<'_, T> {
 
 impl<T> Mutex<T> {
        pub fn new(inner: T) -> Mutex<T> {
-               Mutex {
-                       inner: StdMutex::new(inner),
-                       deps: Arc::new(MutexMetadata {
-                               locked_before: StdMutex::new(HashSet::new()),
-                               mutex_idx: MUTEX_IDX.fetch_add(1, Ordering::Relaxed) as u64,
-                               #[cfg(feature = "backtrace")]
-                               mutex_construction_bt: Backtrace::new(),
-                       }),
-               }
+               Mutex { inner: StdMutex::new(inner), deps: Arc::new(LockMetadata::new()) }
        }
 
        pub fn lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
-               MUTEXES_HELD.with(|held| {
-                       // For each mutex which is currently locked, check that no mutex's locked-before
-                       // set includes the mutex we're about to lock, which would imply a lockorder
-                       // inversion.
-                       for locked in held.borrow().iter() {
-                               for locked_dep in locked.locked_before.lock().unwrap().iter() {
-                                       if *locked_dep == self.deps {
-                                               #[cfg(feature = "backtrace")]
-                                               panic!("Tried to violate existing lockorder.\nMutex that should be locked after the current lock was created at the following backtrace.\nNote that to get a backtrace for the lockorder violation, you should set RUST_BACKTRACE=1\n{:?}", locked.mutex_construction_bt);
-                                               #[cfg(not(feature = "backtrace"))]
-                                               panic!("Tried to violate existing lockorder. Build with the backtrace feature for more info.");
-                                       }
-                               }
-                               // Insert any already-held mutexes in our locked-before set.
-                               self.deps.locked_before.lock().unwrap().insert(Arc::clone(locked));
-                       }
-                       held.borrow_mut().insert(Arc::clone(&self.deps));
-               });
+               LockMetadata::pre_lock(&self.deps);
                self.inner.lock().map(|lock| MutexGuard { mutex: self, lock }).map_err(|_| ())
        }
 
        pub fn try_lock<'a>(&'a self) -> LockResult<MutexGuard<'a, T>> {
                let res = self.inner.try_lock().map(|lock| MutexGuard { mutex: self, lock }).map_err(|_| ());
                if res.is_ok() {
-                       MUTEXES_HELD.with(|held| {
-                               // Since a try-lock will simply fail if the lock is held already, we do not
-                               // consider try-locks to ever generate lockorder inversions. However, if a try-lock
-                               // succeeds, we do consider it to have created lockorder dependencies.
-                               for locked in held.borrow().iter() {
-                                       self.deps.locked_before.lock().unwrap().insert(Arc::clone(locked));
-                               }
-                               held.borrow_mut().insert(Arc::clone(&self.deps));
-                       });
+                       LockMetadata::try_locked(&self.deps);
                }
                res
        }
 }
 
-pub struct RwLock<T: ?Sized> {
-       inner: StdRwLock<T>
+pub struct RwLock<T: Sized> {
+       inner: StdRwLock<T>,
+       deps: Arc<LockMetadata>,
 }
 
-pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
-       lock: StdRwLockReadGuard<'a, T>,
+pub struct RwLockReadGuard<'a, T: Sized + 'a> {
+       lock: &'a RwLock<T>,
+       first_lock: bool,
+       guard: StdRwLockReadGuard<'a, T>,
 }
 
-pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
-       lock: StdRwLockWriteGuard<'a, T>,
+pub struct RwLockWriteGuard<'a, T: Sized + 'a> {
+       lock: &'a RwLock<T>,
+       guard: StdRwLockWriteGuard<'a, T>,
 }
 
-impl<T: ?Sized> Deref for RwLockReadGuard<'_, T> {
+impl<T: Sized> Deref for RwLockReadGuard<'_, T> {
        type Target = T;
 
        fn deref(&self) -> &T {
-               &self.lock.deref()
+               &self.guard.deref()
        }
 }
 
-impl<T: ?Sized> Deref for RwLockWriteGuard<'_, T> {
+impl<T: Sized> Drop for RwLockReadGuard<'_, T> {
+       fn drop(&mut self) {
+               if !self.first_lock {
+                       // Note that its not strictly true that the first taken read lock will get unlocked
+                       // last, but in practice our locks are always taken as RAII, so it should basically
+                       // always be true.
+                       return;
+               }
+               LOCKS_HELD.with(|held| {
+                       held.borrow_mut().remove(&self.lock.deps);
+               });
+       }
+}
+
+impl<T: Sized> Deref for RwLockWriteGuard<'_, T> {
        type Target = T;
 
        fn deref(&self) -> &T {
-               &self.lock.deref()
+               &self.guard.deref()
+       }
+}
+
+impl<T: Sized> Drop for RwLockWriteGuard<'_, T> {
+       fn drop(&mut self) {
+               LOCKS_HELD.with(|held| {
+                       held.borrow_mut().remove(&self.lock.deps);
+               });
        }
 }
 
-impl<T: ?Sized> DerefMut for RwLockWriteGuard<'_, T> {
+impl<T: Sized> DerefMut for RwLockWriteGuard<'_, T> {
        fn deref_mut(&mut self) -> &mut T {
-               self.lock.deref_mut()
+               self.guard.deref_mut()
        }
 }
 
 impl<T> RwLock<T> {
        pub fn new(inner: T) -> RwLock<T> {
-               RwLock { inner: StdRwLock::new(inner) }
+               RwLock { inner: StdRwLock::new(inner), deps: Arc::new(LockMetadata::new()) }
        }
 
        pub fn read<'a>(&'a self) -> LockResult<RwLockReadGuard<'a, T>> {
-               self.inner.read().map(|lock| RwLockReadGuard { lock }).map_err(|_| ())
+               let first_lock = LockMetadata::pre_read_lock(&self.deps);
+               self.inner.read().map(|guard| RwLockReadGuard { lock: self, guard, first_lock }).map_err(|_| ())
        }
 
        pub fn write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
-               self.inner.write().map(|lock| RwLockWriteGuard { lock }).map_err(|_| ())
+               LockMetadata::pre_lock(&self.deps);
+               self.inner.write().map(|guard| RwLockWriteGuard { lock: self, guard }).map_err(|_| ())
        }
 
        pub fn try_write<'a>(&'a self) -> LockResult<RwLockWriteGuard<'a, T>> {
-               self.inner.try_write().map(|lock| RwLockWriteGuard { lock }).map_err(|_| ())
+               let res = self.inner.try_write().map(|guard| RwLockWriteGuard { lock: self, guard }).map_err(|_| ());
+               if res.is_ok() {
+                       LockMetadata::try_locked(&self.deps);
+               }
+               res
+       }
+}
+
+#[test]
+#[should_panic]
+fn recursive_lock_fail() {
+       let mutex = Mutex::new(());
+       let _a = mutex.lock().unwrap();
+       let _b = mutex.lock().unwrap();
+}
+
+#[test]
+fn recursive_read() {
+       let lock = RwLock::new(());
+       let _a = lock.read().unwrap();
+       let _b = lock.read().unwrap();
+}
+
+#[test]
+#[should_panic]
+fn lockorder_fail() {
+       let a = Mutex::new(());
+       let b = Mutex::new(());
+       {
+               let _a = a.lock().unwrap();
+               let _b = b.lock().unwrap();
+       }
+       {
+               let _b = b.lock().unwrap();
+               let _a = a.lock().unwrap();
+       }
+}
+
+#[test]
+#[should_panic]
+fn write_lockorder_fail() {
+       let a = RwLock::new(());
+       let b = RwLock::new(());
+       {
+               let _a = a.write().unwrap();
+               let _b = b.write().unwrap();
+       }
+       {
+               let _b = b.write().unwrap();
+               let _a = a.write().unwrap();
+       }
+}
+
+#[test]
+#[should_panic]
+fn read_lockorder_fail() {
+       let a = RwLock::new(());
+       let b = RwLock::new(());
+       {
+               let _a = a.read().unwrap();
+               let _b = b.read().unwrap();
+       }
+       {
+               let _b = b.read().unwrap();
+               let _a = a.read().unwrap();
+       }
+}
+
+#[test]
+fn read_recurisve_no_lockorder() {
+       // Like the above, but note that no lockorder is implied when we recursively read-lock a
+       // RwLock, causing this to pass just fine.
+       let a = RwLock::new(());
+       let b = RwLock::new(());
+       let _outer = a.read().unwrap();
+       {
+               let _a = a.read().unwrap();
+               let _b = b.read().unwrap();
+       }
+       {
+               let _b = b.read().unwrap();
+               let _a = a.read().unwrap();
+       }
+}
+
+#[test]
+#[should_panic]
+fn read_write_lockorder_fail() {
+       let a = RwLock::new(());
+       let b = RwLock::new(());
+       {
+               let _a = a.write().unwrap();
+               let _b = b.read().unwrap();
+       }
+       {
+               let _b = b.read().unwrap();
+               let _a = a.write().unwrap();
        }
 }
index a6c5649c1d954e5b76f7efe8e28dd675d9d76c31..ec06af2a2ace852bf6c2c4c3aaafdd2864785c5e 100644 (file)
@@ -334,10 +334,10 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
                nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
                nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
 
-               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
                let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
                assert_eq!(reestablish_1.len(), 1);
-               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
                let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
                assert_eq!(reestablish_2.len(), 1);
 
@@ -356,10 +356,10 @@ fn do_test_monitor_temporary_update_fail(disconnect_count: usize) {
                assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
                assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
-               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
                let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
                assert_eq!(reestablish_1.len(), 1);
-               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
                let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
                assert_eq!(reestablish_2.len(), 1);
 
@@ -1108,8 +1108,8 @@ fn test_monitor_update_fail_reestablish() {
        commitment_signed_dance!(nodes[1], nodes[2], updates.commitment_signed, false);
 
        chanmon_cfgs[1].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure));
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
 
        let as_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
        let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
@@ -1127,8 +1127,8 @@ fn test_monitor_update_fail_reestablish() {
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
 
        assert!(as_reestablish == get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id()));
        assert!(bs_reestablish == get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id()));
@@ -1300,8 +1300,8 @@ fn claim_while_disconnected_monitor_update_fail() {
        assert!(nodes[1].node.claim_funds(payment_preimage_1));
        check_added_monitors!(nodes[1], 1);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
 
        let as_reconnect = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
        let bs_reconnect = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
@@ -1432,8 +1432,8 @@ fn monitor_failed_no_reestablish_response() {
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
 
        let as_reconnect = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
        let bs_reconnect = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
@@ -2012,9 +2012,9 @@ fn test_pending_update_fee_ack_on_reconnect() {
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
        let as_connect_msg = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
        let bs_connect_msg = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_connect_msg);
@@ -2094,9 +2094,9 @@ fn do_update_fee_resend_test(deliver_update: bool, parallel_updates: bool) {
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
        let as_connect_msg = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
        let bs_connect_msg = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_connect_msg);
@@ -2258,10 +2258,10 @@ fn do_channel_holding_cell_serialize(disconnect: bool, reload_a: bool) {
                nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
 
                // Now reconnect the two
-               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+               nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
                let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
                assert_eq!(reestablish_1.len(), 1);
-               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+               nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
                let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
                assert_eq!(reestablish_2.len(), 1);
 
index 10404195c955325ff33e6e9e2b07be87c2e51c8a..0d1ee4fb07cae6ad2cad127382764a8b1da939c9 100644 (file)
@@ -441,6 +441,7 @@ struct ClaimableHTLC {
        cltv_expiry: u32,
        value: u64,
        onion_payload: OnionPayload,
+       timer_ticks: u8,
 }
 
 /// A payment identifier used to uniquely identify a payment to LDK.
@@ -886,6 +887,8 @@ impl PendingOutboundPayment {
 /// issues such as overly long function definitions. Note that the ChannelManager can take any
 /// type that implements KeysInterface for its keys manager, but this type alias chooses the
 /// concrete type of the KeysManager.
+///
+/// (C-not exported) as Arcs don't make sense in bindings
 pub type SimpleArcChannelManager<M, T, F, L> = ChannelManager<InMemorySigner, Arc<M>, Arc<T>, Arc<KeysManager>, Arc<F>, Arc<L>>;
 
 /// SimpleRefChannelManager is a type alias for a ChannelManager reference, and is the reference
@@ -896,6 +899,8 @@ pub type SimpleArcChannelManager<M, T, F, L> = ChannelManager<InMemorySigner, Ar
 /// helps with issues such as long function definitions. Note that the ChannelManager can take any
 /// type that implements KeysInterface for its keys manager, but this type alias chooses the
 /// concrete type of the KeysManager.
+///
+/// (C-not exported) as Arcs don't make sense in bindings
 pub type SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L> = ChannelManager<InMemorySigner, &'a M, &'b T, &'c KeysManager, &'d F, &'e L>;
 
 /// Manager which keeps track of a number of channels and sends messages to the appropriate
@@ -1148,6 +1153,9 @@ const CHECK_CLTV_EXPIRY_SANITY_2: u32 = MIN_CLTV_EXPIRY_DELTA as u32 - LATENCY_G
 /// pending HTLCs in flight.
 pub(crate) const PAYMENT_EXPIRY_BLOCKS: u32 = 3;
 
+/// The number of ticks of [`ChannelManager::timer_tick_occurred`] until expiry of incomplete MPPs
+pub(crate) const MPP_TIMEOUT_TICKS: u8 = 3;
+
 /// Information needed for constructing an invoice route hint for this channel.
 #[derive(Clone, Debug, PartialEq)]
 pub struct CounterpartyForwardingInfo {
@@ -3326,6 +3334,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                                                                                phantom_shared_secret,
                                                                        },
                                                                        value: amt_to_forward,
+                                                                       timer_ticks: 0,
                                                                        cltv_expiry,
                                                                        onion_payload,
                                                                };
@@ -3620,6 +3629,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
                        let new_feerate = self.fee_estimator.get_est_sat_per_1000_weight(ConfirmationTarget::Normal);
 
                        let mut handle_errors = Vec::new();
+                       let mut timed_out_mpp_htlcs = Vec::new();
                        {
                                let mut channel_state_lock = self.channel_state.lock().unwrap();
                                let channel_state = &mut *channel_state_lock;
@@ -3668,6 +3678,32 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
 
                                        true
                                });
+
+                               channel_state.claimable_htlcs.retain(|payment_hash, htlcs| {
+                                       if htlcs.is_empty() {
+                                               // This should be unreachable
+                                               debug_assert!(false);
+                                               return false;
+                                       }
+                                       if let OnionPayload::Invoice(ref final_hop_data) = htlcs[0].onion_payload {
+                                               // Check if we've received all the parts we need for an MPP (the value of the parts adds to total_msat).
+                                               // In this case we're not going to handle any timeouts of the parts here.
+                                               if final_hop_data.total_msat == htlcs.iter().fold(0, |total, htlc| total + htlc.value) {
+                                                       return true;
+                                               } else if htlcs.into_iter().any(|htlc| {
+                                                       htlc.timer_ticks += 1;
+                                                       return htlc.timer_ticks >= MPP_TIMEOUT_TICKS
+                                               }) {
+                                                       timed_out_mpp_htlcs.extend(htlcs.into_iter().map(|htlc| (htlc.prev_hop.clone(), payment_hash.clone())));
+                                                       return false;
+                                               }
+                                       }
+                                       true
+                               });
+                       }
+
+                       for htlc_source in timed_out_mpp_htlcs.drain(..) {
+                               self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), HTLCSource::PreviousHopData(htlc_source.0), &htlc_source.1, HTLCFailReason::Reason { failure_code: 23, data: Vec::new() });
                        }
 
                        for (err, counterparty_node_id) in handle_errors.drain(..) {
@@ -5899,6 +5935,7 @@ impl<Signer: Sign, M: Deref , T: Deref , K: Deref , F: Deref , L: Deref >
                                        &events::MessageSendEvent::SendChannelRangeQuery { .. } => false,
                                        &events::MessageSendEvent::SendShortIdsQuery { .. } => false,
                                        &events::MessageSendEvent::SendReplyChannelRange { .. } => false,
+                                       &events::MessageSendEvent::SendGossipTimestampFilter { .. } => false,
                                }
                        });
                }
@@ -6239,6 +6276,7 @@ impl Readable for ClaimableHTLC {
                };
                Ok(Self {
                        prev_hop: prev_hop.0.unwrap(),
+                       timer_ticks: 0,
                        value,
                        onion_payload,
                        cltv_expiry,
@@ -7313,8 +7351,8 @@ mod tests {
 
                let payer_pubkey = nodes[0].node.get_our_node_id();
                let payee_pubkey = nodes[1].node.get_our_node_id();
-               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known() });
-               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
+               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
 
                let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
                let route_params = RouteParameters {
@@ -7357,8 +7395,8 @@ mod tests {
 
                let payer_pubkey = nodes[0].node.get_our_node_id();
                let payee_pubkey = nodes[1].node.get_our_node_id();
-               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known() });
-               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
+               nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+               nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
 
                let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
                let route_params = RouteParameters {
@@ -7523,8 +7561,8 @@ pub mod bench {
                });
                let node_b_holder = NodeHolder { node: &node_b };
 
-               node_a.peer_connected(&node_b.get_our_node_id(), &Init { features: InitFeatures::known() });
-               node_b.peer_connected(&node_a.get_our_node_id(), &Init { features: InitFeatures::known() });
+               node_a.peer_connected(&node_b.get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
+               node_b.peer_connected(&node_a.get_our_node_id(), &Init { features: InitFeatures::known(), remote_network_address: None });
                node_a.create_channel(node_b.get_our_node_id(), 8_000_000, 100_000_000, 42, None).unwrap();
                node_b.handle_open_channel(&node_a.get_our_node_id(), InitFeatures::known(), &get_event_msg!(node_a_holder, MessageSendEvent::SendOpenChannel, node_b.get_our_node_id()));
                node_a.handle_accept_channel(&node_b.get_our_node_id(), InitFeatures::known(), &get_event_msg!(node_b_holder, MessageSendEvent::SendAcceptChannel, node_a.get_our_node_id()));
index 5901efbf95cf47fbceabb97d77dcd94abfcd543f..7088149515d529877659716882f56da06bb80d30 100644 (file)
@@ -1877,8 +1877,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
 
        for i in 0..node_count {
                for j in (i+1)..node_count {
-                       nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &msgs::Init { features: cfgs[j].features.clone() });
-                       nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &msgs::Init { features: cfgs[i].features.clone() });
+                       nodes[i].node.peer_connected(&nodes[j].node.get_our_node_id(), &msgs::Init { features: cfgs[j].features.clone(), remote_network_address: None });
+                       nodes[j].node.peer_connected(&nodes[i].node.get_our_node_id(), &msgs::Init { features: cfgs[i].features.clone(), remote_network_address: None });
                }
        }
 
@@ -2137,9 +2137,9 @@ macro_rules! handle_chan_reestablish_msgs {
 /// pending_htlc_adds includes both the holding cell and in-flight update_add_htlcs, whereas
 /// for claims/fails they are separated out.
 pub fn reconnect_nodes<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, send_funding_locked: (bool, bool), pending_htlc_adds: (i64, i64), pending_htlc_claims: (usize, usize), pending_htlc_fails: (usize, usize), pending_cell_htlc_claims: (usize, usize), pending_cell_htlc_fails: (usize, usize), pending_raa: (bool, bool))  {
-       node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       node_a.node.peer_connected(&node_b.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_1 = get_chan_reestablish_msgs!(node_a, node_b);
-       node_b.node.peer_connected(&node_a.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       node_b.node.peer_connected(&node_a.node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_2 = get_chan_reestablish_msgs!(node_b, node_a);
 
        if send_funding_locked.0 {
index 85007e0e5b90b7c8497e709a611cee589a6c6766..05d42fba28bbd5980a92c398dd12254f60dec122 100644 (file)
@@ -3779,9 +3779,9 @@ fn test_funding_peer_disconnect() {
        let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
        assert!(events_2.is_empty());
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let as_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
 
        // nodes[0] hasn't yet received a funding_locked, so it only sends that on reconnect.
@@ -4026,10 +4026,10 @@ fn test_drop_messages_peer_disconnect_dual_htlc() {
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
        assert_eq!(reestablish_1.len(), 1);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
        assert_eq!(reestablish_2.len(), 1);
 
@@ -4305,9 +4305,9 @@ fn test_no_txn_manager_serialize_deserialize() {
        assert_eq!(nodes[0].node.list_channels().len(), 1);
        check_added_monitors!(nodes[0], 1);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]);
@@ -4425,9 +4425,9 @@ fn test_manager_serialize_deserialize_events() {
        assert_eq!(nodes[0].node.list_channels().len(), 1);
        check_added_monitors!(nodes[0], 1);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &reestablish_1[0]);
@@ -4620,9 +4620,9 @@ fn test_manager_serialize_deserialize_inconsistent_monitor() {
        //... and we can even still claim the payment!
        claim_payment(&nodes[2], &[&nodes[0], &nodes[1]], our_payment_preimage);
 
-       nodes[3].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[3].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish = get_event_msg!(nodes[3], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
-       nodes[0].node.peer_connected(&nodes[3].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[3].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        nodes[0].node.handle_channel_reestablish(&nodes[3].node.get_our_node_id(), &reestablish);
        let msg_events = nodes[0].node.get_and_clear_pending_msg_events();
        assert_eq!(msg_events.len(), 1);
@@ -6681,10 +6681,10 @@ fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() {
        //Disconnect and Reconnect
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
        assert_eq!(reestablish_1.len(), 1);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
        assert_eq!(reestablish_2.len(), 1);
        nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &reestablish_2[0]);
@@ -7329,8 +7329,8 @@ fn test_data_loss_protect() {
 
        check_added_monitors!(nodes[0], 1);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
 
        let reestablish_0 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
 
@@ -7478,10 +7478,10 @@ fn test_announce_disable_channels() {
                }
        }
        // Reconnect peers
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
        assert_eq!(reestablish_1.len(), 3);
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
        assert_eq!(reestablish_2.len(), 3);
 
@@ -9514,8 +9514,8 @@ fn test_keysend_payments_to_private_node() {
 
        let payer_pubkey = nodes[0].node.get_our_node_id();
        let payee_pubkey = nodes[1].node.get_our_node_id();
-       nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known() });
-       nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known() });
+       nodes[0].node.peer_connected(&payee_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+       nodes[1].node.peer_connected(&payer_pubkey, &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
 
        let _chan = create_chan_between_nodes(&nodes[0], &nodes[1], InitFeatures::known(), InitFeatures::known());
        let route_params = RouteParameters {
index fab396e3c7112af934021041abfcf2e1f4d609af..ef07d4c918f8597f28a6b3df90aeaded15b06bb9 100644 (file)
@@ -75,6 +75,11 @@ pub enum DecodeError {
 pub struct Init {
        /// The relevant features which the sender supports
        pub features: InitFeatures,
+       /// The receipient's network address. This adds the option to report a remote IP address
+       /// back to a connecting peer using the init message. A node can decide to use that information
+       /// to discover a potential update to its public IPv4 address (NAT) and use
+       /// that for a node_announcement update message containing the new address.
+       pub remote_network_address: Option<NetAddress>,
 }
 
 /// An error message to be sent or received from a peer
@@ -886,7 +891,7 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
        /// Called when a connection is established with a peer. This can be used to
        /// perform routing table synchronization using a strategy defined by the
        /// implementor.
-       fn sync_routing_table(&self, their_node_id: &PublicKey, init: &Init);
+       fn peer_connected(&self, their_node_id: &PublicKey, init: &Init);
        /// Handles the reply of a query we initiated to learn about channels
        /// for a given range of blocks. We can expect to receive one or more
        /// replies to a single query.
@@ -1167,7 +1172,11 @@ impl Writeable for Init {
                // global_features gets the bottom 13 bits of our features, and local_features gets all of
                // our relevant feature bits. This keeps us compatible with old nodes.
                self.features.write_up_to_13(w)?;
-               self.features.write(w)
+               self.features.write(w)?;
+               encode_tlv_stream!(w, {
+                       (3, self.remote_network_address, option)
+               });
+               Ok(())
        }
 }
 
@@ -1175,8 +1184,13 @@ impl Readable for Init {
        fn read<R: Read>(r: &mut R) -> Result<Self, DecodeError> {
                let global_features: InitFeatures = Readable::read(r)?;
                let features: InitFeatures = Readable::read(r)?;
+               let mut remote_network_address: Option<NetAddress> = None;
+               decode_tlv_stream!(r, {
+                       (3, remote_network_address, option)
+               });
                Ok(Init {
                        features: features.or(global_features),
+                       remote_network_address,
                })
        }
 }
@@ -2447,13 +2461,27 @@ mod tests {
        fn encoding_init() {
                assert_eq!(msgs::Init {
                        features: InitFeatures::from_le_bytes(vec![0xFF, 0xFF, 0xFF]),
+                       remote_network_address: None,
                }.encode(), hex::decode("00023fff0003ffffff").unwrap());
                assert_eq!(msgs::Init {
                        features: InitFeatures::from_le_bytes(vec![0xFF]),
+                       remote_network_address: None,
                }.encode(), hex::decode("0001ff0001ff").unwrap());
                assert_eq!(msgs::Init {
                        features: InitFeatures::from_le_bytes(vec![]),
+                       remote_network_address: None,
                }.encode(), hex::decode("00000000").unwrap());
+
+               let init_msg = msgs::Init { features: InitFeatures::from_le_bytes(vec![]),
+                       remote_network_address: Some(msgs::NetAddress::IPv4 {
+                               addr: [127, 0, 0, 1],
+                               port: 1000,
+                       }),
+               };
+               let encoded_value = init_msg.encode();
+               let target_value = hex::decode("000000000307017f00000103e8").unwrap();
+               assert_eq!(encoded_value, target_value);
+               assert_eq!(msgs::Init::read(&mut Cursor::new(&target_value)).unwrap(), init_msg);
        }
 
        #[test]
index bae9a2914fa8014a87b8a97015bc010d5580a366..346fb98b41eda3d895f9887575764db0ecc44503 100644 (file)
@@ -15,7 +15,7 @@ use chain::{ChannelMonitorUpdateErr, Confirm, Listen, Watch};
 use chain::channelmonitor::{ANTI_REORG_DELAY, ChannelMonitor, LATENCY_GRACE_PERIOD_BLOCKS};
 use chain::transaction::OutPoint;
 use chain::keysinterface::KeysInterface;
-use ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, ChannelManagerReadArgs, PaymentId, PaymentSendFailure};
+use ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, ChannelManagerReadArgs, MPP_TIMEOUT_TICKS, PaymentId, PaymentSendFailure};
 use ln::features::{InitFeatures, InvoiceFeatures};
 use ln::msgs;
 use ln::msgs::ChannelMessageHandler;
@@ -199,6 +199,78 @@ fn mpp_retry() {
        claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage);
 }
 
+fn do_mpp_receive_timeout(send_partial_mpp: bool) {
+       let chanmon_cfgs = create_chanmon_cfgs(4);
+       let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
+       let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
+       let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
+
+       let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
+       let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
+       let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
+       let chan_4_id = create_announced_chan_between_nodes(&nodes, 2, 3, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
+
+       let (mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[3], 100_000);
+       let path = route.paths[0].clone();
+       route.paths.push(path);
+       route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
+       route.paths[0][0].short_channel_id = chan_1_id;
+       route.paths[0][1].short_channel_id = chan_3_id;
+       route.paths[1][0].pubkey = nodes[2].node.get_our_node_id();
+       route.paths[1][0].short_channel_id = chan_2_id;
+       route.paths[1][1].short_channel_id = chan_4_id;
+
+       // Initiate the MPP payment.
+       let _ = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
+       check_added_monitors!(nodes[0], 2); // one monitor per path
+       let mut events = nodes[0].node.get_and_clear_pending_msg_events();
+       assert_eq!(events.len(), 2);
+
+       // Pass half of the payment along the first path.
+       pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 200_000, payment_hash, Some(payment_secret), events.remove(0), false, None);
+
+       if send_partial_mpp {
+               // Time out the partial MPP
+               for _ in 0..MPP_TIMEOUT_TICKS {
+                       nodes[3].node.timer_tick_occurred();
+               }
+
+               // Failed HTLC from node 3 -> 1
+               expect_pending_htlcs_forwardable!(nodes[3]);
+               let htlc_fail_updates_3_1 = get_htlc_update_msgs!(nodes[3], nodes[1].node.get_our_node_id());
+               assert_eq!(htlc_fail_updates_3_1.update_fail_htlcs.len(), 1);
+               nodes[1].node.handle_update_fail_htlc(&nodes[3].node.get_our_node_id(), &htlc_fail_updates_3_1.update_fail_htlcs[0]);
+               check_added_monitors!(nodes[3], 1);
+               commitment_signed_dance!(nodes[1], nodes[3], htlc_fail_updates_3_1.commitment_signed, false);
+
+               // Failed HTLC from node 1 -> 0
+               expect_pending_htlcs_forwardable!(nodes[1]);
+               let htlc_fail_updates_1_0 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
+               assert_eq!(htlc_fail_updates_1_0.update_fail_htlcs.len(), 1);
+               nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &htlc_fail_updates_1_0.update_fail_htlcs[0]);
+               check_added_monitors!(nodes[1], 1);
+               commitment_signed_dance!(nodes[0], nodes[1], htlc_fail_updates_1_0.commitment_signed, false);
+
+               expect_payment_failed_conditions!(nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain().expected_htlc_error_data(23, &[][..]));
+       } else {
+               // Pass half of the payment along the second path.
+               pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 200_000, payment_hash, Some(payment_secret), events.remove(0), true, None);
+
+               // Even after MPP_TIMEOUT_TICKS we should not timeout the MPP if we have all the parts
+               for _ in 0..MPP_TIMEOUT_TICKS {
+                       nodes[3].node.timer_tick_occurred();
+               }
+
+               claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage);
+       }
+}
+
+#[test]
+fn mpp_receive_timeout() {
+       do_mpp_receive_timeout(true);
+       do_mpp_receive_timeout(false);
+}
+
 #[test]
 fn retry_expired_payment() {
        let chanmon_cfgs = create_chanmon_cfgs(3);
@@ -377,12 +449,12 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
        assert_eq!(as_broadcasted_txn[0], as_commitment_tx);
 
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known()});
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
        assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
 
        // Now nodes[1] should send a channel reestablish, which nodes[0] will respond to with an
        // error, as the channel has hit the chain.
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known()});
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
        let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
        nodes[0].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
        let as_err = nodes[0].node.get_and_clear_pending_msg_events();
index d3ac2ebe9a39bf2e918f58dbf4d012ac0434ae99..d12f8c06eed0409630864359e54c20d3b714930d 100644 (file)
@@ -19,7 +19,7 @@ use bitcoin::secp256k1::key::{SecretKey,PublicKey};
 
 use ln::features::InitFeatures;
 use ln::msgs;
-use ln::msgs::{ChannelMessageHandler, LightningError, RoutingMessageHandler};
+use ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, RoutingMessageHandler};
 use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager};
 use util::ser::{VecWriter, Writeable, Writer};
 use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep};
@@ -69,7 +69,7 @@ impl RoutingMessageHandler for IgnoringMessageHandler {
        fn get_next_channel_announcements(&self, _starting_point: u64, _batch_amount: u8) ->
                Vec<(msgs::ChannelAnnouncement, Option<msgs::ChannelUpdate>, Option<msgs::ChannelUpdate>)> { Vec::new() }
        fn get_next_node_announcements(&self, _starting_point: Option<&PublicKey>, _batch_amount: u8) -> Vec<msgs::NodeAnnouncement> { Vec::new() }
-       fn sync_routing_table(&self, _their_node_id: &PublicKey, _init: &msgs::Init) {}
+       fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init) {}
        fn handle_reply_channel_range(&self, _their_node_id: &PublicKey, _msg: msgs::ReplyChannelRange) -> Result<(), LightningError> { Ok(()) }
        fn handle_reply_short_channel_ids_end(&self, _their_node_id: &PublicKey, _msg: msgs::ReplyShortChannelIdsEnd) -> Result<(), LightningError> { Ok(()) }
        fn handle_query_channel_range(&self, _their_node_id: &PublicKey, _msg: msgs::QueryChannelRange) -> Result<(), LightningError> { Ok(()) }
@@ -324,6 +324,7 @@ struct Peer {
        channel_encryptor: PeerChannelEncryptor,
        their_node_id: Option<PublicKey>,
        their_features: Option<InitFeatures>,
+       their_net_address: Option<NetAddress>,
 
        pending_outbound_buffer: LinkedList<Vec<u8>>,
        pending_outbound_buffer_first_msg_offset: usize,
@@ -376,6 +377,8 @@ struct PeerHolder<Descriptor: SocketDescriptor> {
 /// lifetimes). Other times you can afford a reference, which is more efficient, in which case
 /// SimpleRefPeerManager is the more appropriate type. Defining these type aliases prevents
 /// issues such as overly long function definitions.
+///
+/// (C-not exported) as Arcs don't make sense in bindings
 pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArcChannelManager<M, T, F, L>>, Arc<NetGraphMsgHandler<Arc<NetworkGraph>, Arc<C>, Arc<L>>>, Arc<L>, Arc<IgnoringMessageHandler>>;
 
 /// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference
@@ -384,6 +387,8 @@ pub type SimpleArcPeerManager<SD, M, T, F, C, L> = PeerManager<SD, Arc<SimpleArc
 /// usage of lightning-net-tokio (since tokio::spawn requires parameters with static lifetimes).
 /// But if this is not necessary, using a reference is more efficient. Defining these type aliases
 /// helps with issues such as long function definitions.
+///
+/// (C-not exported) as Arcs don't make sense in bindings
 pub type SimpleRefPeerManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, SD, M, T, F, C, L> = PeerManager<SD, SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, M, T, F, L>, &'e NetGraphMsgHandler<&'g NetworkGraph, &'h C, &'f L>, &'f L, IgnoringMessageHandler>;
 
 /// A PeerManager manages a set of peers, described by their [`SocketDescriptor`] and marshalls
@@ -495,6 +500,36 @@ impl core::fmt::Display for OptionalFromDebugger<'_> {
        }
 }
 
+/// A function used to filter out local or private addresses
+/// https://www.iana.org./assignments/ipv4-address-space/ipv4-address-space.xhtml
+/// https://www.iana.org/assignments/ipv6-address-space/ipv6-address-space.xhtml
+fn filter_addresses(ip_address: Option<NetAddress>) -> Option<NetAddress> {
+       match ip_address{
+               // For IPv4 range 10.0.0.0 - 10.255.255.255 (10/8)
+               Some(NetAddress::IPv4{addr: [10, _, _, _], port: _}) => None,
+               // For IPv4 range 0.0.0.0 - 0.255.255.255 (0/8)
+               Some(NetAddress::IPv4{addr: [0, _, _, _], port: _}) => None,
+               // For IPv4 range 100.64.0.0 - 100.127.255.255 (100.64/10)
+               Some(NetAddress::IPv4{addr: [100, 64..=127, _, _], port: _}) => None,
+               // For IPv4 range       127.0.0.0 - 127.255.255.255 (127/8)
+               Some(NetAddress::IPv4{addr: [127, _, _, _], port: _}) => None,
+               // For IPv4 range       169.254.0.0 - 169.254.255.255 (169.254/16)
+               Some(NetAddress::IPv4{addr: [169, 254, _, _], port: _}) => None,
+               // For IPv4 range 172.16.0.0 - 172.31.255.255 (172.16/12)
+               Some(NetAddress::IPv4{addr: [172, 16..=31, _, _], port: _}) => None,
+               // For IPv4 range 192.168.0.0 - 192.168.255.255 (192.168/16)
+               Some(NetAddress::IPv4{addr: [192, 168, _, _], port: _}) => None,
+               // For IPv4 range 192.88.99.0 - 192.88.99.255  (192.88.99/24)
+               Some(NetAddress::IPv4{addr: [192, 88, 99, _], port: _}) => None,
+               // For IPv6 range 2000:0000:0000:0000:0000:0000:0000:0000 - 3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff (2000::/3)
+               Some(NetAddress::IPv6{addr: [0x20..=0x3F, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _], port: _}) => ip_address,
+               // For remaining addresses
+               Some(NetAddress::IPv6{addr: _, port: _}) => None,
+               Some(..) => ip_address,
+               None => None,
+       }
+}
+
 impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> PeerManager<Descriptor, CM, RM, L, CMH> where
                CM::Target: ChannelMessageHandler,
                RM::Target: RoutingMessageHandler,
@@ -543,7 +578,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
                SecretKey::from_slice(&Sha256::from_engine(ephemeral_hash).into_inner()).expect("You broke SHA-256!")
        }
 
-       /// Indicates a new outbound connection has been established to a node with the given node_id.
+       /// Indicates a new outbound connection has been established to a node with the given node_id
+       /// and an optional remote network address.
+       ///
+       /// The remote network address adds the option to report a remote IP address back to a connecting
+       /// peer using the init message.
+       /// The user should pass the remote network address of the host they are connected to.
+       ///
        /// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
        /// descriptor but must disconnect the connection immediately.
        ///
@@ -553,7 +594,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
        /// [`socket_disconnected()`].
        ///
        /// [`socket_disconnected()`]: PeerManager::socket_disconnected
-       pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
+       pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor, remote_network_address: Option<NetAddress>) -> Result<Vec<u8>, PeerHandleError> {
                let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
                let res = peer_encryptor.get_act_one().to_vec();
                let pending_read_buffer = [0; 50].to_vec(); // Noise act two is 50 bytes
@@ -563,6 +604,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
                        channel_encryptor: peer_encryptor,
                        their_node_id: None,
                        their_features: None,
+                       their_net_address: remote_network_address,
 
                        pending_outbound_buffer: LinkedList::new(),
                        pending_outbound_buffer_first_msg_offset: 0,
@@ -583,7 +625,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
                Ok(res)
        }
 
-       /// Indicates a new inbound connection has been established.
+       /// Indicates a new inbound connection has been established to a node with an optional remote
+       /// network address.
+       ///
+       /// The remote network address adds the option to report a remote IP address back to a connecting
+       /// peer using the init message.
+       /// The user should pass the remote network address of the host they are connected to.
        ///
        /// May refuse the connection by returning an Err, but will never write bytes to the remote end
        /// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
@@ -594,7 +641,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
        /// [`socket_disconnected()`].
        ///
        /// [`socket_disconnected()`]: PeerManager::socket_disconnected
-       pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
+       pub fn new_inbound_connection(&self, descriptor: Descriptor, remote_network_address: Option<NetAddress>) -> Result<(), PeerHandleError> {
                let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
                let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
 
@@ -603,6 +650,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
                        channel_encryptor: peer_encryptor,
                        their_node_id: None,
                        their_features: None,
+                       their_net_address: remote_network_address,
 
                        pending_outbound_buffer: LinkedList::new(),
                        pending_outbound_buffer_first_msg_offset: 0,
@@ -864,7 +912,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
                                                                        peer.their_node_id = Some(their_node_id);
                                                                        insert_node_id!();
                                                                        let features = InitFeatures::known();
-                                                                       let resp = msgs::Init { features };
+                                                                       let resp = msgs::Init { features, remote_network_address: filter_addresses(peer.their_net_address.clone())};
                                                                        self.enqueue_message(peer, &resp);
                                                                        peer.awaiting_pong_timer_tick_intervals = 0;
                                                                },
@@ -875,7 +923,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
                                                                        peer.their_node_id = Some(their_node_id);
                                                                        insert_node_id!();
                                                                        let features = InitFeatures::known();
-                                                                       let resp = msgs::Init { features };
+                                                                       let resp = msgs::Init { features, remote_network_address: filter_addresses(peer.their_net_address.clone())};
                                                                        self.enqueue_message(peer, &resp);
                                                                        peer.awaiting_pong_timer_tick_intervals = 0;
                                                                },
@@ -1018,7 +1066,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
                                        return Err(PeerHandleError{ no_connection_possible: true }.into());
                                }
 
-                               self.message_handler.route_handler.sync_routing_table(&peer.their_node_id.unwrap(), &msg);
+                               self.message_handler.route_handler.peer_connected(&peer.their_node_id.unwrap(), &msg);
 
                                self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg);
                                peer.their_features = Some(msg.features);
@@ -1477,6 +1525,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
                                                        msg.sync_complete);
                                                self.enqueue_message(get_peer_for_forwarding!(node_id), msg);
                                        }
+                                       MessageSendEvent::SendGossipTimestampFilter { ref node_id, ref msg } => {
+                                               self.enqueue_message(get_peer_for_forwarding!(node_id), msg);
+                                       }
                                }
                        }
 
@@ -1663,8 +1714,9 @@ fn is_gossip_msg(type_id: u16) -> bool {
 
 #[cfg(test)]
 mod tests {
-       use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler};
+       use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor, IgnoringMessageHandler, filter_addresses};
        use ln::msgs;
+       use ln::msgs::NetAddress;
        use util::events;
        use util::test_utils;
 
@@ -1740,8 +1792,8 @@ mod tests {
                let a_id = PublicKey::from_secret_key(&secp_ctx, &peer_a.our_node_secret);
                let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
                let mut fd_b = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
-               let initial_data = peer_b.new_outbound_connection(a_id, fd_b.clone()).unwrap();
-               peer_a.new_inbound_connection(fd_a.clone()).unwrap();
+               let initial_data = peer_b.new_outbound_connection(a_id, fd_b.clone(), None).unwrap();
+               peer_a.new_inbound_connection(fd_a.clone(), None).unwrap();
                assert_eq!(peer_a.read_event(&mut fd_a, &initial_data).unwrap(), false);
                peer_a.process_events();
                assert_eq!(peer_b.read_event(&mut fd_b, &fd_a.outbound_data.lock().unwrap().split_off(0)).unwrap(), false);
@@ -1848,8 +1900,8 @@ mod tests {
                let a_id = PublicKey::from_secret_key(&secp_ctx, &peers[0].our_node_secret);
                let mut fd_a = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
                let mut fd_b = FileDescriptor { fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())) };
-               let initial_data = peers[1].new_outbound_connection(a_id, fd_b.clone()).unwrap();
-               peers[0].new_inbound_connection(fd_a.clone()).unwrap();
+               let initial_data = peers[1].new_outbound_connection(a_id, fd_b.clone(), None).unwrap();
+               peers[0].new_inbound_connection(fd_a.clone(), None).unwrap();
 
                // If we get a single timer tick before completion, that's fine
                assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1);
@@ -1867,4 +1919,100 @@ mod tests {
 
                assert!(peers[0].read_event(&mut fd_a, &fd_b.outbound_data.lock().unwrap().split_off(0)).is_err());
        }
+
+       #[test]
+       fn test_filter_addresses(){
+               // Tests the filter_addresses function.
+
+               // For (10/8)
+               let ip_address = NetAddress::IPv4{addr: [10, 0, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [10, 0, 255, 201], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [10, 255, 255, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+               // For (0/8)
+               let ip_address = NetAddress::IPv4{addr: [0, 0, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [0, 0, 255, 187], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [0, 255, 255, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+               // For (100.64/10)
+               let ip_address = NetAddress::IPv4{addr: [100, 64, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [100, 78, 255, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [100, 127, 255, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+               // For (127/8)
+               let ip_address = NetAddress::IPv4{addr: [127, 0, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [127, 65, 73, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [127, 255, 255, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+               // For (169.254/16)
+               let ip_address = NetAddress::IPv4{addr: [169, 254, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [169, 254, 221, 101], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [169, 254, 255, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+               // For (172.16/12)
+               let ip_address = NetAddress::IPv4{addr: [172, 16, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [172, 27, 101, 23], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [172, 31, 255, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+               // For (192.168/16)
+               let ip_address = NetAddress::IPv4{addr: [192, 168, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [192, 168, 205, 159], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [192, 168, 255, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+               // For (192.88.99/24)
+               let ip_address = NetAddress::IPv4{addr: [192, 88, 99, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [192, 88, 99, 140], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv4{addr: [192, 88, 99, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+               // For other IPv4 addresses
+               let ip_address = NetAddress::IPv4{addr: [188, 255, 99, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+               let ip_address = NetAddress::IPv4{addr: [123, 8, 129, 14], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+               let ip_address = NetAddress::IPv4{addr: [2, 88, 9, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+
+               // For (2000::/3)
+               let ip_address = NetAddress::IPv6{addr: [32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+               let ip_address = NetAddress::IPv6{addr: [45, 34, 209, 190, 0, 123, 55, 34, 0, 0, 3, 27, 201, 0, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+               let ip_address = NetAddress::IPv6{addr: [63, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), Some(ip_address.clone()));
+
+               // For other IPv6 addresses
+               let ip_address = NetAddress::IPv6{addr: [24, 240, 12, 32, 0, 0, 0, 0, 20, 97, 0, 32, 121, 254, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv6{addr: [68, 23, 56, 63, 0, 0, 2, 7, 75, 109, 0, 39, 0, 0, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+               let ip_address = NetAddress::IPv6{addr: [101, 38, 140, 230, 100, 0, 30, 98, 0, 26, 0, 0, 57, 96, 0, 0], port: 1000};
+               assert_eq!(filter_addresses(Some(ip_address.clone())), None);
+
+               // For (None)
+               assert_eq!(filter_addresses(None), None);
+       }
 }
index a6f5a1b2ef7b8072a151deaeedb8bd27dd16f880..66c1b20d2de0179a83a414069a678921f01b8aa3 100644 (file)
@@ -132,8 +132,8 @@ fn test_priv_forwarding_rejection() {
        check_added_monitors!(nodes[1], 2);
        nodes[1].node = &nodes_1_deserialized;
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() });
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let as_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
        let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &as_reestablish);
@@ -141,8 +141,8 @@ fn test_priv_forwarding_rejection() {
        get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id());
        get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[0].node.get_our_node_id());
 
-       nodes[1].node.peer_connected(&nodes[2].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known() });
-       nodes[2].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[1].node.peer_connected(&nodes[2].node.get_our_node_id(), &msgs::Init { features: InitFeatures::known(), remote_network_address: None });
+       nodes[2].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let bs_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[2].node.get_our_node_id());
        let cs_reestablish = get_event_msg!(nodes[2], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
        nodes[2].node.handle_channel_reestablish(&nodes[1].node.get_our_node_id(), &bs_reestablish);
index cd0f77448a5d5c2c587286dcc7ec9612d5c9ad8c..557aff84c0dad7c6d595e4a6da6f1bcf24d6fced 100644 (file)
@@ -245,9 +245,9 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) {
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
 
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let node_0_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let node_1_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
 
        nodes[1].node.handle_channel_reestablish(&nodes[0].node.get_our_node_id(), &node_0_reestablish);
@@ -305,9 +305,9 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) {
        nodes[0].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
        nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), false);
 
-       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[1].node.peer_connected(&nodes[0].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        let node_1_2nd_reestablish = get_event_msg!(nodes[1], MessageSendEvent::SendChannelReestablish, nodes[0].node.get_our_node_id());
-       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty() });
+       nodes[0].node.peer_connected(&nodes[1].node.get_our_node_id(), &msgs::Init { features: InitFeatures::empty(), remote_network_address: None });
        if recv_count == 0 {
                // If all closing_signeds weren't delivered we can just resume where we left off...
                let node_0_2nd_reestablish = get_event_msg!(nodes[0], MessageSendEvent::SendChannelReestablish, nodes[1].node.get_our_node_id());
index d113acbfc7d4d5e50a17d2bea7012f67fa845285..e7db446a86f17f036ceeccba9aca52c4aa7ea652 100644 (file)
@@ -505,7 +505,7 @@ mod tests {
                let mut reader = io::Cursor::new(buffer);
                let decoded_msg = read(&mut reader, &IgnoringMessageHandler{}).unwrap();
                match decoded_msg {
-                       Message::Init(msgs::Init { features }) => {
+                       Message::Init(msgs::Init { features, .. }) => {
                                assert!(features.supports_variable_length_onion());
                                assert!(features.supports_upfront_shutdown_script());
                                assert!(features.supports_gossip_queries());
index a5e497bb1cf0f279137fd3f5e923e8972317181d..012357df361767e330a698f492846a6b44e8917b 100644 (file)
@@ -25,7 +25,7 @@ use chain;
 use chain::Access;
 use ln::features::{ChannelFeatures, NodeFeatures};
 use ln::msgs::{DecodeError, ErrorAction, Init, LightningError, RoutingMessageHandler, NetAddress, MAX_VALUE_MSAT};
-use ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, OptionalField};
+use ln::msgs::{ChannelAnnouncement, ChannelUpdate, NodeAnnouncement, OptionalField, GossipTimestampFilter};
 use ln::msgs::{QueryChannelRange, ReplyChannelRange, QueryShortChannelIds, ReplyShortChannelIdsEnd};
 use ln::msgs;
 use util::ser::{Writeable, Readable, Writer};
@@ -395,13 +395,28 @@ where C::Target: chain::Access, L::Target: Logger
        /// to request gossip messages for each channel. The sync is considered complete
        /// when the final reply_scids_end message is received, though we are not
        /// tracking this directly.
-       fn sync_routing_table(&self, their_node_id: &PublicKey, init_msg: &Init) {
-
+       fn peer_connected(&self, their_node_id: &PublicKey, init_msg: &Init) {
                // We will only perform a sync with peers that support gossip_queries.
                if !init_msg.features.supports_gossip_queries() {
                        return ();
                }
 
+               // Send a gossip_timestamp_filter to enable gossip message receipt. Note that we have to
+               // use a "all timestamps" filter as sending the current timestamp would result in missing
+               // gossip messages that are simply sent late. We could calculate the intended filter time
+               // by looking at the current time and subtracting two weeks (before which we'll reject
+               // messages), but there's not a lot of reason to bother - our peers should be discarding
+               // the same messages.
+               let mut pending_events = self.pending_events.lock().unwrap();
+               pending_events.push(MessageSendEvent::SendGossipTimestampFilter {
+                       node_id: their_node_id.clone(),
+                       msg: GossipTimestampFilter {
+                               chain_hash: self.network_graph.genesis_hash,
+                               first_timestamp: 0,
+                               timestamp_range: u32::max_value(),
+                       },
+               });
+
                // Check if we need to perform a full synchronization with this peer
                if !self.should_request_full_sync(&their_node_id) {
                        return ();
@@ -410,7 +425,6 @@ where C::Target: chain::Access, L::Target: Logger
                let first_blocknum = 0;
                let number_of_blocks = 0xffffffff;
                log_debug!(self.logger, "Sending query_channel_range peer={}, first_blocknum={}, number_of_blocks={}", log_pubkey!(their_node_id), first_blocknum, number_of_blocks);
-               let mut pending_events = self.pending_events.lock().unwrap();
                pending_events.push(MessageSendEvent::SendChannelRangeQuery {
                        node_id: their_node_id.clone(),
                        msg: QueryChannelRange {
@@ -2270,19 +2284,28 @@ mod tests {
 
                // It should ignore if gossip_queries feature is not enabled
                {
-                       let init_msg = Init { features: InitFeatures::known().clear_gossip_queries() };
-                       net_graph_msg_handler.sync_routing_table(&node_id_1, &init_msg);
+                       let init_msg = Init { features: InitFeatures::known().clear_gossip_queries(), remote_network_address: None };
+                       net_graph_msg_handler.peer_connected(&node_id_1, &init_msg);
                        let events = net_graph_msg_handler.get_and_clear_pending_msg_events();
                        assert_eq!(events.len(), 0);
                }
 
                // It should send a query_channel_message with the correct information
                {
-                       let init_msg = Init { features: InitFeatures::known() };
-                       net_graph_msg_handler.sync_routing_table(&node_id_1, &init_msg);
+                       let init_msg = Init { features: InitFeatures::known(), remote_network_address: None };
+                       net_graph_msg_handler.peer_connected(&node_id_1, &init_msg);
                        let events = net_graph_msg_handler.get_and_clear_pending_msg_events();
-                       assert_eq!(events.len(), 1);
+                       assert_eq!(events.len(), 2);
                        match &events[0] {
+                               MessageSendEvent::SendGossipTimestampFilter{ node_id, msg } => {
+                                       assert_eq!(node_id, &node_id_1);
+                                       assert_eq!(msg.chain_hash, chain_hash);
+                                       assert_eq!(msg.first_timestamp, 0);
+                                       assert_eq!(msg.timestamp_range, u32::max_value());
+                               },
+                               _ => panic!("Expected MessageSendEvent::SendChannelRangeQuery")
+                       };
+                       match &events[1] {
                                MessageSendEvent::SendChannelRangeQuery{ node_id, msg } => {
                                        assert_eq!(node_id, &node_id_1);
                                        assert_eq!(msg.chain_hash, chain_hash);
@@ -2299,16 +2322,18 @@ mod tests {
                {
                        let network_graph = create_network_graph();
                        let (secp_ctx, net_graph_msg_handler) = create_net_graph_msg_handler(&network_graph);
-                       let init_msg = Init { features: InitFeatures::known() };
+                       let init_msg = Init { features: InitFeatures::known(), remote_network_address: None };
                        for n in 1..7 {
                                let node_privkey = &SecretKey::from_slice(&[n; 32]).unwrap();
                                let node_id = PublicKey::from_secret_key(&secp_ctx, node_privkey);
-                               net_graph_msg_handler.sync_routing_table(&node_id, &init_msg);
+                               net_graph_msg_handler.peer_connected(&node_id, &init_msg);
                                let events = net_graph_msg_handler.get_and_clear_pending_msg_events();
                                if n <= 5 {
-                                       assert_eq!(events.len(), 1);
+                                       assert_eq!(events.len(), 2);
                                } else {
-                                       assert_eq!(events.len(), 0);
+                                       // Even after the we stop sending the explicit query, we should still send a
+                                       // gossip_timestamp_filter on each new connection.
+                                       assert_eq!(events.len(), 1);
                                }
 
                        }
index f899f76199999bee3987b2773f7661a37bdef0f8..677a571620ce31a329f8b046d294a8d99b1c2387 100644 (file)
@@ -1587,45 +1587,58 @@ fn add_random_cltv_offset(route: &mut Route, payment_params: &PaymentParameters,
        for path in route.paths.iter_mut() {
                let mut shadow_ctlv_expiry_delta_offset: u32 = 0;
 
-               // Choose the last publicly known node as the starting point for the random walk
-               if let Some(starting_hop) = path.iter().rev().find(|h| network_nodes.contains_key(&NodeId::from_pubkey(&h.pubkey))) {
-                       let mut cur_node_id = NodeId::from_pubkey(&starting_hop.pubkey);
+               // Remember the last three nodes of the random walk and avoid looping back on them.
+               // Init with the last three nodes from the actual path, if possible.
+               let mut nodes_to_avoid: [NodeId; 3] = [NodeId::from_pubkey(&path.last().unwrap().pubkey),
+                       NodeId::from_pubkey(&path.get(path.len().saturating_sub(2)).unwrap().pubkey),
+                       NodeId::from_pubkey(&path.get(path.len().saturating_sub(3)).unwrap().pubkey)];
+
+               // Choose the last publicly known node as the starting point for the random walk.
+               let mut cur_hop: Option<NodeId> = None;
+               let mut path_nonce = [0u8; 12];
+               if let Some(starting_hop) = path.iter().rev()
+                       .find(|h| network_nodes.contains_key(&NodeId::from_pubkey(&h.pubkey))) {
+                               cur_hop = Some(NodeId::from_pubkey(&starting_hop.pubkey));
+                               path_nonce.copy_from_slice(&cur_hop.unwrap().as_slice()[..12]);
+               }
+
+               // Init PRNG with the path-dependant nonce, which is static for private paths.
+               let mut prng = ChaCha20::new(random_seed_bytes, &path_nonce);
+               let mut random_path_bytes = [0u8; ::core::mem::size_of::<usize>()];
 
-                       // Init PRNG with path nonce
-                       let mut path_nonce = [0u8; 12];
-                       path_nonce.copy_from_slice(&cur_node_id.as_slice()[..12]);
-                       let mut prng = ChaCha20::new(random_seed_bytes, &path_nonce);
-                       let mut random_path_bytes = [0u8; ::core::mem::size_of::<usize>()];
+               // Pick a random path length in [1 .. 3]
+               prng.process_in_place(&mut random_path_bytes);
+               let random_walk_length = usize::from_be_bytes(random_path_bytes).wrapping_rem(3).wrapping_add(1);
 
-                       // Pick a random path length in [1 .. 3]
-                       prng.process_in_place(&mut random_path_bytes);
-                       let random_walk_length = usize::from_be_bytes(random_path_bytes).wrapping_rem(3).wrapping_add(1);
+               for random_hop in 0..random_walk_length {
+                       // If we don't find a suitable offset in the public network graph, we default to
+                       // MEDIAN_HOP_CLTV_EXPIRY_DELTA.
+                       let mut random_hop_offset = MEDIAN_HOP_CLTV_EXPIRY_DELTA;
 
-                       for _random_hop in 0..random_walk_length {
+                       if let Some(cur_node_id) = cur_hop {
                                if let Some(cur_node) = network_nodes.get(&cur_node_id) {
-                                       // Randomly choose the next hop
+                                       // Randomly choose the next unvisited hop.
                                        prng.process_in_place(&mut random_path_bytes);
-                                       if let Some(random_channel) = usize::from_be_bytes(random_path_bytes).checked_rem(cur_node.channels.len())
+                                       if let Some(random_channel) = usize::from_be_bytes(random_path_bytes)
+                                               .checked_rem(cur_node.channels.len())
                                                .and_then(|index| cur_node.channels.get(index))
                                                .and_then(|id| network_channels.get(id)) {
                                                        random_channel.as_directed_from(&cur_node_id).map(|(dir_info, next_id)| {
-                                                               dir_info.direction().map(|channel_update_info|
-                                                                       shadow_ctlv_expiry_delta_offset = shadow_ctlv_expiry_delta_offset
-                                                                               .checked_add(channel_update_info.cltv_expiry_delta.into())
-                                                                               .unwrap_or(shadow_ctlv_expiry_delta_offset));
-                                                               cur_node_id = *next_id;
+                                                               if !nodes_to_avoid.iter().any(|x| x == next_id) {
+                                                                       nodes_to_avoid[random_hop] = *next_id;
+                                                                       dir_info.direction().map(|channel_update_info| {
+                                                                               random_hop_offset = channel_update_info.cltv_expiry_delta.into();
+                                                                               cur_hop = Some(*next_id);
+                                                                       });
+                                                               }
                                                        });
                                                }
                                }
                        }
-               } else {
-                       // If the entire path is private, choose a random offset from multiples of
-                       // MEDIAN_HOP_CLTV_EXPIRY_DELTA
-                       let mut prng = ChaCha20::new(random_seed_bytes, &[0u8; 8]);
-                       let mut random_bytes = [0u8; 4];
-                       prng.process_in_place(&mut random_bytes);
-                       let random_walk_length = u32::from_be_bytes(random_bytes).wrapping_rem(3).wrapping_add(1);
-                       shadow_ctlv_expiry_delta_offset = random_walk_length * MEDIAN_HOP_CLTV_EXPIRY_DELTA;
+
+                       shadow_ctlv_expiry_delta_offset = shadow_ctlv_expiry_delta_offset
+                               .checked_add(random_hop_offset)
+                               .unwrap_or(shadow_ctlv_expiry_delta_offset);
                }
 
                // Limit the total offset to reduce the worst-case locked liquidity timevalue
index c39abd1d0ff71d2f613935959007b333204371b2..d8b1740c19ec2f1ec6098fb5f941c5e387845865 100644 (file)
@@ -927,11 +927,8 @@ impl<G: Deref<Target = NetworkGraph>, T: Time> Writeable for ProbabilisticScorer
        }
 }
 
-impl<G, T> ReadableArgs<(ProbabilisticScoringParameters, G)> for ProbabilisticScorerUsingTime<G, T>
-where
-       G: Deref<Target = NetworkGraph>,
-       T: Time,
-{
+impl<G: Deref<Target = NetworkGraph>, T: Time>
+ReadableArgs<(ProbabilisticScoringParameters, G)> for ProbabilisticScorerUsingTime<G, T> {
        #[inline]
        fn read<R: Read>(
                r: &mut R, args: (ProbabilisticScoringParameters, G)
index 3b90015cab901bd0ba72586ffad37dd65d3be711..623b2ea01acb9cf623bc2a4f7bd73e8f32a404ce 100644 (file)
@@ -909,7 +909,15 @@ pub enum MessageSendEvent {
                node_id: PublicKey,
                /// The reply_channel_range which should be sent.
                msg: msgs::ReplyChannelRange,
-       }
+       },
+       /// Sends a timestamp filter for inbound gossip. This should be sent on each new connection to
+       /// enable receiving gossip messages from the peer.
+       SendGossipTimestampFilter {
+               /// The node_id of this message recipient
+               node_id: PublicKey,
+               /// The gossip_timestamp_filter which should be sent.
+               msg: msgs::GossipTimestampFilter,
+       },
 }
 
 /// A trait indicating an object may generate message send events
index 27c2d9de874ed45abca03dabe171ca238d7288ff..3c36cdf066a5048bbb1b6fe112c2906ac824e6cc 100644 (file)
@@ -384,7 +384,7 @@ impl msgs::RoutingMessageHandler for TestRoutingMessageHandler {
                Vec::new()
        }
 
-       fn sync_routing_table(&self, _their_node_id: &PublicKey, _init_msg: &msgs::Init) {}
+       fn peer_connected(&self, _their_node_id: &PublicKey, _init_msg: &msgs::Init) {}
 
        fn handle_reply_channel_range(&self, _their_node_id: &PublicKey, _msg: msgs::ReplyChannelRange) -> Result<(), msgs::LightningError> {
                Ok(())