use bitcoin::blockdata::block::{Block, BlockHeader};
use chain;
-use chain::Filter;
+use chain::{Filter, WatchedOutput};
use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
use chain::channelmonitor;
use chain::channelmonitor::{ChannelMonitor, ChannelMonitorUpdate, ChannelMonitorUpdateErr, MonitorEvent, Persist};
let mut txn_outputs = monitor.block_connected(header, txdata, height, &*self.broadcaster, &*self.fee_estimator, &*self.logger);
if let Some(ref chain_source) = self.chain_source {
+ let block_hash = header.block_hash();
for (txid, outputs) in txn_outputs.drain(..) {
for (idx, output) in outputs.iter() {
- chain_source.register_output(&OutPoint { txid, index: *idx as u16 }, &output.script_pubkey);
+ chain_source.register_output(WatchedOutput {
+ block_hash: Some(block_hash),
+ outpoint: OutPoint { txid, index: *idx as u16 },
+ script_pubkey: output.script_pubkey.clone(),
+ });
}
}
}
use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash};
use ln::onchaintx::{OnchainTxHandler, InputDescriptors};
use chain;
+use chain::WatchedOutput;
use chain::chaininterface::{BroadcasterInterface, FeeEstimator};
use chain::transaction::{OutPoint, TransactionData};
use chain::keysinterface::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, Sign, KeysInterface};
for (txid, outputs) in lock.get_outputs_to_watch().iter() {
for (index, script_pubkey) in outputs.iter() {
assert!(*index <= u16::max_value() as u32);
- filter.register_output(&OutPoint { txid: *txid, index: *index as u16 }, script_pubkey);
+ filter.register_output(WatchedOutput {
+ block_hash: None,
+ outpoint: OutPoint { txid: *txid, index: *index as u16 },
+ script_pubkey: script_pubkey.clone(),
+ });
}
}
}
/// a spending condition.
fn register_tx(&self, txid: &Txid, script_pubkey: &Script);
- /// Registers interest in spends of a transaction output identified by `outpoint` having
- /// `script_pubkey` as the spending condition.
+ /// Registers interest in spends of a transaction output.
///
- /// Optionally, returns any transaction dependent on the output. This is useful for Electrum
- /// clients to facilitate registering in-block descendants.
- fn register_output(&self, outpoint: &OutPoint, script_pubkey: &Script) -> Option<(usize, Transaction)>;
+ /// Optionally, when `output.block_hash` is set, should return any transaction spending the
+ /// output that is found in the corresponding block along with its index.
+ ///
+ /// This return value is useful for Electrum clients in order to supply in-block descendant
+ /// transactions which otherwise were not included. This is not necessary for other clients if
+ /// such descendant transactions were already included (e.g., when a BIP 157 client provides the
+ /// full block).
+ fn register_output(&self, output: WatchedOutput) -> Option<(usize, Transaction)>;
+}
+
+/// A transaction output watched by a [`ChannelMonitor`] for spends on-chain.
+///
+/// Used to convey to a [`Filter`] such an output with a given spending condition. Any transaction
+/// spending the output must be given to [`ChannelMonitor::block_connected`] either directly or via
+/// the return value of [`Filter::register_output`].
+///
+/// If `block_hash` is `Some`, this indicates the output was created in the corresponding block and
+/// may have been spent there. See [`Filter::register_output`] for details.
+///
+/// [`ChannelMonitor`]: channelmonitor::ChannelMonitor
+/// [`ChannelMonitor::block_connected`]: channelmonitor::ChannelMonitor::block_connected
+pub struct WatchedOutput {
+ /// First block where the transaction output may have been spent.
+ pub block_hash: Option<BlockHash>,
+
+ /// Outpoint identifying the transaction output.
+ pub outpoint: OutPoint,
+
+ /// Spending condition of the transaction output.
+ pub script_pubkey: Script,
}
impl<T: Listen> Listen for std::ops::Deref<Target = T> {
// licenses.
use chain;
+use chain::WatchedOutput;
use chain::chaininterface;
use chain::chaininterface::ConfirmationTarget;
use chain::chainmonitor;
self.watched_txn.lock().unwrap().insert((*txid, script_pubkey.clone()));
}
- fn register_output(&self, outpoint: &OutPoint, script_pubkey: &Script) -> Option<(usize, Transaction)> {
- self.watched_outputs.lock().unwrap().insert((*outpoint, script_pubkey.clone()));
+ fn register_output(&self, output: WatchedOutput) -> Option<(usize, Transaction)> {
+ self.watched_outputs.lock().unwrap().insert((output.outpoint, output.script_pubkey));
None
}
}