Skip to content

Commit 6f536ec

Browse files
authored
Merge pull request #4107 from TheBlueMatt/2025-09-fix-forward-while-sync-order
Correct gossip forwarding criteria while doing background sync
2 parents c2e3ae0 + edc7903 commit 6f536ec

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

lightning/src/ln/peer_channel_encryptor.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,11 @@ impl MessageBuf {
656656
res[16 + 2..].copy_from_slice(&encoded_msg);
657657
Self(res)
658658
}
659+
660+
#[cfg(test)]
661+
pub(crate) fn fetch_encoded_msg_with_type_pfx(&self) -> Vec<u8> {
662+
self.0.clone().split_off(16 + 2)
663+
}
659664
}
660665

661666
#[cfg(test)]

lightning/src/ln/peer_handler.rs

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ impl Peer {
828828
}
829829
match self.sync_status {
830830
InitSyncTracker::NoSyncRequested => true,
831-
InitSyncTracker::ChannelsSyncing(i) => i < channel_id,
831+
InitSyncTracker::ChannelsSyncing(i) => channel_id < i,
832832
InitSyncTracker::NodesSyncing(_) => true,
833833
}
834834
}
@@ -4403,6 +4403,80 @@ mod tests {
44034403
assert_eq!(cfgs[1].routing_handler.chan_anns_recvd.load(Ordering::Acquire), 54);
44044404
}
44054405

4406+
#[test]
4407+
fn test_forward_while_syncing() {
4408+
use crate::ln::peer_handler::tests::test_utils::get_dummy_channel_update;
4409+
4410+
// Test forwarding new channel announcements while we're doing syncing.
4411+
let cfgs = create_peermgr_cfgs(2);
4412+
cfgs[0].routing_handler.request_full_sync.store(true, Ordering::Release);
4413+
cfgs[1].routing_handler.request_full_sync.store(true, Ordering::Release);
4414+
cfgs[0].routing_handler.announcement_available_for_sync.store(true, Ordering::Release);
4415+
cfgs[1].routing_handler.announcement_available_for_sync.store(true, Ordering::Release);
4416+
let peers = create_network(2, &cfgs);
4417+
4418+
let (mut fd_a, mut fd_b) = establish_connection(&peers[0], &peers[1]);
4419+
4420+
// Iterate a handful of times to exchange some messages
4421+
for _ in 0..150 {
4422+
peers[1].process_events();
4423+
let a_read_data = fd_b.outbound_data.lock().unwrap().split_off(0);
4424+
assert!(!a_read_data.is_empty());
4425+
4426+
peers[0].read_event(&mut fd_a, &a_read_data).unwrap();
4427+
peers[0].process_events();
4428+
4429+
let b_read_data = fd_a.outbound_data.lock().unwrap().split_off(0);
4430+
assert!(!b_read_data.is_empty());
4431+
peers[1].read_event(&mut fd_b, &b_read_data).unwrap();
4432+
4433+
peers[0].process_events();
4434+
assert_eq!(
4435+
fd_a.outbound_data.lock().unwrap().len(),
4436+
0,
4437+
"Until A receives data, it shouldn't send more messages"
4438+
);
4439+
}
4440+
4441+
// Forward one more gossip backfill message but don't flush it so that we can examine the
4442+
// unencrypted message for broadcasts.
4443+
fd_b.hang_writes.store(true, Ordering::Relaxed);
4444+
peers[1].process_events();
4445+
4446+
{
4447+
let peer_lock = peers[1].peers.read().unwrap();
4448+
let peer = peer_lock.get(&fd_b).unwrap().lock().unwrap();
4449+
assert_eq!(peer.pending_outbound_buffer.len(), 1);
4450+
assert_eq!(peer.gossip_broadcast_buffer.len(), 0);
4451+
}
4452+
4453+
// At this point we should have sent channel announcements up to roughly SCID 150. Now
4454+
// build an updated update for SCID 100 and SCID 5000 and make sure only the one for SCID
4455+
// 100 gets forwarded
4456+
let msg_100 = get_dummy_channel_update(100);
4457+
let msg_ev_100 = MessageSendEvent::BroadcastChannelUpdate { msg: msg_100.clone() };
4458+
4459+
let msg_5000 = get_dummy_channel_update(5000);
4460+
let msg_ev_5000 = MessageSendEvent::BroadcastChannelUpdate { msg: msg_5000 };
4461+
4462+
fd_a.hang_writes.store(true, Ordering::Relaxed);
4463+
4464+
cfgs[1].routing_handler.pending_events.lock().unwrap().push(msg_ev_100);
4465+
cfgs[1].routing_handler.pending_events.lock().unwrap().push(msg_ev_5000);
4466+
peers[1].process_events();
4467+
4468+
{
4469+
let peer_lock = peers[1].peers.read().unwrap();
4470+
let peer = peer_lock.get(&fd_b).unwrap().lock().unwrap();
4471+
assert_eq!(peer.pending_outbound_buffer.len(), 1);
4472+
assert_eq!(peer.gossip_broadcast_buffer.len(), 1);
4473+
4474+
let pending_msg = &peer.gossip_broadcast_buffer[0];
4475+
let expected = encode_msg!(&msg_100);
4476+
assert_eq!(expected, pending_msg.fetch_encoded_msg_with_type_pfx());
4477+
}
4478+
}
4479+
44064480
#[test]
44074481
fn test_handshake_timeout() {
44084482
// Tests that we time out a peer still waiting on handshake completion after a full timer

lightning/src/util/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,7 @@ fn get_dummy_channel_announcement(short_chan_id: u64) -> msgs::ChannelAnnounceme
13551355
}
13561356
}
13571357

1358-
fn get_dummy_channel_update(short_chan_id: u64) -> msgs::ChannelUpdate {
1358+
pub fn get_dummy_channel_update(short_chan_id: u64) -> msgs::ChannelUpdate {
13591359
use bitcoin::secp256k1::ffi::Signature as FFISignature;
13601360
let network = Network::Testnet;
13611361
msgs::ChannelUpdate {

0 commit comments

Comments
 (0)