Skip to content

Commit 64f7d1d

Browse files
committed
Use BTreeMap to store graph nodes and channels
1 parent e4a2170 commit 64f7d1d

File tree

5 files changed

+111
-47
lines changed

5 files changed

+111
-47
lines changed

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/fiber-lib/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ thiserror = "1.0.58"
5757
tokio-util = {version = "0.7.10", features = ["rt"]}
5858
tracing = "0.1"
5959
tracing-subscriber = {version = "0.3", features = ["env-filter"]}
60-
indexmap = "2.11.0"
6160

6261
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
6362
biscuit-auth = "6.0.0-beta.3"

crates/fiber-lib/src/fiber/graph.rs

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ use crate::fiber::types::PaymentHopData;
2222
use crate::invoice::CkbInvoice;
2323
use crate::now_timestamp_as_millis_u64;
2424
use ckb_types::packed::{OutPoint, Script};
25-
use indexmap::IndexMap;
2625
use parking_lot::Mutex;
2726
use serde::{Deserialize, Serialize};
2827
use serde_with::serde_as;
29-
use std::collections::{HashMap, HashSet};
28+
use std::collections::{BTreeMap, HashMap, HashSet};
29+
use std::ops::Bound;
3030
use std::sync::Arc;
3131
use tentacle::multiaddr::MultiAddr;
3232
use tentacle::secio::PeerId;
@@ -448,9 +448,9 @@ pub struct NetworkGraph<S> {
448448
// The count of private channels
449449
pub(crate) private_channels_count: usize,
450450
// All the channels in the network.
451-
pub(crate) channels: IndexMap<OutPoint, ChannelInfo>,
451+
pub(crate) channels: BTreeMap<OutPoint, ChannelInfo>,
452452
// All the nodes in the network.
453-
pub(crate) nodes: IndexMap<Pubkey, NodeInfo>,
453+
pub(crate) nodes: BTreeMap<Pubkey, NodeInfo>,
454454

455455
// Channel stats map, used to track the attempts for each channel,
456456
// this information is used to HELP the path finding algorithm for better routing in two ways:
@@ -528,9 +528,9 @@ where
528528
always_process_gossip_message: false,
529529
source,
530530
private_channels_count: 0,
531-
channels: IndexMap::new(),
531+
channels: BTreeMap::new(),
532532
channel_stats: Default::default(),
533-
nodes: IndexMap::new(),
533+
nodes: BTreeMap::new(),
534534
latest_cursor: Cursor::default(),
535535
store: store.clone(),
536536
history: PaymentHistory::new(source, None, store),
@@ -620,7 +620,7 @@ where
620620
.insert(channel_info.channel_outpoint.clone(), channel_info);
621621
}
622622
OwnedChannelUpdateEvent::Down(channel_outpoint) => {
623-
if let Some(channel_info) = self.channels.swap_remove(&channel_outpoint) {
623+
if let Some(channel_info) = self.channels.remove(&channel_outpoint) {
624624
if !channel_info.is_public {
625625
self.private_channels_count -= 1;
626626
}
@@ -851,14 +851,21 @@ where
851851
self.nodes.values()
852852
}
853853

854-
pub fn get_nodes_with_params(&self, limit: usize, after: Option<u64>) -> Vec<NodeInfo> {
855-
let after = after.unwrap_or_default();
856-
self.nodes
857-
.iter()
858-
.skip(after as usize)
859-
.take(limit)
860-
.map(|(_pubkey, node)| node.to_owned())
861-
.collect()
854+
pub fn get_nodes_with_params(&self, limit: usize, after: Option<Pubkey>) -> Vec<NodeInfo> {
855+
match after {
856+
Some(after) => self
857+
.nodes
858+
.range((Bound::Excluded(after), Bound::Unbounded))
859+
.take(limit)
860+
.map(|(_pubkey, node)| node.to_owned())
861+
.collect(),
862+
None => self
863+
.nodes
864+
.iter()
865+
.take(limit)
866+
.map(|(_pubkey, node)| node.to_owned())
867+
.collect(),
868+
}
862869
}
863870

864871
pub fn get_node(&self, node_id: &Pubkey) -> Option<&NodeInfo> {
@@ -904,20 +911,32 @@ where
904911
}
905912
}
906913

907-
pub fn get_channels_with_params(&self, limit: usize, after: Option<u64>) -> Vec<ChannelInfo> {
908-
let after = after.unwrap_or_default();
909-
self.channels
910-
.iter()
911-
.skip(after as usize)
912-
.take(limit)
913-
.filter_map(|(_out_point, channel_info)| {
914-
if channel_info.is_public {
915-
Some(channel_info.to_owned())
916-
} else {
917-
None
918-
}
919-
})
920-
.collect()
914+
pub fn get_channels_with_params(
915+
&self,
916+
limit: usize,
917+
after: Option<OutPoint>,
918+
) -> Vec<ChannelInfo> {
919+
let filter = |(_out_point, channel_info): (&OutPoint, &ChannelInfo)| {
920+
if channel_info.is_public {
921+
Some(channel_info.to_owned())
922+
} else {
923+
None
924+
}
925+
};
926+
match after {
927+
Some(after) => self
928+
.channels
929+
.range((Bound::Excluded(after), Bound::Unbounded))
930+
.take(limit)
931+
.filter_map(filter)
932+
.collect(),
933+
None => self
934+
.channels
935+
.iter()
936+
.take(limit)
937+
.filter_map(filter)
938+
.collect(),
939+
}
921940
}
922941

923942
pub fn get_channels_by_peer(&self, node_id: Pubkey) -> impl Iterator<Item = &ChannelInfo> {

crates/fiber-lib/src/fiber/tests/rpc.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,8 @@ async fn test_rpc_graph() {
287287
.all(|n| n.version == *env!("CARGO_PKG_VERSION")));
288288
assert!(!graph_nodes.nodes[0].features.is_empty());
289289

290-
let graph_nodes: GraphNodesResult = node_0
290+
// query nodes by page
291+
let graph_nodes_p1: GraphNodesResult = node_0
291292
.send_rpc_request(
292293
"graph_nodes",
293294
GraphNodesParams {
@@ -298,8 +299,33 @@ async fn test_rpc_graph() {
298299
.await
299300
.unwrap();
300301

301-
assert_eq!(graph_nodes.total_count.value(), 2);
302-
assert_eq!(graph_nodes.nodes.len(), 1);
302+
assert_eq!(graph_nodes_p1.total_count.value(), 2);
303+
assert_eq!(graph_nodes_p1.nodes.len(), 1);
304+
305+
let graph_nodes_p2: GraphNodesResult = node_0
306+
.send_rpc_request(
307+
"graph_nodes",
308+
GraphNodesParams {
309+
limit: Some(1),
310+
after: Some(graph_nodes_p1.last_cursor),
311+
},
312+
)
313+
.await
314+
.unwrap();
315+
316+
assert_eq!(graph_nodes_p2.total_count.value(), 2);
317+
assert_eq!(graph_nodes_p2.nodes.len(), 1);
318+
319+
let mut nodes = graph_nodes_p1.nodes.clone();
320+
nodes.extend(graph_nodes_p2.nodes.clone());
321+
assert_eq!(
322+
graph_nodes
323+
.nodes
324+
.iter()
325+
.map(|n| n.node_id)
326+
.collect::<Vec<_>>(),
327+
nodes.iter().map(|n| n.node_id).collect::<Vec<_>>(),
328+
);
303329

304330
let graph_channels: GraphChannelsResult = node_0
305331
.send_rpc_request(
@@ -315,6 +341,21 @@ async fn test_rpc_graph() {
315341
// only public channels
316342
assert_eq!(graph_channels.total_count.value(), 1);
317343
assert_eq!(graph_channels.channels.len(), 1);
344+
345+
// next query is empty
346+
let graph_channels: GraphChannelsResult = node_0
347+
.send_rpc_request(
348+
"graph_channels",
349+
GraphChannelsParams {
350+
limit: Some(1),
351+
after: Some(graph_channels.last_cursor),
352+
},
353+
)
354+
.await
355+
.unwrap();
356+
357+
assert_eq!(graph_channels.total_count.value(), 1);
358+
assert!(graph_channels.channels.is_empty());
318359
}
319360

320361
#[tokio::test]

crates/fiber-lib/src/rpc/graph.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use ckb_types::H256;
1818
use jsonrpsee::proc_macros::rpc;
1919
use jsonrpsee::types::ErrorObjectOwned;
2020

21+
use molecule::prelude::Entity;
2122
use serde::{Deserialize, Serialize};
2223
use serde_with::serde_as;
2324
use std::sync::Arc;
@@ -338,15 +339,16 @@ where
338339
let network_graph = self.network_graph.read().await;
339340
let default_max_limit = 500;
340341
let limit = params.limit.unwrap_or(default_max_limit) as usize;
341-
let after = params.after.as_ref().map(|after| {
342-
let buf: [u8; 8] = after.as_bytes().try_into().unwrap_or_default();
343-
u64::from_le_bytes(buf)
344-
});
342+
let after = params
343+
.after
344+
.as_ref()
345+
.and_then(|after| Pubkey::from_slice(after.as_bytes()).ok());
345346
let nodes = network_graph.get_nodes_with_params(limit, after);
346347
let last_cursor = JsonBytes::from_vec(
347-
(after.unwrap_or_default() + nodes.len() as u64)
348-
.to_le_bytes()
349-
.to_vec(),
348+
nodes
349+
.last()
350+
.map(|n| n.node_id.serialize().to_vec())
351+
.unwrap_or_default(),
350352
);
351353
let nodes = nodes.into_iter().map(Into::into).collect();
352354
let total_count = (network_graph.nodes.len() as u64).into();
@@ -365,16 +367,20 @@ where
365367
let default_max_limit = 500;
366368
let network_graph = self.network_graph.read().await;
367369
let limit = params.limit.unwrap_or(default_max_limit) as usize;
368-
let after = params.after.as_ref().map(|after| {
369-
let buf: [u8; 8] = after.as_bytes().try_into().unwrap_or_default();
370-
u64::from_le_bytes(buf)
370+
let after = params.after.as_ref().and_then(|after| {
371+
if after.is_empty() {
372+
None
373+
} else {
374+
OutPoint::from_slice(after.as_bytes()).ok()
375+
}
371376
});
372377

373378
let channels = network_graph.get_channels_with_params(limit, after);
374379
let last_cursor = JsonBytes::from_vec(
375-
(after.unwrap_or_default() + channels.len() as u64)
376-
.to_le_bytes()
377-
.to_vec(),
380+
channels
381+
.last()
382+
.map(|c| c.channel_outpoint.as_slice().to_vec())
383+
.unwrap_or_default(),
378384
);
379385

380386
let channels = channels.into_iter().map(Into::into).collect();

0 commit comments

Comments
 (0)