use util::{byte_utils, events};
use std::collections::{HashMap, hash_map};
-use std::sync::Mutex;
+use std::sync::{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, L: Deref + Sync + Send, C: Deref + Sync + Send> ManyChannelMonitor<ChanSigner> for SimpleManyChannelMonitor<OutPoint, ChanSigner, T, F, L, C>
Vec::new()
}
- /// Called by SimpleManyChannelMonitor::block_connected, which implements
- /// ChainListener::block_connected.
- /// Eventually this should be pub and, roughly, implement ChainListener, however this requires
- /// &mut self, as well as returns new spendable outputs and outpoints to watch for spending of
- /// on-chain.
- fn block_connected<B: Deref, F: Deref, L: Deref>(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F, logger: L)-> Vec<(Txid, Vec<TxOut>)>
+ /// Called when a new block has been connected to the best chain by <SimpleManyChannelMonitor
+ /// as ChainListener>::block_connected, and should thus generally not be called during normal
+ /// operation. It is exposed both for users who wish to use ChannelMonitors directly and to
+ /// simplify rescans that occur at load-time.
+ ///
+ /// This is very similar to ChainListener::block_connected itself, but requires an &mut self,
+ /// and an explicit reference to a transaction broadcaster and fee estimator.
+ ///
+ /// Returns a list of new (txid, outputs) pairs which spends of must be watched for. Note that
+ /// after this call these are also available via get_outputs_to_watch().
+ pub fn block_connected<B: Deref, F: Deref, L: Deref>(&mut self, txn_matched: &[&Transaction], height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F, logger: L)-> Vec<(Txid, Vec<TxOut>)>
where B::Target: BroadcasterInterface,
F::Target: FeeEstimator,
L::Target: Logger,
watch_outputs
}
- fn block_disconnected<B: Deref, F: Deref, L: Deref>(&mut self, height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F, logger: L)
+ /// Called when a block has been disconnected from the best chain by <SimpleManyChannelMonitor
+ /// as ChainListener>::block_disconnected, and should thus generally not be called during
+ /// normal operation. It is exposed both for users who wish to use ChannelMonitors directly and
+ /// to simplify rescans that occur at load-time.
+ ///
+ /// This is very similar to ChainListener::block_disconnected itself, but requires an &mut self,
+ /// and an explicit reference to a transaction broadcaster and fee estimator.
+ pub fn block_disconnected<B: Deref, F: Deref, L: Deref>(&mut self, height: u32, block_hash: &BlockHash, broadcaster: B, fee_estimator: F, logger: L)
where B::Target: BroadcasterInterface,
F::Target: FeeEstimator,
L::Target: Logger,