Skip to content

Commit 71c7606

Browse files
committed
WIP: Remove ChainWatchedUtil
1 parent abe3533 commit 71c7606

File tree

4 files changed

+27
-197
lines changed

4 files changed

+27
-197
lines changed

lightning/src/chain/chaininterface.rs

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@
55
//! disconnections, transaction broadcasting, and feerate information requests.
66
77
use bitcoin::blockdata::transaction::Transaction;
8-
use bitcoin::blockdata::script::Script;
9-
use bitcoin::hash_types::Txid;
10-
11-
use std::collections::HashSet;
128

139
/// An interface to send a transaction to the Bitcoin network.
1410
pub trait BroadcasterInterface: Sync + Send {
@@ -46,91 +42,3 @@ pub trait FeeEstimator: Sync + Send {
4642

4743
/// Minimum relay fee as required by bitcoin network mempool policy.
4844
pub const MIN_RELAY_FEE_SAT_PER_1000_WEIGHT: u64 = 4000;
49-
50-
/// Utility for tracking registered txn/outpoints and checking for matches
51-
#[cfg_attr(test, derive(PartialEq))]
52-
pub struct ChainWatchedUtil {
53-
watch_all: bool,
54-
55-
// We are more conservative in matching during testing to ensure everything matches *exactly*,
56-
// even though during normal runtime we take more optimized match approaches...
57-
#[cfg(test)]
58-
watched_txn: HashSet<(Txid, Script)>,
59-
#[cfg(not(test))]
60-
watched_txn: HashSet<Script>,
61-
62-
watched_outpoints: HashSet<(Txid, u32)>,
63-
}
64-
65-
impl ChainWatchedUtil {
66-
/// Constructs an empty (watches nothing) ChainWatchedUtil
67-
pub fn new() -> Self {
68-
Self {
69-
watch_all: false,
70-
watched_txn: HashSet::new(),
71-
watched_outpoints: HashSet::new(),
72-
}
73-
}
74-
75-
/// Registers a tx for monitoring, returning true if it was a new tx and false if we'd already
76-
/// been watching for it.
77-
pub fn register_tx(&mut self, txid: &Txid, script_pub_key: &Script) -> bool {
78-
if self.watch_all { return false; }
79-
#[cfg(test)]
80-
{
81-
self.watched_txn.insert((txid.clone(), script_pub_key.clone()))
82-
}
83-
#[cfg(not(test))]
84-
{
85-
let _tx_unused = txid; // It's used in cfg(test), though
86-
self.watched_txn.insert(script_pub_key.clone())
87-
}
88-
}
89-
90-
/// Registers an outpoint for monitoring, returning true if it was a new outpoint and false if
91-
/// we'd already been watching for it
92-
pub fn register_outpoint(&mut self, outpoint: (Txid, u32), _script_pub_key: &Script) -> bool {
93-
if self.watch_all { return false; }
94-
self.watched_outpoints.insert(outpoint)
95-
}
96-
97-
/// Sets us to match all transactions, returning true if this is a new setting and false if
98-
/// we'd already been set to match everything.
99-
pub fn watch_all(&mut self) -> bool {
100-
if self.watch_all { return false; }
101-
self.watch_all = true;
102-
true
103-
}
104-
105-
/// Checks if a given transaction matches the current filter.
106-
pub fn does_match_tx(&self, tx: &Transaction) -> bool {
107-
if self.watch_all {
108-
return true;
109-
}
110-
for out in tx.output.iter() {
111-
#[cfg(test)]
112-
for &(ref txid, ref script) in self.watched_txn.iter() {
113-
if *script == out.script_pubkey {
114-
if tx.txid() == *txid {
115-
return true;
116-
}
117-
}
118-
}
119-
#[cfg(not(test))]
120-
for script in self.watched_txn.iter() {
121-
if *script == out.script_pubkey {
122-
return true;
123-
}
124-
}
125-
}
126-
for input in tx.input.iter() {
127-
for outpoint in self.watched_outpoints.iter() {
128-
let &(outpoint_hash, outpoint_index) = outpoint;
129-
if outpoint_hash == input.previous_output.txid && outpoint_index == input.previous_output.vout {
130-
return true;
131-
}
132-
}
133-
}
134-
false
135-
}
136-
}

lightning/src/chain/channelmonitor.rs

Lines changed: 23 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash};
3636
use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
3737
use chain;
3838
use chain::Notify;
39-
use chain::chaininterface::{ChainWatchedUtil, BroadcasterInterface, FeeEstimator};
39+
use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
4040
use chain::transaction::OutPoint;
4141
use chain::keysinterface::{SpendableOutputDescriptor, ChannelKeys};
4242
use util::logger::Logger;
@@ -171,91 +171,12 @@ pub struct ChainMonitor<ChanSigner: ChannelKeys, C: Deref, T: Deref, F: Deref, L
171171
pub monitors: Mutex<HashMap<OutPoint, ChannelMonitor<ChanSigner>>>,
172172
#[cfg(not(test))]
173173
monitors: Mutex<HashMap<OutPoint, ChannelMonitor<ChanSigner>>>,
174-
watch_events: Mutex<WatchEventCache>,
175174
chain_source: Option<C>,
176175
broadcaster: T,
177176
logger: L,
178177
fee_estimator: F
179178
}
180179

181-
struct WatchEventCache {
182-
watched: ChainWatchedUtil,
183-
events: Vec<WatchEvent>,
184-
}
185-
186-
/// An event indicating on-chain activity to watch for pertaining to a channel.
187-
enum WatchEvent {
188-
/// Watch for a transaction with `txid` and having an output with `script_pubkey` as a spending
189-
/// condition.
190-
WatchTransaction {
191-
/// Identifier of the transaction.
192-
txid: Txid,
193-
194-
/// Spending condition for an output of the transaction.
195-
script_pubkey: Script,
196-
},
197-
/// Watch for spends of a transaction output identified by `outpoint` having `script_pubkey` as
198-
/// the spending condition.
199-
WatchOutput {
200-
/// Identifier for the output.
201-
outpoint: OutPoint,
202-
203-
/// Spending condition for the output.
204-
script_pubkey: Script,
205-
}
206-
}
207-
208-
impl WatchEventCache {
209-
fn new() -> Self {
210-
Self {
211-
watched: ChainWatchedUtil::new(),
212-
events: Vec::new(),
213-
}
214-
}
215-
216-
fn watch_tx(&mut self, txid: &Txid, script_pubkey: &Script) {
217-
if self.watched.register_tx(txid, script_pubkey) {
218-
self.events.push(WatchEvent::WatchTransaction {
219-
txid: *txid,
220-
script_pubkey: script_pubkey.clone()
221-
});
222-
}
223-
}
224-
225-
fn watch_output(&mut self, outpoint: (&Txid, usize), script_pubkey: &Script) {
226-
let (txid, index) = outpoint;
227-
if self.watched.register_outpoint((*txid, index as u32), script_pubkey) {
228-
self.events.push(WatchEvent::WatchOutput {
229-
outpoint: OutPoint {
230-
txid: *txid,
231-
index: index as u16,
232-
},
233-
script_pubkey: script_pubkey.clone(),
234-
});
235-
}
236-
}
237-
238-
fn flush_events<C: Deref>(&mut self, chain_source: &Option<C>) -> bool where C::Target: chain::Notify {
239-
let num_events = self.events.len();
240-
match chain_source {
241-
&None => self.events.clear(),
242-
&Some(ref chain_source) => {
243-
for event in self.events.drain(..) {
244-
match event {
245-
WatchEvent::WatchTransaction { txid, script_pubkey } => {
246-
chain_source.register_tx(txid, script_pubkey)
247-
},
248-
WatchEvent::WatchOutput { outpoint, script_pubkey } => {
249-
chain_source.register_output(outpoint, script_pubkey)
250-
},
251-
}
252-
}
253-
}
254-
}
255-
num_events > 0
256-
}
257-
}
258-
259180
impl<ChanSigner: ChannelKeys, C: Deref, T: Deref, F: Deref, L: Deref> ChainMonitor<ChanSigner, C, T, F, L>
260181
where C::Target: chain::Notify,
261182
T::Target: BroadcasterInterface,
@@ -272,21 +193,23 @@ impl<ChanSigner: ChannelKeys, C: Deref, T: Deref, F: Deref, L: Deref> ChainMonit
272193
/// [`chain::Watch::release_pending_htlc_updates`]: ../../chain/trait.Watch.html#tymethod.release_pending_htlc_updates
273194
/// [`chain::Notify`]: ../../chain/trait.Notify.html
274195
pub fn block_connected(&self, header: &BlockHeader, txdata: &[(usize, &Transaction)], height: u32) -> bool {
275-
let mut watch_events = self.watch_events.lock().unwrap();
276-
let matched_txn: Vec<_> = txdata.iter().filter(|&&(_, tx)| watch_events.watched.does_match_tx(tx)).map(|e| *e).collect();
196+
let mut new_outputs = false;
277197
{
278198
let mut monitors = self.monitors.lock().unwrap();
279199
for monitor in monitors.values_mut() {
280-
let txn_outputs = monitor.block_connected(header, &matched_txn, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
200+
let mut txn_outputs = monitor.block_connected(header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
201+
new_outputs |= !txn_outputs.is_empty();
281202

282-
for (ref txid, ref outputs) in txn_outputs {
283-
for (idx, output) in outputs.iter().enumerate() {
284-
watch_events.watch_output((txid, idx), &output.script_pubkey);
203+
if let Some(ref chain_source) = self.chain_source {
204+
for (txid, outputs) in txn_outputs.drain(..) {
205+
for (idx, output) in outputs.iter().enumerate() {
206+
chain_source.register_output(&OutPoint { txid, index: idx as u16 }, &output.script_pubkey);
207+
}
285208
}
286-
}
209+
};
287210
}
288211
}
289-
watch_events.flush_events(&self.chain_source)
212+
new_outputs
290213
}
291214

292215
/// Delegates to [`ChannelMonitor::block_disconnected`] for each watched channel.
@@ -311,7 +234,6 @@ impl<ChanSigner: ChannelKeys, C: Deref, T: Deref, F: Deref, L: Deref> ChainMonit
311234
pub fn new(chain_source: Option<C>, broadcaster: T, logger: L, feeest: F) -> Self {
312235
Self {
313236
monitors: Mutex::new(HashMap::new()),
314-
watch_events: Mutex::new(WatchEventCache::new()),
315237
chain_source,
316238
broadcaster,
317239
logger,
@@ -325,7 +247,6 @@ impl<ChanSigner: ChannelKeys, C: Deref, T: Deref, F: Deref, L: Deref> ChainMonit
325247
///
326248
/// [`chain::Notify`]: ../../chain/trait.Notify.html
327249
pub fn add_monitor(&self, outpoint: OutPoint, monitor: ChannelMonitor<ChanSigner>) -> Result<(), MonitorUpdateError> {
328-
let mut watch_events = self.watch_events.lock().unwrap();
329250
let mut monitors = self.monitors.lock().unwrap();
330251
let entry = match monitors.entry(outpoint) {
331252
hash_map::Entry::Occupied(_) => return Err(MonitorUpdateError("Channel monitor for given outpoint is already present")),
@@ -334,16 +255,17 @@ impl<ChanSigner: ChannelKeys, C: Deref, T: Deref, F: Deref, L: Deref> ChainMonit
334255
{
335256
let funding_txo = monitor.get_funding_txo();
336257
log_trace!(self.logger, "Got new Channel Monitor for channel {}", log_bytes!(funding_txo.0.to_channel_id()[..]));
337-
watch_events.watch_tx(&funding_txo.0.txid, &funding_txo.1);
338-
watch_events.watch_output((&funding_txo.0.txid, funding_txo.0.index as usize), &funding_txo.1);
339-
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
340-
for (idx, script) in outputs.iter().enumerate() {
341-
watch_events.watch_output((txid, idx), script);
258+
259+
if let Some(ref chain_source) = self.chain_source {
260+
chain_source.register_tx(&funding_txo.0.txid, &funding_txo.1);
261+
for (txid, outputs) in monitor.get_outputs_to_watch().iter() {
262+
for (idx, script_pubkey) in outputs.iter().enumerate() {
263+
chain_source.register_output(&OutPoint { txid: *txid, index: idx as u16 }, &script_pubkey);
264+
}
342265
}
343-
}
266+
};
344267
}
345268
entry.insert(monitor);
346-
watch_events.flush_events(&self.chain_source);
347269
Ok(())
348270
}
349271

@@ -2000,12 +1922,12 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
20001922
}
20011923
}
20021924
self.onchain_tx_handler.block_connected(txn_matched, claimable_outpoints, height, &*broadcaster, &*fee_estimator, &*logger);
2003-
20041925
self.last_block_hash = block_hash;
2005-
for &(ref txid, ref output_scripts) in watch_outputs.iter() {
2006-
self.outputs_to_watch.insert(txid.clone(), output_scripts.iter().map(|o| o.script_pubkey.clone()).collect());
2007-
}
20081926

1927+
watch_outputs.retain(|&(ref txid, ref txouts)| {
1928+
let output_scripts = txouts.iter().map(|o| o.script_pubkey.clone()).collect();
1929+
self.outputs_to_watch.insert(txid.clone(), output_scripts).is_none()
1930+
});
20091931
watch_outputs
20101932
}
20111933

lightning/src/chain/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ pub trait Watch: Send + Sync {
9393
pub trait Notify: Send + Sync {
9494
/// Registers interest in a transaction with `txid` and having an output with `script_pubkey` as
9595
/// a spending condition.
96-
fn register_tx(&self, txid: Txid, script_pubkey: Script);
96+
fn register_tx(&self, txid: &Txid, script_pubkey: &Script);
9797

9898
/// Registers interest in spends of a transaction output identified by `outpoint` having
9999
/// `script_pubkey` as the spending condition.
100-
fn register_output(&self, outpoint: OutPoint, script_pubkey: Script);
100+
fn register_output(&self, outpoint: &OutPoint, script_pubkey: &Script);
101101
}

lightning/src/util/test_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,6 @@ impl chain::Access for TestChainSource {
410410
}
411411

412412
impl chain::Notify for TestChainSource {
413-
fn register_tx(&self, _txid: Txid, _script_pubkey: Script) {}
414-
fn register_output(&self, _outpoint: OutPoint, _script_pubkey: Script) {}
413+
fn register_tx(&self, _txid: &Txid, _script_pubkey: &Script) {}
414+
fn register_output(&self, _outpoint: &OutPoint, _script_pubkey: &Script) {}
415415
}

0 commit comments

Comments
 (0)