use crate::util::events::{MessageSendEvent, MessageSendEventsProvider};
use crate::util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK};
use crate::util::string::PrintableString;
use crate::util::events::{MessageSendEvent, MessageSendEventsProvider};
use crate::util::scid_utils::{block_from_scid, scid_from_parts, MAX_SCID_BLOCK};
use crate::util::string::PrintableString;
- channels: RwLock<BTreeMap<u64, ChannelInfo>>,
- nodes: RwLock<BTreeMap<NodeId, NodeInfo>>,
+ channels: RwLock<IndexedMap<u64, ChannelInfo>>,
+ nodes: RwLock<IndexedMap<NodeId, NodeInfo>>,
// Lock order: removed_channels -> removed_nodes
//
// NOTE: In the following `removed_*` maps, we use seconds since UNIX epoch to track time instead
// Lock order: removed_channels -> removed_nodes
//
// NOTE: In the following `removed_*` maps, we use seconds since UNIX epoch to track time instead
- channels: RwLockReadGuard<'a, BTreeMap<u64, ChannelInfo>>,
- nodes: RwLockReadGuard<'a, BTreeMap<NodeId, NodeInfo>>,
+ channels: RwLockReadGuard<'a, IndexedMap<u64, ChannelInfo>>,
+ nodes: RwLockReadGuard<'a, IndexedMap<NodeId, NodeInfo>>,
self.genesis_hash.write(writer)?;
let channels = self.channels.read().unwrap();
(channels.len() as u64).write(writer)?;
self.genesis_hash.write(writer)?;
let channels = self.channels.read().unwrap();
(channels.len() as u64).write(writer)?;
(*chan_id).write(writer)?;
chan_info.write(writer)?;
}
let nodes = self.nodes.read().unwrap();
(nodes.len() as u64).write(writer)?;
(*chan_id).write(writer)?;
chan_info.write(writer)?;
}
let nodes = self.nodes.read().unwrap();
(nodes.len() as u64).write(writer)?;
let genesis_hash: BlockHash = Readable::read(reader)?;
let channels_count: u64 = Readable::read(reader)?;
let genesis_hash: BlockHash = Readable::read(reader)?;
let channels_count: u64 = Readable::read(reader)?;
for _ in 0..channels_count {
let chan_id: u64 = Readable::read(reader)?;
let chan_info = Readable::read(reader)?;
channels.insert(chan_id, chan_info);
}
let nodes_count: u64 = Readable::read(reader)?;
for _ in 0..channels_count {
let chan_id: u64 = Readable::read(reader)?;
let chan_info = Readable::read(reader)?;
channels.insert(chan_id, chan_info);
}
let nodes_count: u64 = Readable::read(reader)?;
for _ in 0..nodes_count {
let node_id = Readable::read(reader)?;
let node_info = Readable::read(reader)?;
for _ in 0..nodes_count {
let node_id = Readable::read(reader)?;
let node_info = Readable::read(reader)?;
impl<L: Deref> fmt::Display for NetworkGraph<L> where L::Target: Logger {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
writeln!(f, "Network map\n[Channels]")?;
impl<L: Deref> fmt::Display for NetworkGraph<L> where L::Target: Logger {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
writeln!(f, "Network map\n[Channels]")?;
writeln!(f, " {}: {}", key, val)?;
}
writeln!(f, "[Nodes]")?;
writeln!(f, " {}: {}", key, val)?;
}
writeln!(f, "[Nodes]")?;
writeln!(f, " {}: {}", log_bytes!(node_id.as_slice()), val)?;
}
Ok(())
writeln!(f, " {}: {}", log_bytes!(node_id.as_slice()), val)?;
}
Ok(())
- channels: RwLock::new(BTreeMap::new()),
- nodes: RwLock::new(BTreeMap::new()),
+ channels: RwLock::new(IndexedMap::new()),
+ nodes: RwLock::new(IndexedMap::new()),
last_rapid_gossip_sync_timestamp: Mutex::new(None),
removed_channels: Mutex::new(HashMap::new()),
removed_nodes: Mutex::new(HashMap::new()),
last_rapid_gossip_sync_timestamp: Mutex::new(None),
removed_channels: Mutex::new(HashMap::new()),
removed_nodes: Mutex::new(HashMap::new()),
//TODO: because asking the blockchain if short_channel_id is valid is only optional
//in the blockchain API, we need to handle it smartly here, though it's unclear
//exactly how...
//TODO: because asking the blockchain if short_channel_id is valid is only optional
//in the blockchain API, we need to handle it smartly here, though it's unclear
//exactly how...
entry.insert(channel_info);
}
};
for current_node_id in [node_id_a, node_id_b].iter() {
match nodes.entry(current_node_id.clone()) {
entry.insert(channel_info);
}
};
for current_node_id in [node_id_a, node_id_b].iter() {
match nodes.entry(current_node_id.clone()) {
node_entry.insert(NodeInfo {
channels: vec!(short_channel_id),
announcement_info: None,
node_entry.insert(NodeInfo {
channels: vec!(short_channel_id),
announcement_info: None,
for scid in node.channels.iter() {
if let Some(chan_info) = channels.remove(scid) {
let other_node_id = if node_id == chan_info.node_one { chan_info.node_two } else { chan_info.node_one };
for scid in node.channels.iter() {
if let Some(chan_info) = channels.remove(scid) {
let other_node_id = if node_id == chan_info.node_one { chan_info.node_two } else { chan_info.node_one };
// Sadly BTreeMap::retain was only stabilized in 1.53 so we can't switch to it for some
// time.
let mut scids_to_remove = Vec::new();
// Sadly BTreeMap::retain was only stabilized in 1.53 so we can't switch to it for some
// time.
let mut scids_to_remove = Vec::new();
- fn remove_channel_in_nodes(nodes: &mut BTreeMap<NodeId, NodeInfo>, chan: &ChannelInfo, short_channel_id: u64) {
+ fn remove_channel_in_nodes(nodes: &mut IndexedMap<NodeId, NodeInfo>, chan: &ChannelInfo, short_channel_id: u64) {
impl ReadOnlyNetworkGraph<'_> {
/// Returns all known valid channels' short ids along with announced channel info.
///
impl ReadOnlyNetworkGraph<'_> {
/// Returns all known valid channels' short ids along with announced channel info.
///
- /// (C-not exported) because we have no mapping for `BTreeMap`s
- pub fn channels(&self) -> &BTreeMap<u64, ChannelInfo> {
+ /// (C-not exported) because we don't want to return lifetime'd references
+ pub fn channels(&self) -> &IndexedMap<u64, ChannelInfo> {
#[cfg(c_bindings)] // Non-bindings users should use `channels`
/// Returns the list of channels in the graph
pub fn list_channels(&self) -> Vec<u64> {
#[cfg(c_bindings)] // Non-bindings users should use `channels`
/// Returns the list of channels in the graph
pub fn list_channels(&self) -> Vec<u64> {
- /// (C-not exported) because we have no mapping for `BTreeMap`s
- pub fn nodes(&self) -> &BTreeMap<NodeId, NodeInfo> {
+ /// (C-not exported) because we don't want to return lifetime'd references
+ pub fn nodes(&self) -> &IndexedMap<NodeId, NodeInfo> {
#[cfg(c_bindings)] // Non-bindings users should use `nodes`
/// Returns the list of nodes in the graph
pub fn list_nodes(&self) -> Vec<NodeId> {
#[cfg(c_bindings)] // Non-bindings users should use `nodes`
/// Returns the list of nodes in the graph
pub fn list_nodes(&self) -> Vec<NodeId> {
use crate::ln::features::InitFeatures;
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate, NodeAlias, MAX_EXCESS_BYTES_FOR_RELAY, NodeId, RoutingFees, ChannelUpdateInfo, ChannelInfo, NodeAnnouncementInfo, NodeInfo};
use crate::ln::msgs::{RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement,
use crate::ln::features::InitFeatures;
use crate::routing::gossip::{P2PGossipSync, NetworkGraph, NetworkUpdate, NodeAlias, MAX_EXCESS_BYTES_FOR_RELAY, NodeId, RoutingFees, ChannelUpdateInfo, ChannelInfo, NodeAnnouncementInfo, NodeInfo};
use crate::ln::msgs::{RoutingMessageHandler, UnsignedNodeAnnouncement, NodeAnnouncement,