}
}
+enum InitSyncTracker{
+ NoSyncRequested,
+ ChannelsSyncing(u64),
+ NodesSyncing(PublicKey),
+}
+
struct Peer {
channel_encryptor: PeerChannelEncryptor,
outbound: bool,
pending_read_buffer: Vec<u8>,
pending_read_buffer_pos: usize,
pending_read_is_header: bool,
+
+ sync_status: InitSyncTracker,
+}
+
+impl Peer {
+ /// Returns true if the the channel announcements/updates for the given channel should be
+ /// forwarded to this peer.
+ /// If we are sending our routing table to this peer and we have not yet sent channel
+ /// announcements/updates for the given channel_id then we will send it when we get to that
+ /// point and we shouldn't send it yet to avoid sending duplicate updates. If we've already
+ /// sent the old versions, we should send the update, and so return true here.
+ fn should_forward_channel(&self, channel_id: u64)->bool{
+ match self.sync_status {
+ InitSyncTracker::NoSyncRequested => true,
+ InitSyncTracker::ChannelsSyncing(i) => i < channel_id,
+ InitSyncTracker::NodesSyncing(_) => true,
+ }
+ }
}
struct PeerHolder<Descriptor: SocketDescriptor> {
pending_read_buffer: pending_read_buffer,
pending_read_buffer_pos: 0,
pending_read_is_header: false,
+
+ sync_status: InitSyncTracker::NoSyncRequested,
}).is_some() {
panic!("PeerManager driver duplicated descriptors!");
};
pending_read_buffer: pending_read_buffer,
pending_read_buffer_pos: 0,
pending_read_is_header: false,
+
+ sync_status: InitSyncTracker::NoSyncRequested,
}).is_some() {
panic!("PeerManager driver duplicated descriptors!");
};
Ok(())
}
- fn do_attempt_write_data(descriptor: &mut Descriptor, peer: &mut Peer) {
+ fn do_attempt_write_data(&self, descriptor: &mut Descriptor, peer: &mut Peer) {
+ macro_rules! encode_and_send_msg {
+ ($msg: expr, $msg_code: expr) => {
+ {
+ log_trace!(self, "Encoding and sending sync update message of type {} to {}", $msg_code, log_pubkey!(peer.their_node_id.unwrap()));
+ peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!($msg, $msg_code)[..]));
+ }
+ }
+ }
+ const MSG_BUFF_SIZE: usize = 10;
while !peer.awaiting_write_event {
+ if peer.pending_outbound_buffer.len() < MSG_BUFF_SIZE {
+ match peer.sync_status {
+ InitSyncTracker::NoSyncRequested => {},
+ InitSyncTracker::ChannelsSyncing(c) if c < 0xffff_ffff_ffff_ffff => {
+ let steps = ((MSG_BUFF_SIZE - peer.pending_outbound_buffer.len() + 2) / 3) as u8;
+ let all_messages = self.message_handler.route_handler.get_next_channel_announcements(0, steps);
+ for &(ref announce, ref update_a, ref update_b) in all_messages.iter() {
+ encode_and_send_msg!(announce, 256);
+ encode_and_send_msg!(update_a, 258);
+ encode_and_send_msg!(update_b, 258);
+ peer.sync_status = InitSyncTracker::ChannelsSyncing(announce.contents.short_channel_id + 1);
+ }
+ if all_messages.is_empty() || all_messages.len() != steps as usize {
+ peer.sync_status = InitSyncTracker::ChannelsSyncing(0xffff_ffff_ffff_ffff);
+ }
+ },
+ InitSyncTracker::ChannelsSyncing(c) if c == 0xffff_ffff_ffff_ffff => {
+ let steps = (MSG_BUFF_SIZE - peer.pending_outbound_buffer.len()) as u8;
+ let all_messages = self.message_handler.route_handler.get_next_node_announcements(None, steps);
+ for msg in all_messages.iter() {
+ encode_and_send_msg!(msg, 256);
+ peer.sync_status = InitSyncTracker::NodesSyncing(msg.contents.node_id);
+ }
+ if all_messages.is_empty() || all_messages.len() != steps as usize {
+ peer.sync_status = InitSyncTracker::NoSyncRequested;
+ }
+ },
+ InitSyncTracker::ChannelsSyncing(_) => unreachable!(),
+ InitSyncTracker::NodesSyncing(key) => {
+ let steps = (MSG_BUFF_SIZE - peer.pending_outbound_buffer.len()) as u8;
+ let all_messages = self.message_handler.route_handler.get_next_node_announcements(Some(&key), steps);
+ for msg in all_messages.iter() {
+ encode_and_send_msg!(msg, 256);
+ peer.sync_status = InitSyncTracker::NodesSyncing(msg.contents.node_id);
+ }
+ if all_messages.is_empty() || all_messages.len() != steps as usize {
+ peer.sync_status = InitSyncTracker::NoSyncRequested;
+ }
+ },
+ }
+ }
+
if {
let next_buff = match peer.pending_outbound_buffer.front() {
None => return,
Some(buff) => buff,
};
- let should_be_reading = peer.pending_outbound_buffer.len() < 10;
+ let should_be_reading = peer.pending_outbound_buffer.len() < MSG_BUFF_SIZE;
let data_sent = descriptor.send_data(next_buff, peer.pending_outbound_buffer_first_msg_offset, should_be_reading);
peer.pending_outbound_buffer_first_msg_offset += data_sent;
if peer.pending_outbound_buffer_first_msg_offset == next_buff.len() { true } else { false }
None => panic!("Descriptor for write_event is not already known to PeerManager"),
Some(peer) => {
peer.awaiting_write_event = false;
- Self::do_attempt_write_data(descriptor, peer);
+ self.do_attempt_write_data(descriptor, peer);
}
};
Ok(())
if msg.local_features.supports_unknown_bits() { "present" } else { "none" },
if msg.global_features.supports_unknown_bits() { "present" } else { "none" });
+ if msg.local_features.initial_routing_sync() {
+ peer.sync_status = InitSyncTracker::ChannelsSyncing(0);
+ peers.peers_needing_send.insert(peer_descriptor.clone());
+ }
peer.their_global_features = Some(msg.global_features);
peer.their_local_features = Some(msg.local_features);
self.initial_syncs_sent.fetch_add(1, Ordering::AcqRel);
local_features.set_initial_routing_sync();
}
+
encode_and_send_msg!(msgs::Init {
global_features: msgs::GlobalFeatures::new(),
local_features,
}
}
- Self::do_attempt_write_data(peer_descriptor, peer);
+ self.do_attempt_write_data(peer_descriptor, peer);
peer.pending_outbound_buffer.len() > 10 // pause_read
}
//TODO: Drop the pending channel? (or just let it timeout, but that sucks)
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 33)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::SendOpenChannel { ref node_id, ref msg } => {
log_trace!(self, "Handling SendOpenChannel event in peer_handler for node {} for channel {}",
//TODO: Drop the pending channel? (or just let it timeout, but that sucks)
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 32)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::SendFundingCreated { ref node_id, ref msg } => {
log_trace!(self, "Handling SendFundingCreated event in peer_handler for node {} for channel {} (which becomes {})",
//they should just throw away this funding transaction
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 34)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::SendFundingSigned { ref node_id, ref msg } => {
log_trace!(self, "Handling SendFundingSigned event in peer_handler for node {} for channel {}",
//they should just throw away this funding transaction
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 35)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => {
log_trace!(self, "Handling SendFundingLocked event in peer_handler for node {} for channel {}",
//TODO: Do whatever we're gonna do for handling dropped messages
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 36)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => {
log_trace!(self, "Handling SendAnnouncementSignatures event in peer_handler for node {} for channel {})",
//they should just throw away this funding transaction
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 259)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
log_trace!(self, "Handling UpdateHTLCs event in peer_handler for node {} with {} adds, {} fulfills, {} fails for channel {}",
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 134)));
}
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(commitment_signed, 132)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
log_trace!(self, "Handling SendRevokeAndACK event in peer_handler for node {} for channel {}",
//TODO: Do whatever we're gonna do for handling dropped messages
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 133)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::SendClosingSigned { ref node_id, ref msg } => {
log_trace!(self, "Handling SendClosingSigned event in peer_handler for node {} for channel {}",
//TODO: Do whatever we're gonna do for handling dropped messages
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 39)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::SendShutdown { ref node_id, ref msg } => {
log_trace!(self, "Handling Shutdown event in peer_handler for node {} for channel {}",
//TODO: Do whatever we're gonna do for handling dropped messages
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 38)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } => {
log_trace!(self, "Handling SendChannelReestablish event in peer_handler for node {} for channel {}",
//TODO: Do whatever we're gonna do for handling dropped messages
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 136)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
log_trace!(self, "Handling BroadcastChannelAnnouncement event in peer_handler for short channel id {}", msg.contents.short_channel_id);
let encoded_update_msg = encode_msg!(update_msg, 258);
for (ref descriptor, ref mut peer) in peers.peers.iter_mut() {
- if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_global_features.is_none() {
+ if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_global_features.is_none() ||
+ !peer.should_forward_channel(msg.contents.short_channel_id) {
continue
}
match peer.their_node_id {
}
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..]));
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_update_msg[..]));
- Self::do_attempt_write_data(&mut (*descriptor).clone(), peer);
+ self.do_attempt_write_data(&mut (*descriptor).clone(), peer);
}
}
},
let encoded_msg = encode_msg!(msg, 258);
for (ref descriptor, ref mut peer) in peers.peers.iter_mut() {
- if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_global_features.is_none() {
+ if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_global_features.is_none() ||
+ !peer.should_forward_channel(msg.contents.short_channel_id) {
continue
}
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..]));
- Self::do_attempt_write_data(&mut (*descriptor).clone(), peer);
+ self.do_attempt_write_data(&mut (*descriptor).clone(), peer);
}
}
},
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 17)));
// This isn't guaranteed to work, but if there is enough free
// room in the send buffer, put the error message there...
- Self::do_attempt_write_data(&mut descriptor, &mut peer);
+ self.do_attempt_write_data(&mut descriptor, &mut peer);
} else {
log_trace!(self, "Handling DisconnectPeer HandleError event in peer_handler for node {} with no message", log_pubkey!(node_id));
}
//TODO: Do whatever we're gonna do for handling dropped messages
});
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 17)));
- Self::do_attempt_write_data(&mut descriptor, peer);
+ self.do_attempt_write_data(&mut descriptor, peer);
},
}
} else {
for mut descriptor in peers.peers_needing_send.drain() {
match peers.peers.get_mut(&descriptor) {
- Some(peer) => Self::do_attempt_write_data(&mut descriptor, peer),
+ Some(peer) => self.do_attempt_write_data(&mut descriptor, peer),
None => panic!("Inconsistent peers set state!"),
}
}
use std::cmp;
use std::sync::{RwLock,Arc};
-use std::collections::{HashMap,BinaryHeap};
-use std::collections::hash_map::Entry;
+use std::collections::{HashMap,BinaryHeap,BTreeMap};
+use std::collections::btree_map::Entry as BtreeEntry;
use std;
/// A hop in a route
htlc_minimum_msat: u64,
fee_base_msat: u32,
fee_proportional_millionths: u32,
+ last_update_message: Option<msgs::ChannelUpdate>,
}
impl std::fmt::Display for DirectionalChannelInfo {
features: GlobalFeatures,
one_to_two: DirectionalChannelInfo,
two_to_one: DirectionalChannelInfo,
+ //this is cached here so we can send out it later if required by route_init_sync
+ //keep an eye on this to see if the extra memory is a problem
+ announcement_message: Option<msgs::ChannelAnnouncement>,
}
impl std::fmt::Display for ChannelInfo {
rgb: [u8; 3],
alias: [u8; 32],
addresses: Vec<NetAddress>,
+ //this is cached here so we can send out it later if required by route_init_sync
+ //keep an eye on this to see if the extra memory is a problem
+ announcement_message: Option<msgs::NodeAnnouncement>,
}
impl std::fmt::Display for NodeInfo {
struct NetworkMap {
#[cfg(feature = "non_bitcoin_chain_hash_routing")]
- channels: HashMap<(u64, Sha256dHash), ChannelInfo>,
+ channels: BTreeMap<(u64, Sha256dHash), ChannelInfo>,
#[cfg(not(feature = "non_bitcoin_chain_hash_routing"))]
- channels: HashMap<u64, ChannelInfo>,
+ channels: BTreeMap<u64, ChannelInfo>,
our_node_id: PublicKey,
- nodes: HashMap<PublicKey, NodeInfo>,
+ nodes: BTreeMap<PublicKey, NodeInfo>,
}
struct MutNetworkMap<'a> {
#[cfg(feature = "non_bitcoin_chain_hash_routing")]
- channels: &'a mut HashMap<(u64, Sha256dHash), ChannelInfo>,
+ channels: &'a mut BTreeMap<(u64, Sha256dHash), ChannelInfo>,
#[cfg(not(feature = "non_bitcoin_chain_hash_routing"))]
- channels: &'a mut HashMap<u64, ChannelInfo>,
- nodes: &'a mut HashMap<PublicKey, NodeInfo>,
+ channels: &'a mut BTreeMap<u64, ChannelInfo>,
+ nodes: &'a mut BTreeMap<PublicKey, NodeInfo>,
}
impl NetworkMap {
fn borrow_parts(&mut self) -> MutNetworkMap {
node.rgb = msg.contents.rgb;
node.alias = msg.contents.alias;
node.addresses = msg.contents.addresses.clone();
- Ok(msg.contents.excess_data.is_empty() && msg.contents.excess_address_data.is_empty() && !msg.contents.features.supports_unknown_bits())
+
+ let should_relay = msg.contents.excess_data.is_empty() && msg.contents.excess_address_data.is_empty() && !msg.contents.features.supports_unknown_bits();
+ node.announcement_message = if should_relay { Some(msg.clone()) } else { None };
+ Ok(should_relay)
}
}
}
let mut network_lock = self.network_map.write().unwrap();
let network = network_lock.borrow_parts();
+ let should_relay = msg.contents.excess_data.is_empty() && !msg.contents.features.supports_unknown_bits();
+
let chan_info = ChannelInfo {
features: msg.contents.features.clone(),
one_to_two: DirectionalChannelInfo {
htlc_minimum_msat: u64::max_value(),
fee_base_msat: u32::max_value(),
fee_proportional_millionths: u32::max_value(),
+ last_update_message: None,
},
two_to_one: DirectionalChannelInfo {
src_node_id: msg.contents.node_id_2.clone(),
htlc_minimum_msat: u64::max_value(),
fee_base_msat: u32::max_value(),
fee_proportional_millionths: u32::max_value(),
- }
+ last_update_message: None,
+ },
+ announcement_message: if should_relay { Some(msg.clone()) } else { None },
};
match network.channels.entry(NetworkMap::get_key(msg.contents.short_channel_id, msg.contents.chain_hash)) {
- Entry::Occupied(mut entry) => {
+ BtreeEntry::Occupied(mut entry) => {
//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 its unclear
//exactly how...
return Err(HandleError{err: "Already have knowledge of channel", action: Some(ErrorAction::IgnoreError)})
}
},
- Entry::Vacant(entry) => {
+ BtreeEntry::Vacant(entry) => {
entry.insert(chan_info);
}
};
macro_rules! add_channel_to_node {
( $node_id: expr ) => {
match network.nodes.entry($node_id) {
- Entry::Occupied(node_entry) => {
+ BtreeEntry::Occupied(node_entry) => {
node_entry.into_mut().channels.push(NetworkMap::get_key(msg.contents.short_channel_id, msg.contents.chain_hash));
},
- Entry::Vacant(node_entry) => {
+ BtreeEntry::Vacant(node_entry) => {
node_entry.insert(NodeInfo {
channels: vec!(NetworkMap::get_key(msg.contents.short_channel_id, msg.contents.chain_hash)),
lowest_inbound_channel_fee_base_msat: u32::max_value(),
rgb: [0; 3],
alias: [0; 32],
addresses: Vec::new(),
+ announcement_message: None,
});
}
}
add_channel_to_node!(msg.contents.node_id_1);
add_channel_to_node!(msg.contents.node_id_2);
- Ok(msg.contents.excess_data.is_empty() && !msg.contents.features.supports_unknown_bits())
+ Ok(should_relay)
}
fn handle_htlc_fail_channel_update(&self, update: &msgs::HTLCFailChannelUpdate) {
$target.htlc_minimum_msat = msg.contents.htlc_minimum_msat;
$target.fee_base_msat = msg.contents.fee_base_msat;
$target.fee_proportional_millionths = msg.contents.fee_proportional_millionths;
+ $target.last_update_message = if msg.contents.excess_data.is_empty() {
+ Some(msg.clone())
+ } else {
+ None
+ };
}
}
-
let msg_hash = Message::from_slice(&Sha256dHash::from_data(&msg.contents.encode()[..])[..]).unwrap();
if msg.contents.flags & 1 == 1 {
dest_node_id = channel.one_to_two.src_node_id.clone();
Ok(msg.contents.excess_data.is_empty())
}
+
+
+ fn get_next_channel_announcements(&self, starting_point: u64, batch_amount: u8) -> Vec<(msgs::ChannelAnnouncement, msgs::ChannelUpdate,msgs::ChannelUpdate)> {
+ let mut result = Vec::with_capacity(batch_amount as usize);
+ let network = self.network_map.read().unwrap();
+ let mut iter = network.channels.range(starting_point..);
+ while result.len() < batch_amount as usize {
+ if let Some((_, ref chan)) = iter.next() {
+ if chan.announcement_message.is_some() &&
+ chan.one_to_two.last_update_message.is_some() &&
+ chan.two_to_one.last_update_message.is_some() {
+ result.push((chan.announcement_message.clone().unwrap(),
+ chan.one_to_two.last_update_message.clone().unwrap(),
+ chan.two_to_one.last_update_message.clone().unwrap()));
+ } else {
+ // TODO: We may end up sending un-announced channel_updates if we are sending
+ // initial sync data while receiving announce/updates for this channel.
+ }
+ } else {
+ return result;
+ }
+ }
+ result
+ }
+
+ fn get_next_node_announcements(&self, starting_point: Option<&PublicKey>, batch_amount: u8) -> Vec<msgs::NodeAnnouncement> {
+ let mut result = Vec::with_capacity(batch_amount as usize);
+ let network = self.network_map.read().unwrap();
+ let mut iter = if let Some(pubkey) = starting_point {
+ let mut iter = network.nodes.range((*pubkey)..);
+ iter.next();
+ iter
+ } else {
+ network.nodes.range(..)
+ };
+ while result.len() < batch_amount as usize {
+ if let Some((_, ref node)) = iter.next() {
+ if node.announcement_message.is_some() {
+ result.push(node.announcement_message.clone().unwrap());
+ }
+ } else {
+ return result;
+ }
+ }
+ result
+ }
}
#[derive(Eq, PartialEq)]
impl Router {
/// Creates a new router with the given node_id to be used as the source for get_route()
pub fn new(our_pubkey: PublicKey, chain_monitor: Arc<ChainWatchInterface>, logger: Arc<Logger>) -> Router {
- let mut nodes = HashMap::new();
+ let mut nodes = BTreeMap::new();
nodes.insert(our_pubkey.clone(), NodeInfo {
channels: Vec::new(),
lowest_inbound_channel_fee_base_msat: u32::max_value(),
rgb: [0; 3],
alias: [0; 32],
addresses: Vec::new(),
+ announcement_message: None,
});
Router {
secp_ctx: Secp256k1::verification_only(),
network_map: RwLock::new(NetworkMap {
- channels: HashMap::new(),
+ channels: BTreeMap::new(),
our_node_id: our_pubkey,
nodes: nodes,
}),
unimplemented!();
}
- fn remove_channel_in_nodes(nodes: &mut HashMap<PublicKey, NodeInfo>, chan: &ChannelInfo, short_channel_id: u64) {
+ fn remove_channel_in_nodes(nodes: &mut BTreeMap<PublicKey, NodeInfo>, chan: &ChannelInfo, short_channel_id: u64) {
macro_rules! remove_from_node {
($node_id: expr) => {
- if let Entry::Occupied(mut entry) = nodes.entry($node_id) {
+ if let BtreeEntry::Occupied(mut entry) = nodes.entry($node_id) {
entry.get_mut().channels.retain(|chan_id| {
short_channel_id != *NetworkMap::get_short_id(chan_id)
});
rgb: [0; 3],
alias: [0; 32],
addresses: Vec::new(),
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(1, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: u32::max_value(), // This value should be ignored
fee_proportional_millionths: u32::max_value(), // This value should be ignored
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node1.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
network.nodes.insert(node2.clone(), NodeInfo {
channels: vec!(NetworkMap::get_key(2, zero_hash.clone()), NetworkMap::get_key(4, zero_hash.clone())),
rgb: [0; 3],
alias: [0; 32],
addresses: Vec::new(),
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(2, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: u32::max_value(), // This value should be ignored
fee_proportional_millionths: u32::max_value(), // This value should be ignored
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node2.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
network.nodes.insert(node8.clone(), NodeInfo {
channels: vec!(NetworkMap::get_key(12, zero_hash.clone()), NetworkMap::get_key(13, zero_hash.clone())),
rgb: [0; 3],
alias: [0; 32],
addresses: Vec::new(),
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(12, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: u32::max_value(), // This value should be ignored
fee_proportional_millionths: u32::max_value(), // This value should be ignored
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node8.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
network.nodes.insert(node3.clone(), NodeInfo {
channels: vec!(
rgb: [0; 3],
alias: [0; 32],
addresses: Vec::new(),
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(3, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node3.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 100,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(4, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 1000000,
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node3.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(13, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 2000000,
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node3.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
network.nodes.insert(node4.clone(), NodeInfo {
channels: vec!(NetworkMap::get_key(5, zero_hash.clone()), NetworkMap::get_key(11, zero_hash.clone())),
rgb: [0; 3],
alias: [0; 32],
addresses: Vec::new(),
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(5, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: 100,
fee_proportional_millionths: 0,
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node4.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
network.nodes.insert(node5.clone(), NodeInfo {
channels: vec!(NetworkMap::get_key(6, zero_hash.clone()), NetworkMap::get_key(11, zero_hash.clone())),
rgb: [0; 3],
alias: [0; 32],
addresses: Vec::new(),
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(6, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node5.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(11, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node4.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
network.nodes.insert(node6.clone(), NodeInfo {
channels: vec!(NetworkMap::get_key(7, zero_hash.clone())),
rgb: [0; 3],
alias: [0; 32],
addresses: Vec::new(),
+ announcement_message: None,
});
network.channels.insert(NetworkMap::get_key(7, zero_hash.clone()), ChannelInfo {
features: GlobalFeatures::new(),
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 1000000,
+ last_update_message: None,
}, two_to_one: DirectionalChannelInfo {
src_node_id: node6.clone(),
last_update: 0,
htlc_minimum_msat: 0,
fee_base_msat: 0,
fee_proportional_millionths: 0,
+ last_update_message: None,
},
+ announcement_message: None,
});
}