Skip to content

Commit 662f13a

Browse files
committed
Test that we don't forget to track any outputs at monitor-load
This tests, after each functional test, that if we serialize and reload all of our ChannelMonitors we end up tracking the same set of outputs as before.
1 parent 73dce20 commit 662f13a

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

lightning/src/chain/chaininterface.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ pub trait FeeEstimator: Sync + Send {
126126
pub const MIN_RELAY_FEE_SAT_PER_1000_WEIGHT: u64 = 4000;
127127

128128
/// Utility for tracking registered txn/outpoints and checking for matches
129+
#[cfg_attr(test, derive(PartialEq))]
129130
pub struct ChainWatchedUtil {
130131
watch_all: bool,
131132

@@ -305,6 +306,17 @@ pub struct ChainWatchInterfaceUtil {
305306
logger: Arc<Logger>,
306307
}
307308

309+
// We only expose PartialEq in test since its somewhat unclear exactly what it should do and we're
310+
// only comparing a subset of fields (essentially just checking that the set of things we're
311+
// watching is the same).
312+
#[cfg(test)]
313+
impl PartialEq for ChainWatchInterfaceUtil {
314+
fn eq(&self, o: &Self) -> bool {
315+
self.network == o.network &&
316+
*self.watched.lock().unwrap() == *o.watched.lock().unwrap()
317+
}
318+
}
319+
308320
/// Register listener
309321
impl ChainWatchInterface for ChainWatchInterfaceUtil {
310322
fn install_watch_tx(&self, txid: &Sha256dHash, script_pub_key: &Script) {

lightning/src/ln/functional_test_utils.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use chain::chaininterface;
55
use chain::transaction::OutPoint;
66
use chain::keysinterface::KeysInterface;
77
use ln::channelmanager::{ChannelManager,RAACommitmentOrder, PaymentPreimage, PaymentHash};
8+
use ln::channelmonitor::{ChannelMonitor, ManyChannelMonitor};
89
use ln::router::{Route, Router};
910
use ln::features::InitFeatures;
1011
use ln::msgs;
@@ -16,6 +17,7 @@ use util::events::{Event, EventsProvider, MessageSendEvent, MessageSendEventsPro
1617
use util::errors::APIError;
1718
use util::logger::Logger;
1819
use util::config::UserConfig;
20+
use util::ser::ReadableArgs;
1921

2022
use bitcoin::util::hash::BitcoinHash;
2123
use bitcoin::blockdata::block::BlockHeader;
@@ -89,6 +91,27 @@ impl<'a, 'b> Drop for Node<'a, 'b> {
8991
assert!(self.node.get_and_clear_pending_msg_events().is_empty());
9092
assert!(self.node.get_and_clear_pending_events().is_empty());
9193
assert!(self.chan_monitor.added_monitors.lock().unwrap().is_empty());
94+
95+
// Check that if we serialize and then deserialize all our channel monitors we get the
96+
// same set of outputs to watch for on chain as we have now. Note that if we write
97+
// tests that fully close channels and remove the monitors at some point this may break.
98+
let chain_watch = Arc::new(chaininterface::ChainWatchInterfaceUtil::new(Network::Testnet, Arc::clone(&self.logger) as Arc<Logger>));
99+
let feeest = Arc::new(test_utils::TestFeeEstimator { sat_per_kw: 253 });
100+
let channel_monitor = test_utils::TestChannelMonitor::new(chain_watch.clone(), self.tx_broadcaster.clone(), self.logger.clone(), feeest);
101+
let old_monitors = self.chan_monitor.simple_monitor.monitors.lock().unwrap();
102+
for (_, old_monitor) in old_monitors.iter() {
103+
let mut w = test_utils::TestVecWriter(Vec::new());
104+
old_monitor.write_for_disk(&mut w).unwrap();
105+
let (_, deserialized_monitor) = <(Sha256d, ChannelMonitor<EnforcingChannelKeys>)>::read(
106+
&mut ::std::io::Cursor::new(&w.0), Arc::clone(&self.logger) as Arc<Logger>).unwrap();
107+
if let Err(_) = channel_monitor.add_update_monitor(deserialized_monitor.get_funding_txo().unwrap(), deserialized_monitor) {
108+
panic!();
109+
}
110+
}
111+
112+
if *chain_watch != *self.chain_monitor {
113+
panic!();
114+
}
92115
}
93116
}
94117
}

0 commit comments

Comments
 (0)