let relevant_txids = confirmables
.iter()
.flat_map(|c| c.get_relevant_txids())
- .collect::<HashSet<(Txid, Option<BlockHash>)>>();
+ .collect::<HashSet<(Txid, u32, Option<BlockHash>)>>();
let mut unconfirmed_txs = Vec::new();
- for (txid, block_hash_opt) in relevant_txids {
+ for (txid, _conf_height, block_hash_opt) in relevant_txids {
if let Some(block_hash) = block_hash_opt {
let block_status = maybe_await!(self.client.get_block_status(&block_hash))?;
if block_status.in_best_chain {
self.events.lock().unwrap().push(TestConfirmableEvent::BestBlockUpdated(block_hash, height));
}
- fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
- self.confirmed_txs.lock().unwrap().iter().map(|(&txid, (hash, _))| (txid, Some(*hash))).collect::<Vec<_>>()
+ fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
+ self.confirmed_txs.lock().unwrap().iter().map(|(&txid, (hash, height))| (txid, *height, Some(*hash))).collect::<Vec<_>>()
}
}
});
}
- fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
+ fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut txids = Vec::new();
let monitor_states = self.monitors.read().unwrap();
for monitor_state in monitor_states.values() {
txids.append(&mut monitor_state.monitor.get_relevant_txids());
}
- txids.sort_unstable();
- txids.dedup();
+ txids.sort_unstable_by(|a, b| a.0.cmp(&b.0).then(b.1.cmp(&a.1)));
+ txids.dedup_by_key(|(txid, _, _)| *txid);
txids
}
}
}
/// Returns the set of txids that should be monitored for re-organization out of the chain.
- pub fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
+ pub fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let inner = self.inner.lock().unwrap();
- let mut txids: Vec<(Txid, Option<BlockHash>)> = inner.onchain_events_awaiting_threshold_conf
+ let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = inner.onchain_events_awaiting_threshold_conf
.iter()
- .map(|entry| (entry.txid, entry.block_hash))
+ .map(|entry| (entry.txid, entry.height, entry.block_hash))
.chain(inner.onchain_tx_handler.get_relevant_txids().into_iter())
.collect();
- txids.sort_unstable();
- txids.dedup();
+ txids.sort_unstable_by(|a, b| a.0.cmp(&b.0).then(b.1.cmp(&a.1)));
+ txids.dedup_by_key(|(txid, _, _)| *txid);
txids
}
self.0.best_block_updated(header, height, &*self.1, &*self.2, &*self.3);
}
- fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
+ fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
self.0.get_relevant_txids()
}
}
/// blocks.
fn best_block_updated(&self, header: &Header, height: u32);
/// Returns transactions that must be monitored for reorganization out of the chain along
- /// with the hash of the block as part of which it had been previously confirmed.
+ /// with the height and the hash of the block as part of which it had been previously confirmed.
///
/// Note that the returned `Option<BlockHash>` might be `None` for channels created with LDK
/// 0.0.112 and prior, in which case you need to manually track previous confirmations.
/// given to [`transaction_unconfirmed`].
///
/// If any of the returned transactions are confirmed in a block other than the one with the
- /// given hash, they need to be unconfirmed and reconfirmed via [`transaction_unconfirmed`] and
- /// [`transactions_confirmed`], respectively.
+ /// given hash at the given height, they need to be unconfirmed and reconfirmed via
+ /// [`transaction_unconfirmed`] and [`transactions_confirmed`], respectively.
///
/// [`transactions_confirmed`]: Self::transactions_confirmed
/// [`transaction_unconfirmed`]: Self::transaction_unconfirmed
- fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)>;
+ fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)>;
}
/// An enum representing the status of a channel monitor update persistence.
self.claimable_outpoints.get(outpoint).is_some()
}
- pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
- let mut txids: Vec<(Txid, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
+ pub(crate) fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
+ let mut txids: Vec<(Txid, u32, Option<BlockHash>)> = self.onchain_events_awaiting_threshold_conf
.iter()
- .map(|entry| (entry.txid, entry.block_hash))
+ .map(|entry| (entry.txid, entry.height, entry.block_hash))
.collect();
- txids.sort_unstable_by_key(|(txid, _)| *txid);
- txids.dedup();
+ txids.sort_unstable_by(|a, b| a.0.cmp(&b.0).then(b.1.cmp(&a.1)));
+ txids.dedup_by_key(|(txid, _, _)| *txid);
txids
}
self.channel_transaction_parameters.funding_outpoint
}
+ /// Returns the height in which our funding transaction was confirmed.
+ pub fn get_funding_tx_confirmation_height(&self) -> Option<u32> {
+ let conf_height = self.funding_tx_confirmation_height;
+ if conf_height > 0 {
+ Some(conf_height)
+ } else {
+ None
+ }
+ }
+
/// Returns the block hash in which our funding transaction was confirmed.
pub fn get_funding_tx_confirmed_in(&self) -> Option<BlockHash> {
self.funding_tx_confirmed_in
});
}
- fn get_relevant_txids(&self) -> Vec<(Txid, Option<BlockHash>)> {
+ fn get_relevant_txids(&self) -> Vec<(Txid, u32, Option<BlockHash>)> {
let mut res = Vec::with_capacity(self.short_to_chan_info.read().unwrap().len());
for (_cp_id, peer_state_mutex) in self.per_peer_state.read().unwrap().iter() {
let mut peer_state_lock = peer_state_mutex.lock().unwrap();
let peer_state = &mut *peer_state_lock;
for chan in peer_state.channel_by_id.values().filter_map(|phase| if let ChannelPhase::Funded(chan) = phase { Some(chan) } else { None }) {
- if let (Some(funding_txo), Some(block_hash)) = (chan.context.get_funding_txo(), chan.context.get_funding_tx_confirmed_in()) {
- res.push((funding_txo.txid, Some(block_hash)));
+ let txid_opt = chan.context.get_funding_txo();
+ let height_opt = chan.context.get_funding_tx_confirmation_height();
+ let hash_opt = chan.context.get_funding_tx_confirmed_in();
+ if let (Some(funding_txo), Some(conf_height), Some(block_hash)) = (txid_opt, height_opt, hash_opt) {
+ res.push((funding_txo.txid, conf_height, Some(block_hash)));
}
}
}
if use_funding_unconfirmed {
let relevant_txids = nodes[0].node.get_relevant_txids();
assert_eq!(relevant_txids.len(), 1);
- let block_hash_opt = relevant_txids[0].1;
+ let block_hash_opt = relevant_txids[0].2;
let expected_hash = nodes[0].get_block_header(chan_conf_height).block_hash();
+ assert_eq!(relevant_txids[0].1, chan_conf_height);
assert_eq!(block_hash_opt, Some(expected_hash));
let txid = relevant_txids[0].0;
assert_eq!(txid, chan.3.txid());
if use_funding_unconfirmed {
let relevant_txids = nodes[0].node.get_relevant_txids();
assert_eq!(relevant_txids.len(), 1);
- let block_hash_opt = relevant_txids[0].1;
+ let block_hash_opt = relevant_txids[0].2;
let expected_hash = nodes[0].get_block_header(chan_conf_height).block_hash();
+ assert_eq!(chan_conf_height, relevant_txids[0].1);
assert_eq!(block_hash_opt, Some(expected_hash));
let txid = relevant_txids[0].0;
assert_eq!(txid, chan.3.txid());
--- /dev/null
+## API Updates
+
+- The `Confirm::get_relevant_txids()` call now also returns the height under which LDK expects the respective transaction to be confirmed.