Skip to content

Commit 0ff16b4

Browse files
committed
Track block hash, return via get_relevant_txids
Previously, `Confirm::get_relevant_txids()` only returned a list of transactions that have to be monitored for reorganization out of the chain. This interface however required double bookkeeping: while we internally keep track of the best block, height, etc, it would also require the user to keep track which transaction was previously confirmed in which block and to take actions based on any change, e.g, to reconfirm them when the block would be reorged-out and the transactions had been reconfirmed in another block. Here, we track the confirmation block hash internally and return it via `Confirm::get_relevant_txids()` to the user, which alleviates the requirement for double bookkeeping: the user can now simply check whether the given transaction is still confirmed and in the given block, and take action if not.
1 parent fc9a4c2 commit 0ff16b4

File tree

7 files changed

+74
-48
lines changed

7 files changed

+74
-48
lines changed

lightning/src/chain/chainmonitor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
//! servicing [`ChannelMonitor`] updates from the client.
2525
2626
use bitcoin::blockdata::block::BlockHeader;
27-
use bitcoin::hash_types::Txid;
27+
use bitcoin::hash_types::{Txid, BlockHash};
2828

2929
use crate::chain;
3030
use crate::chain::{ChannelMonitorUpdateStatus, Filter, WatchedOutput};
@@ -544,7 +544,7 @@ where
544544
});
545545
}
546546

547-
fn get_relevant_txids(&self) -> Vec<Txid> {
547+
fn get_relevant_txids(&self) -> Vec<(Txid, BlockHash)> {
548548
let mut txids = Vec::new();
549549
let monitor_states = self.monitors.read().unwrap();
550550
for monitor_state in monitor_states.values() {

lightning/src/chain/channelmonitor.rs

Lines changed: 42 additions & 30 deletions
Large diffs are not rendered by default.

lightning/src/chain/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ pub trait Confirm {
171171
/// if they become available at the same time.
172172
fn best_block_updated(&self, header: &BlockHeader, height: u32);
173173

174-
/// Returns transactions that should be monitored for reorganization out of the chain.
174+
/// Returns transactions that should be monitored for reorganization out of the chain along
175+
/// with the hash of the block as part of which had been previously confirmed.
175176
///
176177
/// Will include any transactions passed to [`transactions_confirmed`] that have insufficient
177178
/// confirmations to be safe from a chain reorganization. Will not include any transactions
@@ -184,7 +185,7 @@ pub trait Confirm {
184185
///
185186
/// [`transactions_confirmed`]: Self::transactions_confirmed
186187
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
187-
fn get_relevant_txids(&self) -> Vec<Txid>;
188+
fn get_relevant_txids(&self) -> Vec<(Txid, BlockHash)>;
188189
}
189190

190191
/// An enum representing the status of a channel monitor update persistence.

lightning/src/chain/onchaintx.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use bitcoin::blockdata::transaction::Transaction;
1616
use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
1717
use bitcoin::blockdata::script::Script;
1818

19-
use bitcoin::hash_types::Txid;
19+
use bitcoin::hash_types::{Txid, BlockHash};
2020

2121
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
2222
use bitcoin::secp256k1;
@@ -58,6 +58,7 @@ const MAX_ALLOC_SIZE: usize = 64*1024;
5858
struct OnchainEventEntry {
5959
txid: Txid,
6060
height: u32,
61+
block_hash: Option<BlockHash>,
6162
event: OnchainEvent,
6263
}
6364

@@ -92,6 +93,7 @@ impl Writeable for OnchainEventEntry {
9293
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
9394
write_tlv_fields!(writer, {
9495
(0, self.txid, required),
96+
(1, self.block_hash, option),
9597
(2, self.height, required),
9698
(4, self.event, required),
9799
});
@@ -103,14 +105,16 @@ impl MaybeReadable for OnchainEventEntry {
103105
fn read<R: io::Read>(reader: &mut R) -> Result<Option<Self>, DecodeError> {
104106
let mut txid = Txid::all_zeros();
105107
let mut height = 0;
108+
let mut block_hash = None;
106109
let mut event = None;
107110
read_tlv_fields!(reader, {
108111
(0, txid, required),
112+
(1, block_hash, option),
109113
(2, height, required),
110114
(4, event, ignorable),
111115
});
112116
if let Some(ev) = event {
113-
Ok(Some(Self { txid, height, event: ev }))
117+
Ok(Some(Self { txid, height, block_hash, event: ev }))
114118
} else {
115119
Ok(None)
116120
}
@@ -512,7 +516,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
512516
/// `conf_height` represents the height at which the transactions in `txn_matched` were
513517
/// confirmed. This does not need to equal the current blockchain tip height, which should be
514518
/// provided via `cur_height`, however it must never be higher than `cur_height`.
515-
pub(crate) fn update_claims_view<B: Deref, F: Deref, L: Deref>(&mut self, txn_matched: &[&Transaction], requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32, broadcaster: &B, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L)
519+
pub(crate) fn update_claims_view<B: Deref, F: Deref, L: Deref>(&mut self, txn_matched: &[&Transaction], requests: Vec<PackageTemplate>, conf_height: u32, conf_hash: BlockHash, cur_height: u32, broadcaster: &B, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L)
516520
where B::Target: BroadcasterInterface,
517521
F::Target: FeeEstimator,
518522
L::Target: Logger,
@@ -625,6 +629,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
625629
let entry = OnchainEventEntry {
626630
txid: tx.txid(),
627631
height: conf_height,
632+
block_hash: Some(conf_hash),
628633
event: OnchainEvent::Claim { claim_request: first_claim_txid_height.0.clone() }
629634
};
630635
if !self.onchain_events_awaiting_threshold_conf.contains(&entry) {
@@ -665,6 +670,7 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
665670
let entry = OnchainEventEntry {
666671
txid: tx.txid(),
667672
height: conf_height,
673+
block_hash: Some(conf_hash),
668674
event: OnchainEvent::ContentiousOutpoint { package },
669675
};
670676
if !self.onchain_events_awaiting_threshold_conf.contains(&entry) {
@@ -824,12 +830,12 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
824830
self.claimable_outpoints.get(outpoint).is_some()
825831
}
826832

827-
pub(crate) fn get_relevant_txids(&self) -> Vec<Txid> {
828-
let mut txids: Vec<Txid> = self.onchain_events_awaiting_threshold_conf
833+
pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, BlockHash)> {
834+
let mut txids: Vec<(Txid, BlockHash)> = self.onchain_events_awaiting_threshold_conf
829835
.iter()
830-
.map(|entry| entry.txid)
836+
.map(|entry| (entry.txid, entry.block_hash.unwrap()))
831837
.collect();
832-
txids.sort_unstable();
838+
txids.sort_unstable_by_key(|tuple| tuple.0);
833839
txids.dedup();
834840
txids
835841
}

lightning/src/ln/channel.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4513,6 +4513,11 @@ impl<Signer: Sign> Channel<Signer> {
45134513
self.channel_transaction_parameters.funding_outpoint
45144514
}
45154515

4516+
/// Returns the block hash in which our funding transaction was confirmed.
4517+
pub fn get_funding_tx_confirmed_in(&self) -> Option<BlockHash> {
4518+
self.funding_tx_confirmed_in
4519+
}
4520+
45164521
fn get_holder_selected_contest_delay(&self) -> u16 {
45174522
self.channel_transaction_parameters.holder_selected_contest_delay
45184523
}

lightning/src/ln/channelmanager.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5759,12 +5759,12 @@ where
57595759
});
57605760
}
57615761

5762-
fn get_relevant_txids(&self) -> Vec<Txid> {
5762+
fn get_relevant_txids(&self) -> Vec<(Txid, BlockHash)> {
57635763
let channel_state = self.channel_state.lock().unwrap();
57645764
let mut res = Vec::with_capacity(channel_state.short_to_chan_info.len());
57655765
for chan in channel_state.by_id.values() {
5766-
if let Some(funding_txo) = chan.get_funding_txo() {
5767-
res.push(funding_txo.txid);
5766+
if let (Some(funding_txo), Some(block_hash)) = (chan.get_funding_txo(), chan.get_funding_tx_confirmed_in()) {
5767+
res.push((funding_txo.txid, block_hash));
57685768
}
57695769
}
57705770
res

lightning/src/ln/reorg_tests.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,9 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
281281
if !reorg_after_reload {
282282
if use_funding_unconfirmed {
283283
let relevant_txids = nodes[0].node.get_relevant_txids();
284-
assert_eq!(&relevant_txids[..], &[chan.3.txid()]);
285-
nodes[0].node.transaction_unconfirmed(&relevant_txids[0]);
284+
let txid = relevant_txids[0].0;
285+
assert_eq!(txid, chan.3.txid());
286+
nodes[0].node.transaction_unconfirmed(&txid);
286287
} else if connect_style == ConnectStyle::FullBlockViaListen {
287288
disconnect_blocks(&nodes[0], CHAN_CONFIRM_DEPTH - 1);
288289
assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
@@ -350,8 +351,9 @@ fn do_test_unconf_chan(reload_node: bool, reorg_after_reload: bool, use_funding_
350351
if reorg_after_reload {
351352
if use_funding_unconfirmed {
352353
let relevant_txids = nodes[0].node.get_relevant_txids();
353-
assert_eq!(&relevant_txids[..], &[chan.3.txid()]);
354-
nodes[0].node.transaction_unconfirmed(&relevant_txids[0]);
354+
let txid = relevant_txids[0].0;
355+
assert_eq!(txid, chan.3.txid());
356+
nodes[0].node.transaction_unconfirmed(&txid);
355357
} else if connect_style == ConnectStyle::FullBlockViaListen {
356358
disconnect_blocks(&nodes[0], CHAN_CONFIRM_DEPTH - 1);
357359
assert_eq!(nodes[0].node.list_channels().len(), 1);

0 commit comments

Comments
 (0)