use bitcoin::hashes::sha256d::Hash as Sha256dHash;
use bitcoin::hashes::Hash;
+use bitcoin::hashes::hex::FromHex;
use bitcoin::hash_types::BlockHash;
use bitcoin::network::constants::Network;
use crate::io_extras::{copy, sink};
use crate::prelude::*;
use core::{cmp, fmt};
+use core::convert::TryFrom;
use crate::sync::{RwLock, RwLockReadGuard};
#[cfg(feature = "std")]
use core::sync::atomic::{AtomicUsize, Ordering};
use crate::sync::Mutex;
use core::ops::{Bound, Deref};
+use core::str::FromStr;
#[cfg(feature = "std")]
use std::time::{SystemTime, UNIX_EPOCH};
pub fn as_slice(&self) -> &[u8] {
&self.0
}
+
+ /// Get the public key from this NodeId
+ pub fn as_pubkey(&self) -> Result<PublicKey, secp256k1::Error> {
+ PublicKey::from_slice(&self.0)
+ }
}
impl fmt::Debug for NodeId {
}
}
+impl From<PublicKey> for NodeId {
+ fn from(pubkey: PublicKey) -> Self {
+ Self::from_pubkey(&pubkey)
+ }
+}
+
+impl TryFrom<NodeId> for PublicKey {
+ type Error = secp256k1::Error;
+
+ fn try_from(node_id: NodeId) -> Result<Self, Self::Error> {
+ node_id.as_pubkey()
+ }
+}
+
+impl FromStr for NodeId {
+ type Err = bitcoin::hashes::hex::Error;
+
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let data: [u8; PUBLIC_KEY_SIZE] = FromHex::from_hex(s)?;
+ Ok(NodeId(data))
+ }
+}
+
/// Represents the network as nodes and channels between them
pub struct NetworkGraph<L: Deref> where L::Target: Logger {
secp_ctx: Secp256k1<secp256k1::VerifyOnly>,
msg: ChannelUpdate,
},
/// An error indicating that a channel failed to route a payment, which should be applied via
- /// [`NetworkGraph::channel_failed`].
+ /// [`NetworkGraph::channel_failed_permanent`] if permanent.
ChannelFailure {
/// The short channel id of the closed channel.
short_channel_id: u64,
let _ = self.update_channel(msg);
},
NetworkUpdate::ChannelFailure { short_channel_id, is_permanent } => {
- let action = if is_permanent { "Removing" } else { "Disabling" };
- log_debug!(self.logger, "{} channel graph entry for {} due to a payment failure.", action, short_channel_id);
- self.channel_failed(short_channel_id, is_permanent);
+ if is_permanent {
+ log_debug!(self.logger, "Removing channel graph entry for {} due to a payment failure.", short_channel_id);
+ self.channel_failed_permanent(short_channel_id);
+ }
},
NetworkUpdate::NodeFailure { ref node_id, is_permanent } => {
if is_permanent {
///
/// Since node aliases are provided by third parties, they are a potential avenue for injection
/// attacks. Care must be taken when processing.
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct NodeAlias(pub [u8; 32]);
impl fmt::Display for NodeAlias {
features: msg.features.clone(),
last_update: msg.timestamp,
rgb: msg.rgb,
- alias: NodeAlias(msg.alias),
+ alias: msg.alias,
announcement_message: if should_relay { full_msg.cloned() } else { None },
});
Ok(())
}
- /// Marks a channel in the graph as failed if a corresponding HTLC fail was sent.
- /// If permanent, removes a channel from the local storage.
- /// May cause the removal of nodes too, if this was their last channel.
- /// If not permanent, makes channels unavailable for routing.
- pub fn channel_failed(&self, short_channel_id: u64, is_permanent: bool) {
+ /// Marks a channel in the graph as failed permanently.
+ ///
+ /// The channel and any node for which this was their last channel are removed from the graph.
+ pub fn channel_failed_permanent(&self, short_channel_id: u64) {
#[cfg(feature = "std")]
let current_time_unix = Some(SystemTime::now().duration_since(UNIX_EPOCH).expect("Time must be > 1970").as_secs());
#[cfg(not(feature = "std"))]
let current_time_unix = None;
- self.channel_failed_with_time(short_channel_id, is_permanent, current_time_unix)
+ self.channel_failed_permanent_with_time(short_channel_id, current_time_unix)
}
- /// Marks a channel in the graph as failed if a corresponding HTLC fail was sent.
- /// If permanent, removes a channel from the local storage.
- /// May cause the removal of nodes too, if this was their last channel.
- /// If not permanent, makes channels unavailable for routing.
- fn channel_failed_with_time(&self, short_channel_id: u64, is_permanent: bool, current_time_unix: Option<u64>) {
+ /// Marks a channel in the graph as failed permanently.
+ ///
+ /// The channel and any node for which this was their last channel are removed from the graph.
+ fn channel_failed_permanent_with_time(&self, short_channel_id: u64, current_time_unix: Option<u64>) {
let mut channels = self.channels.write().unwrap();
- if is_permanent {
- if let Some(chan) = channels.remove(&short_channel_id) {
- let mut nodes = self.nodes.write().unwrap();
- self.removed_channels.lock().unwrap().insert(short_channel_id, current_time_unix);
- Self::remove_channel_in_nodes(&mut nodes, &chan, short_channel_id);
- }
- } else {
- if let Some(chan) = channels.get_mut(&short_channel_id) {
- if let Some(one_to_two) = chan.one_to_two.as_mut() {
- one_to_two.enabled = false;
- }
- if let Some(two_to_one) = chan.two_to_one.as_mut() {
- two_to_one.enabled = false;
- }
- }
+ if let Some(chan) = channels.remove(&short_channel_id) {
+ let mut nodes = self.nodes.write().unwrap();
+ self.removed_channels.lock().unwrap().insert(short_channel_id, current_time_unix);
+ Self::remove_channel_in_nodes(&mut nodes, &chan, short_channel_id);
}
}
timestamp: 100,
node_id,
rgb: [0; 3],
- alias: [0; 32],
+ alias: NodeAlias([0; 32]),
addresses: Vec::new(),
excess_address_data: Vec::new(),
excess_data: Vec::new(),
assert!(network_graph.read_only().channels().get(&short_channel_id).unwrap().one_to_two.is_some());
}
- // Non-permanent closing just disables a channel
+ // Non-permanent failure doesn't touch the channel at all
{
match network_graph.read_only().channels().get(&short_channel_id) {
None => panic!(),
match network_graph.read_only().channels().get(&short_channel_id) {
None => panic!(),
Some(channel_info) => {
- assert!(!channel_info.one_to_two.as_ref().unwrap().enabled);
+ assert!(channel_info.one_to_two.as_ref().unwrap().enabled);
}
};
}
// Mark the channel as permanently failed. This will also remove the two nodes
// and all of the entries will be tracked as removed.
- network_graph.channel_failed_with_time(short_channel_id, true, Some(tracking_time));
+ network_graph.channel_failed_permanent_with_time(short_channel_id, Some(tracking_time));
// Should not remove from tracking if insufficient time has passed
network_graph.remove_stale_channels_and_tracking_with_time(
// Mark the channel as permanently failed. This will also remove the two nodes
// and all of the entries will be tracked as removed.
- network_graph.channel_failed(short_channel_id, true);
+ network_graph.channel_failed_permanent(short_channel_id);
// The first time we call the following, the channel will have a removal time assigned.
network_graph.remove_stale_channels_and_tracking_with_time(removal_time);