Skip to content

Commit 3d80b58

Browse files
Consider channel_ids in short_to_chan_info as unguaranteed
As the `short_to_chan_info` map has been removed from the `channel_state`, there is no longer any consistency guarantees between the `by_id` and `short_to_chan_info` maps. This commit ensures that we don't force unwrap channels where the channel_id has been queried from the `short_to_chan_info` map.
1 parent 5856f53 commit 3d80b58

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2317,7 +2317,14 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
23172317
Some((_cp_id, chan_id)) => Some(chan_id.clone()),
23182318
};
23192319
let chan_update_opt = if let Some(forwarding_id) = forwarding_id_opt {
2320-
let chan = channel_state.by_id.get_mut(&forwarding_id).unwrap();
2320+
let chan = match channel_state.by_id.get_mut(&forwarding_id) {
2321+
None => {
2322+
// Channel was removed. The short_to_chan_info and by_id maps have
2323+
// no consistency guarantees.
2324+
break Some(("Don't have available channel for forwarding as requested.", 0x4000 | 10, None));
2325+
},
2326+
Some(chan) => chan
2327+
};
23212328
if !chan.should_announce() && !self.default_configuration.accept_forwards_to_priv_channels {
23222329
// Note that the behavior here should be identical to the above block - we
23232330
// should NOT reveal the existence or non-existence of a private channel if
@@ -2544,7 +2551,12 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
25442551
},
25452552
None => { },
25462553
}
2547-
} else { unreachable!(); }
2554+
} else {
2555+
// The channel was likely removed after we fetched the id from the
2556+
// `short_to_chan_info` map, but before we successfully locked the `by_id` map.
2557+
// This can occur as no consistency guarantees exists between the two maps.
2558+
return Err(APIError::ChannelUnavailable{err: "No channel available with first hop!".to_owned()});
2559+
}
25482560
return Ok(());
25492561
};
25502562

@@ -3133,9 +3145,8 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
31333145
let mut channel_state_lock = self.channel_state.lock().unwrap();
31343146
let channel_state = &mut *channel_state_lock;
31353147
if short_chan_id != 0 {
3136-
let forward_chan_id = match self.short_to_chan_info.read().unwrap().get(&short_chan_id) {
3137-
Some((_cp_id, chan_id)) => chan_id.clone(),
3138-
None => {
3148+
macro_rules! forwarding_channel_not_found {
3149+
() => {
31393150
for forward_info in pending_forwards.drain(..) {
31403151
match forward_info {
31413152
HTLCForwardInfo::AddHTLC { prev_short_channel_id, prev_htlc_id, forward_info: PendingHTLCInfo {
@@ -3222,6 +3233,12 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
32223233
}
32233234
}
32243235
}
3236+
}
3237+
}
3238+
let forward_chan_id = match self.short_to_chan_info.read().unwrap().get(&short_chan_id) {
3239+
Some((_cp_id, chan_id)) => chan_id.clone(),
3240+
None => {
3241+
forwarding_channel_not_found!();
32253242
continue;
32263243
}
32273244
};
@@ -3351,7 +3368,8 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
33513368
});
33523369
}
33533370
} else {
3354-
unreachable!();
3371+
forwarding_channel_not_found!();
3372+
continue;
33553373
}
33563374
} else {
33573375
for forward_info in pending_forwards.drain(..) {
@@ -4301,7 +4319,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
43014319
return ClaimFundsFromHop::MonitorUpdateFail(counterparty_node_id, res, None);
43024320
},
43034321
}
4304-
} else { unreachable!(); }
4322+
} else { return ClaimFundsFromHop::PrevHopForceClosed }
43054323
}
43064324

43074325
fn finalize_claims(&self, mut sources: Vec<HTLCSource>) {
@@ -5217,7 +5235,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
52175235
try_chan_entry!(self, chan.get_mut().channel_update(&msg), chan);
52185236
}
52195237
},
5220-
hash_map::Entry::Vacant(_) => unreachable!()
5238+
hash_map::Entry::Vacant(_) => return Ok(NotifyOption::SkipPersist)
52215239
}
52225240
Ok(NotifyOption::DoPersist)
52235241
}

0 commit comments

Comments
 (0)