Skip to content

Commit 65e588f

Browse files
committed
Add ChannelMonitor::transaction_unconfirmed
Define an Electrum-friendly interface for ChannelMonitor where transactions are unconfirmed independently from updating the latest block.
1 parent 8e37448 commit 65e588f

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,29 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
13311331
header, txdata, height, broadcaster, fee_estimator, logger)
13321332
}
13331333

1334+
/// Processes a transaction that was reorganized out of the chain.
1335+
///
1336+
/// Used instead of [`block_disconnected`] by clients that are notified of transactions rather
1337+
/// than blocks. May be called before or after [`update_best_block`] for transactions in the
1338+
/// corresponding block. See [`update_best_block`] for further calling expectations.
1339+
///
1340+
/// [`block_disconnected`]: Self::block_disconnected
1341+
/// [`update_best_block`]: Self::update_best_block
1342+
pub fn transaction_unconfirmed<B: Deref, F: Deref, L: Deref>(
1343+
&self,
1344+
txid: &Txid,
1345+
broadcaster: B,
1346+
fee_estimator: F,
1347+
logger: L,
1348+
) where
1349+
B::Target: BroadcasterInterface,
1350+
F::Target: FeeEstimator,
1351+
L::Target: Logger,
1352+
{
1353+
self.inner.lock().unwrap().transaction_unconfirmed(
1354+
txid, broadcaster, fee_estimator, logger);
1355+
}
1356+
13341357
/// Updates the monitor with the current best chain tip, returning new outputs to watch. See
13351358
/// [`block_connected`] for details.
13361359
///
@@ -1339,10 +1362,13 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
13391362
/// block.
13401363
///
13411364
/// Must be called after new blocks become available for the most recent block. Intermediary
1342-
/// blocks, however, may be safely skipped.
1365+
/// blocks, however, may be safely skipped. In the event of a chain re-organization, this only
1366+
/// needs to be called for the most recent block assuming `transaction_unconfirmed` is called
1367+
/// for any affected transactions.
13431368
///
13441369
/// [`block_connected`]: Self::block_connected
13451370
/// [`transactions_confirmed`]: Self::transactions_confirmed
1371+
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
13461372
pub fn update_best_block<B: Deref, F: Deref, L: Deref>(
13471373
&self,
13481374
header: &BlockHeader,
@@ -2229,13 +2255,13 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
22292255
debug_assert!(
22302256
unmatured_htlcs.iter().find(|&htlc| htlc == &htlc_update.0).is_none(),
22312257
"An unmature HTLC transaction conflicts with a maturing one; failed to \
2232-
call block_disconnected for a block containing the conflicting \
2233-
transaction.");
2258+
call either transaction_unconfirmed for the conflicting transaction \
2259+
or block_disconnected for a block containing it.");
22342260
debug_assert!(
22352261
matured_htlcs.iter().find(|&htlc| htlc == &htlc_update.0).is_none(),
22362262
"A matured HTLC transaction conflicts with a maturing one; failed to \
2237-
call block_disconnected for a block containing the conflicting \
2238-
transaction.");
2263+
call either transaction_unconfirmed for the conflicting transaction \
2264+
or block_disconnected for a block containing it.");
22392265
matured_htlcs.push(htlc_update.0.clone());
22402266
}
22412267

@@ -2297,6 +2323,21 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
22972323
self.best_block = BestBlock::new(header.prev_blockhash, height - 1);
22982324
}
22992325

2326+
fn transaction_unconfirmed<B: Deref, F: Deref, L: Deref>(
2327+
&mut self,
2328+
txid: &Txid,
2329+
broadcaster: B,
2330+
fee_estimator: F,
2331+
logger: L,
2332+
) where
2333+
B::Target: BroadcasterInterface,
2334+
F::Target: FeeEstimator,
2335+
L::Target: Logger,
2336+
{
2337+
self.onchain_events_waiting_threshold_conf.retain(|ref entry| entry.txid != *txid);
2338+
self.onchain_tx_handler.transaction_unconfirmed(txid, broadcaster, fee_estimator, logger);
2339+
}
2340+
23002341
/// Filters a block's `txdata` for transactions spending watched outputs or for any child
23012342
/// transactions thereof.
23022343
fn filter_block<'a>(&self, txdata: &TransactionData<'a>) -> Vec<&'a Transaction> {

lightning/src/ln/onchaintx.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,30 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
869869
}
870870
}
871871

872+
pub(crate) fn transaction_unconfirmed<B: Deref, F: Deref, L: Deref>(
873+
&mut self,
874+
txid: &Txid,
875+
broadcaster: B,
876+
fee_estimator: F,
877+
logger: L,
878+
) where
879+
B::Target: BroadcasterInterface,
880+
F::Target: FeeEstimator,
881+
L::Target: Logger,
882+
{
883+
let mut height = None;
884+
for entry in self.onchain_events_waiting_threshold_conf.iter() {
885+
if entry.txid == *txid {
886+
height = Some(entry.height);
887+
break;
888+
}
889+
}
890+
891+
if let Some(height) = height {
892+
self.block_disconnected(height, broadcaster, fee_estimator, logger);
893+
}
894+
}
895+
872896
pub(crate) fn block_disconnected<B: Deref, F: Deref, L: Deref>(&mut self, height: u32, broadcaster: B, fee_estimator: F, logger: L)
873897
where B::Target: BroadcasterInterface,
874898
F::Target: FeeEstimator,

0 commit comments

Comments
 (0)