Delay failure of non-dust HTLC-outputs until solving timeout tx matures

Fix tests broken by introduced change
This commit is contained in:
Antoine Riard 2019-02-06 20:02:38 -05:00
parent 587af43eca
commit a2b6a76e59
3 changed files with 22 additions and 5 deletions

File diff suppressed because one or more lines are too long

View file

@ -1876,7 +1876,7 @@ impl ChannelMonitor {
// While all commitment/HTLC-Success/HTLC-Timeout transactions have one input, HTLCs // While all commitment/HTLC-Success/HTLC-Timeout transactions have one input, HTLCs
// can also be resolved in a few other ways which can have more than one output. Thus, // can also be resolved in a few other ways which can have more than one output. Thus,
// we call is_resolving_htlc_output here outside of the tx.input.len() == 1 check. // we call is_resolving_htlc_output here outside of the tx.input.len() == 1 check.
let mut updated = self.is_resolving_htlc_output(tx); let mut updated = self.is_resolving_htlc_output(tx, height);
if updated.len() > 0 { if updated.len() > 0 {
htlc_updated.append(&mut updated); htlc_updated.append(&mut updated);
} }
@ -1994,7 +1994,7 @@ impl ChannelMonitor {
/// Check if any transaction broadcasted is resolving HTLC output by a success or timeout on a local /// Check if any transaction broadcasted is resolving HTLC output by a success or timeout on a local
/// or remote commitment tx, if so send back the source, preimage if found and payment_hash of resolved HTLC /// or remote commitment tx, if so send back the source, preimage if found and payment_hash of resolved HTLC
fn is_resolving_htlc_output(&mut self, tx: &Transaction) -> Vec<(HTLCSource, Option<PaymentPreimage>, PaymentHash)> { fn is_resolving_htlc_output(&mut self, tx: &Transaction, height: u32) -> Vec<(HTLCSource, Option<PaymentPreimage>, PaymentHash)> {
let mut htlc_updated = Vec::new(); let mut htlc_updated = Vec::new();
'outer_loop: for input in &tx.input { 'outer_loop: for input in &tx.input {
@ -2101,7 +2101,17 @@ impl ChannelMonitor {
payment_preimage.0.copy_from_slice(&input.witness[1]); payment_preimage.0.copy_from_slice(&input.witness[1]);
htlc_updated.push((source, Some(payment_preimage), payment_hash)); htlc_updated.push((source, Some(payment_preimage), payment_hash));
} else { } else {
htlc_updated.push((source, None, payment_hash)); log_info!(self, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height{})", log_bytes!(payment_hash.0), height + HTLC_FAIL_ANTI_REORG_DELAY - 1);
match self.htlc_updated_waiting_threshold_conf.entry(height + HTLC_FAIL_ANTI_REORG_DELAY - 1) {
hash_map::Entry::Occupied(mut entry) => {
let e = entry.get_mut();
e.retain(|ref update| update.0 != source);
e.push((source, None, payment_hash.clone()));
}
hash_map::Entry::Vacant(entry) => {
entry.insert(vec![(source, None, payment_hash)]);
}
}
} }
} }
} }

View file

@ -2241,6 +2241,7 @@ fn test_htlc_on_chain_timeout() {
} }
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![timeout_tx]}, 1); nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![timeout_tx]}, 1);
connect_blocks(&nodes[1].chain_monitor, HTLC_FAIL_ANTI_REORG_DELAY - 1, 1, true, header.bitcoin_hash());
check_added_monitors!(nodes[1], 0); check_added_monitors!(nodes[1], 0);
check_closed_broadcast!(nodes[1]); check_closed_broadcast!(nodes[1]);
@ -3898,6 +3899,7 @@ fn test_duplicate_payment_hash_one_failure_one_success() {
check_spends!(htlc_success_txn[1], commitment_txn[0].clone()); check_spends!(htlc_success_txn[1], commitment_txn[0].clone());
nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![htlc_timeout_tx] }, 200); nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![htlc_timeout_tx] }, 200);
connect_blocks(&nodes[1].chain_monitor, HTLC_FAIL_ANTI_REORG_DELAY - 1, 200, true, header.bitcoin_hash());
expect_pending_htlcs_forwardable!(nodes[1]); expect_pending_htlcs_forwardable!(nodes[1]);
let htlc_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); let htlc_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
assert!(htlc_updates.update_add_htlcs.is_empty()); assert!(htlc_updates.update_add_htlcs.is_empty());