Skip to content

Commit 925e642

Browse files
committed
DRY HTLC failure code in check_spend_counterparty_transaction
This extracts the HTLC-not-in-broadcasted-commitment-transaction code from check_spend_counterparty_transaction and moves it to a global macro, DRYing up the two very similar codepaths (fixing some minor logging inconsistencies) in the process. This macro will be used for local commitment transaction HTLC failure as well in the next commit. This commit has no functional change outside of logging.
1 parent 8530078 commit 925e642

File tree

1 file changed

+65
-87
lines changed

1 file changed

+65
-87
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 65 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,69 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
12011201
}
12021202
}
12031203

1204+
/// Compares a broadcasted commitment transaction's HTLCs with those in the latest state,
1205+
/// failing any HTLCs which didn't make it into the broadcasted commitment transaction back
1206+
/// after ANTI_REORG_DELAY blocks.
1207+
macro_rules! fail_unbroadcast_htlcs {
1208+
($self: expr, $commitment_tx_type: expr, $commitment_tx_conf_height: expr, $confirmed_htlcs_list: expr, $logger: expr) => { {
1209+
macro_rules! check_htlc_fails {
1210+
($txid: expr, $commitment_tx: expr) => {
1211+
if let Some(ref latest_outpoints) = $self.counterparty_claimable_outpoints.get($txid) {
1212+
for &(ref htlc, ref source_option) in latest_outpoints.iter() {
1213+
if let &Some(ref source) = source_option {
1214+
// Check if the HTLC is present in the commitment transaction that was
1215+
// broadcast, but not if it was below the dust limit, which we should
1216+
// fail backwards immediately as there is no way for us to learn the
1217+
// payment_preimage.
1218+
// Note that if the dust limit were allowed to change between
1219+
// commitment transactions we'd want to be check whether *any*
1220+
// broadcastable commitment transaction has the HTLC in it, but it
1221+
// cannot currently change after channel initialization, so we don't
1222+
// need to here.
1223+
let confirmed_htlcs_iter: &mut Iterator<Item = (&HTLCOutputInCommitment, Option<&HTLCSource>)> = &mut $confirmed_htlcs_list;
1224+
let mut matched_htlc = false;
1225+
for (ref broadcast_htlc, ref broadcast_source) in confirmed_htlcs_iter {
1226+
if broadcast_htlc.transaction_output_index.is_some() && Some(&**source) == *broadcast_source {
1227+
matched_htlc = true;
1228+
break;
1229+
}
1230+
}
1231+
if matched_htlc { continue; }
1232+
$self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
1233+
if entry.height != $commitment_tx_conf_height { return true; }
1234+
match entry.event {
1235+
OnchainEvent::HTLCUpdate { source: ref update_source, .. } => {
1236+
*update_source != **source
1237+
},
1238+
_ => true,
1239+
}
1240+
});
1241+
let entry = OnchainEventEntry {
1242+
txid: *$txid,
1243+
height: $commitment_tx_conf_height,
1244+
event: OnchainEvent::HTLCUpdate {
1245+
source: (**source).clone(),
1246+
payment_hash: htlc.payment_hash.clone(),
1247+
onchain_value_satoshis: Some(htlc.amount_msat / 1000),
1248+
},
1249+
};
1250+
log_trace!($logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of {} commitment transaction, waiting for confirmation (at height {})",
1251+
log_bytes!(htlc.payment_hash.0), $commitment_tx, $commitment_tx_type, entry.confirmation_threshold());
1252+
$self.onchain_events_awaiting_threshold_conf.push(entry);
1253+
}
1254+
}
1255+
}
1256+
}
1257+
}
1258+
if let Some(ref txid) = $self.current_counterparty_commitment_txid {
1259+
check_htlc_fails!(txid, "current");
1260+
}
1261+
if let Some(ref txid) = $self.prev_counterparty_commitment_txid {
1262+
check_htlc_fails!(txid, "previous");
1263+
}
1264+
} }
1265+
}
1266+
12041267
impl<Signer: Sign> ChannelMonitorImpl<Signer> {
12051268
/// Inserts a revocation secret into this channel monitor. Prunes old preimages if neither
12061269
/// needed by holder commitment transactions HTCLs nor by counterparty ones. Unless we haven't already seen
@@ -1558,43 +1621,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
15581621
}
15591622
self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number);
15601623

1561-
macro_rules! check_htlc_fails {
1562-
($txid: expr, $commitment_tx: expr) => {
1563-
if let Some(ref outpoints) = self.counterparty_claimable_outpoints.get($txid) {
1564-
for &(ref htlc, ref source_option) in outpoints.iter() {
1565-
if let &Some(ref source) = source_option {
1566-
self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
1567-
if entry.height != height { return true; }
1568-
match entry.event {
1569-
OnchainEvent::HTLCUpdate { source: ref update_source, .. } => {
1570-
*update_source != **source
1571-
},
1572-
_ => true,
1573-
}
1574-
});
1575-
let entry = OnchainEventEntry {
1576-
txid: *$txid,
1577-
height,
1578-
event: OnchainEvent::HTLCUpdate {
1579-
source: (**source).clone(),
1580-
payment_hash: htlc.payment_hash.clone(),
1581-
onchain_value_satoshis: Some(htlc.amount_msat / 1000),
1582-
},
1583-
};
1584-
log_info!(logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of revoked counterparty commitment transaction, waiting for confirmation (at height {})", log_bytes!(htlc.payment_hash.0), $commitment_tx, entry.confirmation_threshold());
1585-
self.onchain_events_awaiting_threshold_conf.push(entry);
1586-
}
1587-
}
1588-
}
1589-
}
1590-
}
1591-
if let Some(ref txid) = self.current_counterparty_commitment_txid {
1592-
check_htlc_fails!(txid, "current");
1593-
}
1594-
if let Some(ref txid) = self.prev_counterparty_commitment_txid {
1595-
check_htlc_fails!(txid, "counterparty");
1596-
}
1597-
// No need to check holder commitment txn, symmetric HTLCSource must be present as per-htlc data on counterparty commitment tx
1624+
fail_unbroadcast_htlcs!(self, "revoked counterparty", height, [].iter().map(|a| *a), logger);
15981625
}
15991626
} else if let Some(per_commitment_data) = per_commitment_option {
16001627
// While this isn't useful yet, there is a potential race where if a counterparty
@@ -1610,56 +1637,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
16101637
self.counterparty_commitment_txn_on_chain.insert(commitment_txid, commitment_number);
16111638

16121639
log_info!(logger, "Got broadcast of non-revoked counterparty commitment transaction {}", commitment_txid);
1613-
1614-
macro_rules! check_htlc_fails {
1615-
($txid: expr, $commitment_tx: expr, $id: tt) => {
1616-
if let Some(ref latest_outpoints) = self.counterparty_claimable_outpoints.get($txid) {
1617-
$id: for &(ref htlc, ref source_option) in latest_outpoints.iter() {
1618-
if let &Some(ref source) = source_option {
1619-
// Check if the HTLC is present in the commitment transaction that was
1620-
// broadcast, but not if it was below the dust limit, which we should
1621-
// fail backwards immediately as there is no way for us to learn the
1622-
// payment_preimage.
1623-
// Note that if the dust limit were allowed to change between
1624-
// commitment transactions we'd want to be check whether *any*
1625-
// broadcastable commitment transaction has the HTLC in it, but it
1626-
// cannot currently change after channel initialization, so we don't
1627-
// need to here.
1628-
for &(ref broadcast_htlc, ref broadcast_source) in per_commitment_data.iter() {
1629-
if broadcast_htlc.transaction_output_index.is_some() && Some(source) == broadcast_source.as_ref() {
1630-
continue $id;
1631-
}
1632-
}
1633-
log_trace!(logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of counterparty commitment transaction", log_bytes!(htlc.payment_hash.0), $commitment_tx);
1634-
self.onchain_events_awaiting_threshold_conf.retain(|ref entry| {
1635-
if entry.height != height { return true; }
1636-
match entry.event {
1637-
OnchainEvent::HTLCUpdate { source: ref update_source, .. } => {
1638-
*update_source != **source
1639-
},
1640-
_ => true,
1641-
}
1642-
});
1643-
self.onchain_events_awaiting_threshold_conf.push(OnchainEventEntry {
1644-
txid: *$txid,
1645-
height,
1646-
event: OnchainEvent::HTLCUpdate {
1647-
source: (**source).clone(),
1648-
payment_hash: htlc.payment_hash.clone(),
1649-
onchain_value_satoshis: Some(htlc.amount_msat / 1000),
1650-
},
1651-
});
1652-
}
1653-
}
1654-
}
1655-
}
1656-
}
1657-
if let Some(ref txid) = self.current_counterparty_commitment_txid {
1658-
check_htlc_fails!(txid, "current", 'current_loop);
1659-
}
1660-
if let Some(ref txid) = self.prev_counterparty_commitment_txid {
1661-
check_htlc_fails!(txid, "previous", 'prev_loop);
1662-
}
1640+
fail_unbroadcast_htlcs!(self, "counterparty", height, per_commitment_data.iter().map(|(a, b)| (a, b.as_ref().map(|b| b.as_ref()))), logger);
16631641

16641642
let htlc_claim_reqs = self.get_counterparty_htlc_output_claim_reqs(commitment_number, commitment_txid, Some(tx));
16651643
for req in htlc_claim_reqs {

0 commit comments

Comments
 (0)