Skip to content

Commit a29d25a

Browse files
committed
Keep track of the Init Features for every connected/channel'd peer
Since we want to keep track of the Init-context features for every peer we have channels with, we have to keep them for as long as the peer is connected (since we may open a channel with them at any point). We go ahead and take this opportunity to create a new per-peer-state struct which has two levels of mutexes which is appropriate for moving channel storage to. Since we can't process messages from a given peer in parallel, the inner lock is a regular mutex, but the outer lock is RW so that we can process for different peers at the same time with an outer read lock.
1 parent 79d050f commit a29d25a

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

lightning/src/ln/channelmanager.rs

+59-1
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ pub(super) struct ChannelHolder<ChanSigner: ChannelKeys> {
275275
pub(super) pending_msg_events: Vec<events::MessageSendEvent>,
276276
}
277277

278+
/// State we hold per-peer. In the future we should put channels in here, but for now we only hold
279+
/// the latest Init features we heard from the peer.
280+
struct PeerState {
281+
latest_features: InitFeatures,
282+
}
283+
278284
#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))]
279285
const ERR: () = "You need at least 32 bit pointers (well, usize, but we'll assume they're the same) for ChannelManager::latest_block_height";
280286

@@ -328,6 +334,14 @@ pub struct ChannelManager<ChanSigner: ChannelKeys> {
328334
channel_state: Mutex<ChannelHolder<ChanSigner>>,
329335
our_network_key: SecretKey,
330336

337+
/// The bulk of our storage will eventually be here (channels and message queues and the like).
338+
/// If we are connected to a peer we always at least have an entry here, even if no channels
339+
/// are currently open with that peer.
340+
/// Because adding or removing an entry is rare, we usually take an outer read lock and then
341+
/// operate on the inner value freely. Sadly, this prevents parallel operation when opening a
342+
/// new channel.
343+
per_peer_state: RwLock<HashMap<PublicKey, Mutex<PeerState>>>,
344+
331345
pending_events: Mutex<Vec<events::Event>>,
332346
/// Used when we have to take a BIG lock to make sure everything is self-consistent.
333347
/// Essentially just when we're serializing ourselves out.
@@ -610,6 +624,8 @@ impl<ChanSigner: ChannelKeys> ChannelManager<ChanSigner> {
610624
}),
611625
our_network_key: keys_manager.get_node_secret(),
612626

627+
per_peer_state: RwLock::new(HashMap::new()),
628+
613629
pending_events: Mutex::new(Vec::new()),
614630
total_consistency_lock: RwLock::new(()),
615631

@@ -2780,6 +2796,7 @@ impl<ChanSigner: ChannelKeys> ChannelMessageHandler for ChannelManager<ChanSigne
27802796
let _ = self.total_consistency_lock.read().unwrap();
27812797
let mut failed_channels = Vec::new();
27822798
let mut failed_payments = Vec::new();
2799+
let mut no_channels_remain = true;
27832800
{
27842801
let mut channel_state_lock = self.channel_state.lock().unwrap();
27852802
let channel_state = &mut *channel_state_lock;
@@ -2818,6 +2835,8 @@ impl<ChanSigner: ChannelKeys> ChannelMessageHandler for ChannelManager<ChanSigne
28182835
short_to_id.remove(&short_id);
28192836
}
28202837
return false;
2838+
} else {
2839+
no_channels_remain = false;
28212840
}
28222841
}
28232842
true
@@ -2843,6 +2862,10 @@ impl<ChanSigner: ChannelKeys> ChannelMessageHandler for ChannelManager<ChanSigne
28432862
}
28442863
});
28452864
}
2865+
if no_channels_remain {
2866+
self.per_peer_state.write().unwrap().remove(their_node_id);
2867+
}
2868+
28462869
for failure in failed_channels.drain(..) {
28472870
self.finish_force_close_channel(failure);
28482871
}
@@ -2853,10 +2876,25 @@ impl<ChanSigner: ChannelKeys> ChannelMessageHandler for ChannelManager<ChanSigne
28532876
}
28542877
}
28552878

2856-
fn peer_connected(&self, their_node_id: &PublicKey, _init_msg: &msgs::Init) {
2879+
fn peer_connected(&self, their_node_id: &PublicKey, init_msg: &msgs::Init) {
28572880
log_debug!(self, "Generating channel_reestablish events for {}", log_pubkey!(their_node_id));
28582881

28592882
let _ = self.total_consistency_lock.read().unwrap();
2883+
2884+
{
2885+
let mut peer_state_lock = self.per_peer_state.write().unwrap();
2886+
match peer_state_lock.entry(their_node_id.clone()) {
2887+
hash_map::Entry::Vacant(e) => {
2888+
e.insert(Mutex::new(PeerState {
2889+
latest_features: init_msg.features.clone(),
2890+
}));
2891+
},
2892+
hash_map::Entry::Occupied(e) => {
2893+
e.get().lock().unwrap().latest_features = init_msg.features.clone();
2894+
},
2895+
}
2896+
}
2897+
28602898
let mut channel_state_lock = self.channel_state.lock().unwrap();
28612899
let channel_state = &mut *channel_state_lock;
28622900
let pending_msg_events = &mut channel_state.pending_msg_events;
@@ -3123,6 +3161,14 @@ impl<ChanSigner: ChannelKeys + Writeable> Writeable for ChannelManager<ChanSigne
31233161
}
31243162
}
31253163

3164+
let per_peer_state = self.per_peer_state.write().unwrap();
3165+
(per_peer_state.len() as u64).write(writer)?;
3166+
for (peer_pubkey, peer_state_mutex) in per_peer_state.iter() {
3167+
peer_pubkey.write(writer)?;
3168+
let peer_state = peer_state_mutex.lock().unwrap();
3169+
peer_state.latest_features.write(writer)?;
3170+
}
3171+
31263172
Ok(())
31273173
}
31283174
}
@@ -3256,6 +3302,16 @@ impl<'a, R : ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArg
32563302
claimable_htlcs.insert(payment_hash, previous_hops);
32573303
}
32583304

3305+
let peer_count: u64 = Readable::read(reader)?;
3306+
let mut per_peer_state = HashMap::with_capacity(cmp::min(peer_count as usize, 128));
3307+
for _ in 0..peer_count {
3308+
let peer_pubkey = Readable::read(reader)?;
3309+
let peer_state = PeerState {
3310+
latest_features: Readable::read(reader)?,
3311+
};
3312+
per_peer_state.insert(peer_pubkey, Mutex::new(peer_state));
3313+
}
3314+
32593315
let channel_manager = ChannelManager {
32603316
genesis_hash,
32613317
fee_estimator: args.fee_estimator,
@@ -3275,6 +3331,8 @@ impl<'a, R : ::std::io::Read, ChanSigner: ChannelKeys + Readable<R>> ReadableArg
32753331
}),
32763332
our_network_key: args.keys_manager.get_node_secret(),
32773333

3334+
per_peer_state: RwLock::new(per_peer_state),
3335+
32783336
pending_events: Mutex::new(Vec::new()),
32793337
total_consistency_lock: RwLock::new(()),
32803338
keys_manager: args.keys_manager,

0 commit comments

Comments
 (0)