use util::{byte_utils, events};
use std::collections::{HashMap, hash_map, HashSet};
-use std::sync::{Arc,Mutex};
+use std::sync::{Arc,Mutex, MutexGuard};
use std::{hash,cmp, mem};
use std::ops::Deref;
fn get_and_clear_pending_htlcs_updated(&self) -> Vec<HTLCUpdate>;
}
+/// A lock held on a specific ManyChannelMonitor that includes a reference to the current version
+/// of a ChannelMonitor contained within.
+pub struct ManyChannelMonitorLock<'a, Key, ChanSigner: ChannelKeys> {
+ lock_ptr: *mut MutexGuard<'a, HashMap<Key, ChannelMonitor<ChanSigner>>>,
+ monitor: &'a ChannelMonitor<ChanSigner>,
+}
+impl<'a, Key, ChanSigner: ChannelKeys> ::std::ops::Deref for ManyChannelMonitorLock<'a, Key, ChanSigner> {
+ type Target = ChannelMonitor<ChanSigner>;
+ fn deref(&self) -> &ChannelMonitor<ChanSigner> {
+ self.monitor
+ }
+}
+impl<'a, Key, ChanSigner: ChannelKeys> Drop for ManyChannelMonitorLock<'a, Key, ChanSigner> {
+ fn drop(&mut self) {
+ // Dereferencing the lock_ptr is trivially safe here - it is created when this object is
+ // created, is never null, and is not modified at any point other than creation.
+ let _ = unsafe { Box::from_raw(self.lock_ptr) };
+ // Drop the box, freeing the lock
+ }
+}
+
/// A simple implementation of a ManyChannelMonitor and ChainListener. Can be used to create a
/// watchtower or watch our own channels.
///
None => Err(MonitorUpdateError("No such monitor registered"))
}
}
+
+ /// Gets a reference to the latest copy of a given ChannelMonitor given a &Key, if any has been
+ /// registered.
+ ///
+ /// The returned value contains a lock on this object, and other calls into this object will
+ /// almost certainly block until the returned value is dropped!
+ pub fn get_monitor_ref_by_key<'a>(&'a self, key: &Key) -> Option<ManyChannelMonitorLock<'a, Key, ChanSigner>> {
+ // Rust doesn't natively allow self-referential structs, and the only way to return a
+ // reference to something inside our Mutex is to return a struct that contains the lock and
+ // a reference to something pulled out of said lock.
+ // To avoid this, we have to fall back to some use of unsafe, but luckily its incredibly
+ // trivial - we simply Box up the MutexGuard and Box::leak() it, ensuring that its sitting
+ // in our heap without Rust having any reference to drop it.
+ // Then, we do a map lookup against the raw pointer, either returning a
+ // ManyChannelMonitorMonRef (which will drop the lock by recreating the Box when it gets
+ // dropped), or we will recreate the Box immediately and drop the lock before returning
+ // None.
+ //
+ // The returned ManyChannelMonitorMonRef is templated by a lifetime for which &self is
+ // valid, ensuring this object cannot be dropped until after the returned value is.
+ let lock = Box::new(self.monitors.lock().unwrap());
+ let lock_ptr: *mut MutexGuard<HashMap<Key, ChannelMonitor<ChanSigner>>> = Box::leak(lock);
+ let mon = unsafe { (*lock_ptr).get(key) };
+ if let Some(monitor) = mon {
+ Some(ManyChannelMonitorLock { lock_ptr, monitor })
+ } else {
+ let _ = unsafe { Box::from_raw(lock_ptr) };
+ // Drop the lock again
+ None
+ }
+ }
}
impl<ChanSigner: ChannelKeys, T: Deref + Sync + Send, F: Deref + Sync + Send> ManyChannelMonitor<ChanSigner> for SimpleManyChannelMonitor<OutPoint, ChanSigner, T, F>