Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/fiber-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ thiserror = "1.0.58"
tokio-util = {version = "0.7.10", features = ["rt"]}
tracing = "0.1"
tracing-subscriber = {version = "0.3", features = ["env-filter"]}
indexmap = "2.11.0"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
biscuit-auth = "6.0.0-beta.3"
Expand Down
62 changes: 19 additions & 43 deletions crates/fiber-lib/src/fiber/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use crate::fiber::types::PaymentHopData;
use crate::invoice::CkbInvoice;
use crate::now_timestamp_as_millis_u64;
use ckb_types::packed::{OutPoint, Script};
use indexmap::IndexMap;
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
Expand Down Expand Up @@ -85,6 +86,7 @@ impl From<NodeAnnouncement> for NodeInfo {
#[derive(Clone, Debug, PartialEq)]
pub struct ChannelInfo {
pub channel_outpoint: OutPoint,
pub is_public: bool,
// The timestamp in the block header of the block that includes the funding transaction of the channel.
pub timestamp: u64,

Expand Down Expand Up @@ -195,8 +197,10 @@ impl TryFrom<&ChannelActorState> for ChannelInfo {
Some(state.get_local_channel_update_info()),
)
};
let is_public = state.is_public();
Ok(Self {
channel_outpoint,
is_public,
timestamp,
features: 0,
node1,
Expand All @@ -213,6 +217,7 @@ impl From<(u64, ChannelAnnouncement)> for ChannelInfo {
fn from((timestamp, channel_announcement): (u64, ChannelAnnouncement)) -> Self {
Self {
channel_outpoint: channel_announcement.channel_outpoint,
is_public: true,
timestamp,
features: channel_announcement.features,
node1: channel_announcement.node1_id,
Expand Down Expand Up @@ -441,7 +446,7 @@ pub struct NetworkGraph<S> {
// The pubkey of the node that is running this instance of the network graph.
source: Pubkey,
// All the channels in the network.
pub(crate) channels: HashMap<OutPoint, ChannelInfo>,
pub(crate) channels: IndexMap<OutPoint, ChannelInfo>,
// All the nodes in the network.
nodes: HashMap<Pubkey, NodeInfo>,

Expand Down Expand Up @@ -520,7 +525,7 @@ where
#[cfg(any(test, feature = "bench"))]
always_process_gossip_message: false,
source,
channels: HashMap::new(),
channels: IndexMap::new(),
channel_stats: Default::default(),
nodes: HashMap::new(),
latest_cursor: Cursor::default(),
Expand Down Expand Up @@ -609,7 +614,7 @@ where
.insert(channel_info.channel_outpoint.clone(), channel_info);
}
OwnedChannelUpdateEvent::Down(channel_outpoint) => {
self.channels.remove(&channel_outpoint);
self.channels.swap_remove(&channel_outpoint);
self.channel_stats.lock().remove_channel(&channel_outpoint);
}
OwnedChannelUpdateEvent::Updated(channel_outpoint, node, channel_update) => {
Expand Down Expand Up @@ -653,19 +658,6 @@ where
self.history.reset();
}

fn load_channel_updates_from_store(&self, channel_info: &mut ChannelInfo) {
let channel_update_of_node1 = self
.store
.get_latest_channel_update(&channel_info.channel_outpoint, true)
.map(Into::into);
let channel_update_of_node2 = self
.store
.get_latest_channel_update(&channel_info.channel_outpoint, false)
.map(Into::into);
channel_info.update_of_node1 = channel_update_of_node1;
channel_info.update_of_node2 = channel_update_of_node2;
}

fn load_channel_info_mut(&mut self, channel_outpoint: &OutPoint) -> Option<&mut ChannelInfo> {
if !self.channels.contains_key(channel_outpoint) {
if let Some((timestamp, channel_announcement)) =
Expand Down Expand Up @@ -907,35 +899,19 @@ where
}
}

pub fn get_channels_with_params(
&self,
limit: usize,
after: Option<Cursor>,
) -> Vec<ChannelInfo> {
let cursor = after.unwrap_or_default();
self.store
.get_broadcast_messages_iter(&cursor)
.into_iter()
.filter_map(|message| match message {
BroadcastMessageWithTimestamp::ChannelAnnouncement(
timestamp,
channel_announcement,
) => {
let mut channel_info = ChannelInfo::from((timestamp, channel_announcement));
self.load_channel_updates_from_store(&mut channel_info);

// assuming channel is closed if disabled from the both side
let is_closed = channel_info.update_of_node1.is_some_and(|u| !u.enabled)
&& channel_info.update_of_node2.is_some_and(|u| !u.enabled);
if !is_closed {
Some(channel_info)
} else {
None
}
pub fn get_channels_with_params(&self, limit: usize, after: Option<u64>) -> Vec<ChannelInfo> {
let after = after.unwrap_or_default();
self.channels
.iter()
.skip(after as usize)
.take(limit)
.filter_map(|(_out_point, channel_info)| {
if channel_info.is_public {
Some(channel_info.to_owned())
} else {
None
}
_ => None,
})
.take(limit)
.collect()
}

Expand Down
23 changes: 10 additions & 13 deletions crates/fiber-lib/src/rpc/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,20 +357,17 @@ where
let default_max_limit = 500;
let network_graph = self.network_graph.read().await;
let limit = params.limit.unwrap_or(default_max_limit) as usize;
let cursor = params
.after
.as_ref()
.map(|cursor| Cursor::from_bytes(cursor.as_bytes()))
.transpose()
.map_err(|e| {
ErrorObjectOwned::owned(INVALID_PARAMS_CODE, e.to_string(), Some(params))
})?;
let after = params.after.as_ref().map(|after| {
let buf: [u8; 8] = after.as_bytes().try_into().unwrap_or_default();
u64::from_le_bytes(buf)
});

let channels = network_graph.get_channels_with_params(limit, cursor);
let last_cursor = channels
.last()
.map(|node| JsonBytes::from_vec(node.cursor().to_bytes().into()))
.unwrap_or_default();
let channels = network_graph.get_channels_with_params(limit, after);
let last_cursor = JsonBytes::from_vec(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer to use page and per_page as parameters.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The param is still exposed as last_cursor for the external RPC, so even we change to network_graph.get_channels_with_params(per_page, page * per_page); the extern user feels no difference, and some unneccesary complexity is introduced: need to encode two (page, per_page) instead of one param (after) into last_cursor.

(after.unwrap_or_default() + channels.len() as u64)
.to_le_bytes()
.to_vec(),
);

let channels = channels.into_iter().map(Into::into).collect();
Ok(GraphChannelsResult {
Expand Down
Loading