diff --git a/lightning/src/ln/peer_channel_encryptor.rs b/lightning/src/ln/peer_channel_encryptor.rs index 310308805ec..c7a7ba51be4 100644 --- a/lightning/src/ln/peer_channel_encryptor.rs +++ b/lightning/src/ln/peer_channel_encryptor.rs @@ -656,6 +656,11 @@ impl MessageBuf { res[16 + 2..].copy_from_slice(&encoded_msg); Self(res) } + + #[cfg(test)] + pub(crate) fn fetch_encoded_msg_with_type_pfx(&self) -> Vec { + self.0.clone().split_off(16 + 2) + } } #[cfg(test)] diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index c1809fdadd9..c41fe1fc8c0 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -828,7 +828,7 @@ impl Peer { } match self.sync_status { InitSyncTracker::NoSyncRequested => true, - InitSyncTracker::ChannelsSyncing(i) => i < channel_id, + InitSyncTracker::ChannelsSyncing(i) => channel_id < i, InitSyncTracker::NodesSyncing(_) => true, } } @@ -4403,6 +4403,80 @@ mod tests { assert_eq!(cfgs[1].routing_handler.chan_anns_recvd.load(Ordering::Acquire), 54); } + #[test] + fn test_forward_while_syncing() { + use crate::ln::peer_handler::tests::test_utils::get_dummy_channel_update; + + // Test forwarding new channel announcements while we're doing syncing. + let cfgs = create_peermgr_cfgs(2); + cfgs[0].routing_handler.request_full_sync.store(true, Ordering::Release); + cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release); + cfgs[0].routing_handler.announcement_available_for_sync.store(true, Ordering::Release); + cfgs[1].routing_handler.announcement_available_for_sync.store(true, Ordering::Release); + let peers = create_network(2, &cfgs); + + let (mut fd_a, mut fd_b) = establish_connection(&peers[0], &peers[1]); + + // Iterate a handful of times to exchange some messages + for _ in 0..150 { + peers[1].process_events(); + let a_read_data = fd_b.outbound_data.lock().unwrap().split_off(0); + assert!(!a_read_data.is_empty()); + + peers[0].read_event(&mut fd_a, &a_read_data).unwrap(); + peers[0].process_events(); + + let b_read_data = fd_a.outbound_data.lock().unwrap().split_off(0); + assert!(!b_read_data.is_empty()); + peers[1].read_event(&mut fd_b, &b_read_data).unwrap(); + + peers[0].process_events(); + assert_eq!( + fd_a.outbound_data.lock().unwrap().len(), + 0, + "Until A receives data, it shouldn't send more messages" + ); + } + + // Forward one more gossip backfill message but don't flush it so that we can examine the + // unencrypted message for broadcasts. + fd_b.hang_writes.store(true, Ordering::Relaxed); + peers[1].process_events(); + + { + let peer_lock = peers[1].peers.read().unwrap(); + let peer = peer_lock.get(&fd_b).unwrap().lock().unwrap(); + assert_eq!(peer.pending_outbound_buffer.len(), 1); + assert_eq!(peer.gossip_broadcast_buffer.len(), 0); + } + + // At this point we should have sent channel announcements up to roughly SCID 150. Now + // build an updated update for SCID 100 and SCID 5000 and make sure only the one for SCID + // 100 gets forwarded + let msg_100 = get_dummy_channel_update(100); + let msg_ev_100 = MessageSendEvent::BroadcastChannelUpdate { msg: msg_100.clone() }; + + let msg_5000 = get_dummy_channel_update(5000); + let msg_ev_5000 = MessageSendEvent::BroadcastChannelUpdate { msg: msg_5000 }; + + fd_a.hang_writes.store(true, Ordering::Relaxed); + + cfgs[1].routing_handler.pending_events.lock().unwrap().push(msg_ev_100); + cfgs[1].routing_handler.pending_events.lock().unwrap().push(msg_ev_5000); + peers[1].process_events(); + + { + let peer_lock = peers[1].peers.read().unwrap(); + let peer = peer_lock.get(&fd_b).unwrap().lock().unwrap(); + assert_eq!(peer.pending_outbound_buffer.len(), 1); + assert_eq!(peer.gossip_broadcast_buffer.len(), 1); + + let pending_msg = &peer.gossip_broadcast_buffer[0]; + let expected = encode_msg!(&msg_100); + assert_eq!(expected, pending_msg.fetch_encoded_msg_with_type_pfx()); + } + } + #[test] fn test_handshake_timeout() { // Tests that we time out a peer still waiting on handshake completion after a full timer diff --git a/lightning/src/util/test_utils.rs b/lightning/src/util/test_utils.rs index 769c2a3ed3e..16eb5da5f1e 100644 --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@ -1355,7 +1355,7 @@ fn get_dummy_channel_announcement(short_chan_id: u64) -> msgs::ChannelAnnounceme } } -fn get_dummy_channel_update(short_chan_id: u64) -> msgs::ChannelUpdate { +pub fn get_dummy_channel_update(short_chan_id: u64) -> msgs::ChannelUpdate { use bitcoin::secp256k1::ffi::Signature as FFISignature; let network = Network::Testnet; msgs::ChannelUpdate {