Skip to content

Commit a95338a

Browse files
Merge pull request #3038 from TheBlueMatt/2024-05-no-dir-with-on-side-offline
Ignore partially-pruned channels during routing
2 parents 37bf61c + 4fd8cb8 commit a95338a

File tree

2 files changed

+126
-74
lines changed

2 files changed

+126
-74
lines changed

lightning/src/routing/gossip.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,7 @@ impl ChannelInfo {
879879
/// Returns a [`DirectedChannelInfo`] for the channel directed to the given `target` from a
880880
/// returned `source`, or `None` if `target` is not one of the channel's counterparties.
881881
pub fn as_directed_to(&self, target: &NodeId) -> Option<(DirectedChannelInfo, &NodeId)> {
882+
if self.one_to_two.is_none() || self.two_to_one.is_none() { return None; }
882883
let (direction, source, outbound) = {
883884
if target == &self.node_one {
884885
(self.two_to_one.as_ref(), &self.node_two, false)
@@ -888,12 +889,14 @@ impl ChannelInfo {
888889
return None;
889890
}
890891
};
891-
direction.map(|dir| (DirectedChannelInfo::new(self, dir, outbound), source))
892+
let dir = direction.expect("We checked that both directions are available at the start");
893+
Some((DirectedChannelInfo::new(self, dir, outbound), source))
892894
}
893895

894896
/// Returns a [`DirectedChannelInfo`] for the channel directed from the given `source` to a
895897
/// returned `target`, or `None` if `source` is not one of the channel's counterparties.
896898
pub fn as_directed_from(&self, source: &NodeId) -> Option<(DirectedChannelInfo, &NodeId)> {
899+
if self.one_to_two.is_none() || self.two_to_one.is_none() { return None; }
897900
let (direction, target, outbound) = {
898901
if source == &self.node_one {
899902
(self.one_to_two.as_ref(), &self.node_two, true)
@@ -903,7 +906,8 @@ impl ChannelInfo {
903906
return None;
904907
}
905908
};
906-
direction.map(|dir| (DirectedChannelInfo::new(self, dir, outbound), target))
909+
let dir = direction.expect("We checked that both directions are available at the start");
910+
Some((DirectedChannelInfo::new(self, dir, outbound), target))
907911
}
908912

909913
/// Returns a [`ChannelUpdateInfo`] based on the direction implied by the channel_flag.

lightning/src/routing/router.rs

+120-72
Original file line numberDiff line numberDiff line change
@@ -5503,6 +5503,18 @@ mod tests {
55035503
fee_proportional_millionths: 0,
55045504
excess_data: Vec::new()
55055505
});
5506+
update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
5507+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5508+
short_channel_id: 5,
5509+
timestamp: 2,
5510+
flags: 3, // disable direction 1
5511+
cltv_expiry_delta: 0,
5512+
htlc_minimum_msat: 0,
5513+
htlc_maximum_msat: 200_000,
5514+
fee_base_msat: 0,
5515+
fee_proportional_millionths: 0,
5516+
excess_data: Vec::new()
5517+
});
55065518

55075519
// Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
55085520
// Add 100 sats to the capacities of {12, 13}, because these channels
@@ -5680,6 +5692,18 @@ mod tests {
56805692
fee_proportional_millionths: 0,
56815693
excess_data: Vec::new()
56825694
});
5695+
update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
5696+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5697+
short_channel_id: 5,
5698+
timestamp: 2,
5699+
flags: 3, // disable direction 1
5700+
cltv_expiry_delta: 0,
5701+
htlc_minimum_msat: 0,
5702+
htlc_maximum_msat: 200_000,
5703+
fee_base_msat: 0,
5704+
fee_proportional_millionths: 0,
5705+
excess_data: Vec::new()
5706+
});
56835707

56845708
// Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
56855709
// Add 100 sats to the capacities of {12, 13}, because these channels
@@ -5853,6 +5877,18 @@ mod tests {
58535877
fee_proportional_millionths: 0,
58545878
excess_data: Vec::new()
58555879
});
5880+
update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
5881+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
5882+
short_channel_id: 5,
5883+
timestamp: 2,
5884+
flags: 3, // Disable direction 1
5885+
cltv_expiry_delta: 0,
5886+
htlc_minimum_msat: 0,
5887+
htlc_maximum_msat: 100_000,
5888+
fee_base_msat: 0,
5889+
fee_proportional_millionths: 0,
5890+
excess_data: Vec::new()
5891+
});
58565892

58575893
// Path via {node7, node2, node4} is channels {12, 13, 6, 11}.
58585894
// All channels should be 100 sats capacity. But for the fee experiment,
@@ -6245,92 +6281,104 @@ mod tests {
62456281
let payment_params = PaymentParameters::from_node_id(nodes[6], 42);
62466282

62476283
add_channel(&gossip_sync, &secp_ctx, &our_privkey, &privkeys[1], ChannelFeatures::from_le_bytes(id_to_feature_flags(6)), 6);
6248-
update_channel(&gossip_sync, &secp_ctx, &our_privkey, UnsignedChannelUpdate {
6249-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6250-
short_channel_id: 6,
6251-
timestamp: 1,
6252-
flags: 0,
6253-
cltv_expiry_delta: (6 << 4) | 0,
6254-
htlc_minimum_msat: 0,
6255-
htlc_maximum_msat: MAX_VALUE_MSAT,
6256-
fee_base_msat: 0,
6257-
fee_proportional_millionths: 0,
6258-
excess_data: Vec::new()
6259-
});
6284+
for (key, flags) in [(&our_privkey, 0), (&privkeys[1], 3)] {
6285+
update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
6286+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6287+
short_channel_id: 6,
6288+
timestamp: 1,
6289+
flags,
6290+
cltv_expiry_delta: (6 << 4) | 0,
6291+
htlc_minimum_msat: 0,
6292+
htlc_maximum_msat: MAX_VALUE_MSAT,
6293+
fee_base_msat: 0,
6294+
fee_proportional_millionths: 0,
6295+
excess_data: Vec::new()
6296+
});
6297+
}
62606298
add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[1], NodeFeatures::from_le_bytes(id_to_feature_flags(1)), 0);
62616299

62626300
add_channel(&gossip_sync, &secp_ctx, &privkeys[1], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(5)), 5);
6263-
update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
6264-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6265-
short_channel_id: 5,
6266-
timestamp: 1,
6267-
flags: 0,
6268-
cltv_expiry_delta: (5 << 4) | 0,
6269-
htlc_minimum_msat: 0,
6270-
htlc_maximum_msat: MAX_VALUE_MSAT,
6271-
fee_base_msat: 100,
6272-
fee_proportional_millionths: 0,
6273-
excess_data: Vec::new()
6274-
});
6301+
for (key, flags) in [(&privkeys[1], 0), (&privkeys[4], 3)] {
6302+
update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
6303+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6304+
short_channel_id: 5,
6305+
timestamp: 1,
6306+
flags,
6307+
cltv_expiry_delta: (5 << 4) | 0,
6308+
htlc_minimum_msat: 0,
6309+
htlc_maximum_msat: MAX_VALUE_MSAT,
6310+
fee_base_msat: 100,
6311+
fee_proportional_millionths: 0,
6312+
excess_data: Vec::new()
6313+
});
6314+
}
62756315
add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[4], NodeFeatures::from_le_bytes(id_to_feature_flags(4)), 0);
62766316

62776317
add_channel(&gossip_sync, &secp_ctx, &privkeys[4], &privkeys[3], ChannelFeatures::from_le_bytes(id_to_feature_flags(4)), 4);
6278-
update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
6279-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6280-
short_channel_id: 4,
6281-
timestamp: 1,
6282-
flags: 0,
6283-
cltv_expiry_delta: (4 << 4) | 0,
6284-
htlc_minimum_msat: 0,
6285-
htlc_maximum_msat: MAX_VALUE_MSAT,
6286-
fee_base_msat: 0,
6287-
fee_proportional_millionths: 0,
6288-
excess_data: Vec::new()
6289-
});
6318+
for (key, flags) in [(&privkeys[4], 0), (&privkeys[3], 3)] {
6319+
update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
6320+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6321+
short_channel_id: 4,
6322+
timestamp: 1,
6323+
flags,
6324+
cltv_expiry_delta: (4 << 4) | 0,
6325+
htlc_minimum_msat: 0,
6326+
htlc_maximum_msat: MAX_VALUE_MSAT,
6327+
fee_base_msat: 0,
6328+
fee_proportional_millionths: 0,
6329+
excess_data: Vec::new()
6330+
});
6331+
}
62906332
add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[3], NodeFeatures::from_le_bytes(id_to_feature_flags(3)), 0);
62916333

62926334
add_channel(&gossip_sync, &secp_ctx, &privkeys[3], &privkeys[2], ChannelFeatures::from_le_bytes(id_to_feature_flags(3)), 3);
6293-
update_channel(&gossip_sync, &secp_ctx, &privkeys[3], UnsignedChannelUpdate {
6294-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6295-
short_channel_id: 3,
6296-
timestamp: 1,
6297-
flags: 0,
6298-
cltv_expiry_delta: (3 << 4) | 0,
6299-
htlc_minimum_msat: 0,
6300-
htlc_maximum_msat: MAX_VALUE_MSAT,
6301-
fee_base_msat: 0,
6302-
fee_proportional_millionths: 0,
6303-
excess_data: Vec::new()
6304-
});
6335+
for (key, flags) in [(&privkeys[3], 0), (&privkeys[2], 3)] {
6336+
update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
6337+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6338+
short_channel_id: 3,
6339+
timestamp: 1,
6340+
flags,
6341+
cltv_expiry_delta: (3 << 4) | 0,
6342+
htlc_minimum_msat: 0,
6343+
htlc_maximum_msat: MAX_VALUE_MSAT,
6344+
fee_base_msat: 0,
6345+
fee_proportional_millionths: 0,
6346+
excess_data: Vec::new()
6347+
});
6348+
}
63056349
add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[2], NodeFeatures::from_le_bytes(id_to_feature_flags(2)), 0);
63066350

63076351
add_channel(&gossip_sync, &secp_ctx, &privkeys[2], &privkeys[4], ChannelFeatures::from_le_bytes(id_to_feature_flags(2)), 2);
6308-
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
6309-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6310-
short_channel_id: 2,
6311-
timestamp: 1,
6312-
flags: 0,
6313-
cltv_expiry_delta: (2 << 4) | 0,
6314-
htlc_minimum_msat: 0,
6315-
htlc_maximum_msat: MAX_VALUE_MSAT,
6316-
fee_base_msat: 0,
6317-
fee_proportional_millionths: 0,
6318-
excess_data: Vec::new()
6319-
});
6352+
for (key, flags) in [(&privkeys[2], 0), (&privkeys[4], 3)] {
6353+
update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
6354+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6355+
short_channel_id: 2,
6356+
timestamp: 1,
6357+
flags,
6358+
cltv_expiry_delta: (2 << 4) | 0,
6359+
htlc_minimum_msat: 0,
6360+
htlc_maximum_msat: MAX_VALUE_MSAT,
6361+
fee_base_msat: 0,
6362+
fee_proportional_millionths: 0,
6363+
excess_data: Vec::new()
6364+
});
6365+
}
63206366

63216367
add_channel(&gossip_sync, &secp_ctx, &privkeys[4], &privkeys[6], ChannelFeatures::from_le_bytes(id_to_feature_flags(1)), 1);
6322-
update_channel(&gossip_sync, &secp_ctx, &privkeys[4], UnsignedChannelUpdate {
6323-
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6324-
short_channel_id: 1,
6325-
timestamp: 1,
6326-
flags: 0,
6327-
cltv_expiry_delta: (1 << 4) | 0,
6328-
htlc_minimum_msat: 100,
6329-
htlc_maximum_msat: MAX_VALUE_MSAT,
6330-
fee_base_msat: 0,
6331-
fee_proportional_millionths: 0,
6332-
excess_data: Vec::new()
6333-
});
6368+
for (key, flags) in [(&privkeys[4], 0), (&privkeys[6], 3)] {
6369+
update_channel(&gossip_sync, &secp_ctx, key, UnsignedChannelUpdate {
6370+
chain_hash: ChainHash::using_genesis_block(Network::Testnet),
6371+
short_channel_id: 1,
6372+
timestamp: 1,
6373+
flags,
6374+
cltv_expiry_delta: (1 << 4) | 0,
6375+
htlc_minimum_msat: 100,
6376+
htlc_maximum_msat: MAX_VALUE_MSAT,
6377+
fee_base_msat: 0,
6378+
fee_proportional_millionths: 0,
6379+
excess_data: Vec::new()
6380+
});
6381+
}
63346382
add_or_update_node(&gossip_sync, &secp_ctx, &privkeys[6], NodeFeatures::from_le_bytes(id_to_feature_flags(6)), 0);
63356383

63366384
{

0 commit comments

Comments
 (0)