Skip to content

Commit f57c885

Browse files
committed
Electrum interface for ChainMonitor
Add an interface to ChainMonitor for Electrum users, delegating to the corresponding methods in each ChannelMonitor.
1 parent c57bf73 commit f57c885

File tree

1 file changed

+87
-2
lines changed

1 file changed

+87
-2
lines changed

lightning/src/chain/chainmonitor.rs

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
//! servicing [`ChannelMonitor`] updates from the client.
2525
2626
use bitcoin::blockdata::block::{Block, BlockHeader};
27+
use bitcoin::hash_types::Txid;
28+
use bitcoin::blockdata::transaction::TxOut;
2729

2830
use chain;
2931
use chain::{Filter, WatchedOutput};
@@ -82,10 +84,63 @@ where C::Target: chain::Filter,
8284
/// descendants of such transactions. It is not necessary to re-fetch the block to obtain
8385
/// updated `txdata`.
8486
pub fn block_connected(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
87+
self.process_chain_data(header, txdata, |monitor, txdata| {
88+
monitor.block_connected(
89+
header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
90+
});
91+
}
92+
93+
/// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
94+
/// of a channel and reacting accordingly to newly confirmed transactions. For details, see
95+
/// [`ChannelMonitor::transactions_confirmed`].
96+
///
97+
/// Used instead of [`block_connected`] by clients that are notified of transactions rather than
98+
/// blocks. May be called before or after [`update_best_block`] for transactions in the
99+
/// corresponding block. See [`update_best_block`] for further calling expectations.
100+
///
101+
/// [`block_connected`]: Self::block_connected
102+
/// [`update_best_block`]: Self::update_best_block
103+
pub fn transactions_confirmed(&self, header: &BlockHeader, txdata: &TransactionData, height: u32) {
104+
self.process_chain_data(header, txdata, |monitor, txdata| {
105+
monitor.transactions_confirmed(
106+
header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
107+
});
108+
}
109+
110+
/// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
111+
/// of a channel and reacting accordingly based on the new chain tip. For details, see
112+
/// [`ChannelMonitor::update_best_block`].
113+
///
114+
/// Used instead of [`block_connected`] by clients that are notified of transactions rather than
115+
/// blocks. May be called before or after [`transactions_confirmed`] for the corresponding
116+
/// block.
117+
///
118+
/// Must be called after new blocks become available for the most recent block. Intermediary
119+
/// blocks, however, may be safely skipped. In the event of a chain re-organization, this only
120+
/// needs to be called for the most recent block assuming `transaction_unconfirmed` is called
121+
/// for any affected transactions.
122+
///
123+
/// [`block_connected`]: Self::block_connected
124+
/// [`transactions_confirmed`]: Self::transactions_confirmed
125+
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
126+
pub fn update_best_block(&self, header: &BlockHeader, height: u32) {
127+
self.process_chain_data(header, &[], |monitor, txdata| {
128+
// While in practice there shouldn't be any recursive calls when given empty txdata,
129+
// it's still possible if a chain::Filter implementation returns a transaction.
130+
debug_assert!(txdata.is_empty());
131+
monitor.update_best_block(
132+
header, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger)
133+
});
134+
}
135+
136+
fn process_chain_data<FN>(&self, header: &BlockHeader, txdata: &TransactionData, process: FN)
137+
where
138+
FN: Fn(&ChannelMonitor<ChannelSigner>, &TransactionData) -> Vec<(Txid, Vec<(u32, TxOut)>)>
139+
{
85140
let mut dependent_txdata = Vec::new();
86141
let monitors = self.monitors.read().unwrap();
87142
for monitor in monitors.values() {
88-
let mut txn_outputs = monitor.block_connected(header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
143+
let mut txn_outputs = process(monitor, txdata);
89144

90145
// Register any new outputs with the chain source for filtering, storing any dependent
91146
// transactions from within the block that previously had not been included in txdata.
@@ -114,7 +169,7 @@ where C::Target: chain::Filter,
114169
dependent_txdata.sort_unstable_by_key(|(index, _tx)| *index);
115170
dependent_txdata.dedup_by_key(|(index, _tx)| *index);
116171
let txdata: Vec<_> = dependent_txdata.iter().map(|(index, tx)| (*index, tx)).collect();
117-
self.block_connected(header, &txdata, height);
172+
self.process_chain_data(header, &txdata, process);
118173
}
119174
}
120175

@@ -128,6 +183,36 @@ where C::Target: chain::Filter,
128183
}
129184
}
130185

186+
/// Dispatches to per-channel monitors, which are responsible for updating their on-chain view
187+
/// of a channel based on transactions unconfirmed as a result of a chain reorganization. See
188+
/// [`ChannelMonitor::transaction_unconfirmed`] for details.
189+
///
190+
/// Used instead of [`block_disconnected`] by clients that are notified of transactions rather
191+
/// than blocks. May be called before or after [`update_best_block`] for transactions in the
192+
/// corresponding block. See [`update_best_block`] for further calling expectations.
193+
///
194+
/// [`block_disconnected`]: Self::block_disconnected
195+
/// [`update_best_block`]: Self::update_best_block
196+
pub fn transaction_unconfirmed(&self, txid: &Txid) {
197+
let monitors = self.monitors.read().unwrap();
198+
for monitor in monitors.values() {
199+
monitor.transaction_unconfirmed(txid, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
200+
}
201+
}
202+
203+
/// Returns the set of txids that should be monitored for re-organization out of the chain.
204+
pub fn get_relevant_txids(&self) -> Vec<Txid> {
205+
let mut txids = Vec::new();
206+
let monitors = self.monitors.read().unwrap();
207+
for monitor in monitors.values() {
208+
txids.append(&mut monitor.get_relevant_txids());
209+
}
210+
211+
txids.sort_unstable();
212+
txids.dedup();
213+
txids
214+
}
215+
131216
/// Creates a new `ChainMonitor` used to watch on-chain activity pertaining to channels.
132217
///
133218
/// When an optional chain source implementing [`chain::Filter`] is provided, the chain monitor

0 commit comments

Comments
 (0)