Skip to content

Commit a5bcd56

Browse files
authored
Merge pull request #280 from TheBlueMatt/2018-12-no-to-remote-revoked-htlcs
Move fail-backwards up for no to-remote output claims
2 parents 0faf7bb + e662fa1 commit a5bcd56

File tree

2 files changed

+51
-34
lines changed

2 files changed

+51
-34
lines changed

src/ln/channelmonitor.rs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,11 +1179,34 @@ impl ChannelMonitor {
11791179
}
11801180
}
11811181

1182-
if !inputs.is_empty() || !txn_to_broadcast.is_empty() { // ie we're confident this is actually ours
1182+
if !inputs.is_empty() || !txn_to_broadcast.is_empty() || per_commitment_option.is_some() { // ie we're confident this is actually ours
11831183
// We're definitely a remote commitment transaction!
11841184
log_trace!(self, "Got broadcast of revoked remote commitment transaction, generating general spend tx with {} inputs and {} other txn to broadcast", inputs.len(), txn_to_broadcast.len());
11851185
watch_outputs.append(&mut tx.output.clone());
11861186
self.remote_commitment_txn_on_chain.insert(commitment_txid, (commitment_number, tx.output.iter().map(|output| { output.script_pubkey.clone() }).collect()));
1187+
1188+
// TODO: We really should only fail backwards after our revocation claims have been
1189+
// confirmed, but we also need to do more other tracking of in-flight pre-confirm
1190+
// on-chain claims, so we can do that at the same time.
1191+
macro_rules! check_htlc_fails {
1192+
($txid: expr, $commitment_tx: expr) => {
1193+
if let Some(&(_, ref outpoints)) = self.remote_claimable_outpoints.get(&$txid) {
1194+
for &(ref payment_hash, ref source, _) in outpoints.iter() {
1195+
log_trace!(self, "Failing HTLC with payment_hash {} from {} remote commitment tx due to broadcast of revoked remote commitment transaction", log_bytes!(payment_hash.0), $commitment_tx);
1196+
htlc_updated.push(((*source).clone(), None, payment_hash.clone()));
1197+
}
1198+
}
1199+
}
1200+
}
1201+
if let Storage::Local { ref current_remote_commitment_txid, ref prev_remote_commitment_txid, .. } = self.key_storage {
1202+
if let &Some(ref txid) = current_remote_commitment_txid {
1203+
check_htlc_fails!(txid, "current");
1204+
}
1205+
if let &Some(ref txid) = prev_remote_commitment_txid {
1206+
check_htlc_fails!(txid, "remote");
1207+
}
1208+
}
1209+
// No need to check local commitment txn, symmetric HTLCSource must be present as per-htlc data on remote commitment tx
11871210
}
11881211
if inputs.is_empty() { return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs, htlc_updated); } // Nothing to be done...probably a false positive/local tx
11891212

@@ -1211,29 +1234,6 @@ impl ChannelMonitor {
12111234
output: spend_tx.output[0].clone(),
12121235
});
12131236
txn_to_broadcast.push(spend_tx);
1214-
1215-
// TODO: We really should only fail backwards after our revocation claims have been
1216-
// confirmed, but we also need to do more other tracking of in-flight pre-confirm
1217-
// on-chain claims, so we can do that at the same time.
1218-
if let Storage::Local { ref current_remote_commitment_txid, ref prev_remote_commitment_txid, .. } = self.key_storage {
1219-
if let &Some(ref txid) = current_remote_commitment_txid {
1220-
if let Some(&(_, ref latest_outpoints)) = self.remote_claimable_outpoints.get(&txid) {
1221-
for &(ref payment_hash, ref source, _) in latest_outpoints.iter() {
1222-
log_trace!(self, "Failing HTLC with payment_hash {} from current remote commitment tx due to broadcast of revoked remote commitment transaction", log_bytes!(payment_hash.0));
1223-
htlc_updated.push(((*source).clone(), None, payment_hash.clone()));
1224-
}
1225-
}
1226-
}
1227-
if let &Some(ref txid) = prev_remote_commitment_txid {
1228-
if let Some(&(_, ref prev_outpoint)) = self.remote_claimable_outpoints.get(&txid) {
1229-
for &(ref payment_hash, ref source, _) in prev_outpoint.iter() {
1230-
log_trace!(self, "Failing HTLC with payment_hash {} from previous remote commitment tx due to broadcast of revoked remote commitment transaction", log_bytes!(payment_hash.0));
1231-
htlc_updated.push(((*source).clone(), None, payment_hash.clone()));
1232-
}
1233-
}
1234-
}
1235-
}
1236-
// No need to check local commitment txn, symmetric HTLCSource must be present as per-htlc data on remote commitment tx
12371237
} else if let Some(per_commitment_data) = per_commitment_option {
12381238
// While this isn't useful yet, there is a potential race where if a counterparty
12391239
// revokes a state at the same time as the commitment transaction for that state is

src/ln/functional_tests.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,7 +2951,7 @@ fn test_simple_commitment_revoked_fail_backward() {
29512951
}
29522952
}
29532953

2954-
fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool) {
2954+
fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool, use_dust: bool, no_to_remote: bool) {
29552955
// Test that if our counterparty broadcasts a revoked commitment transaction we fail all
29562956
// pending HTLCs on that channel backwards even if the HTLCs aren't present in our latest
29572957
// commitment transaction anymore.
@@ -2973,15 +2973,22 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool) {
29732973
create_announced_chan_between_nodes(&nodes, 0, 1);
29742974
let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
29752975

2976-
let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
2976+
let (payment_preimage, _payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], if no_to_remote { 10_000 } else { 3_000_000 });
29772977
// Get the will-be-revoked local txn from nodes[2]
29782978
let revoked_local_txn = nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().last_local_commitment_txn.clone();
2979+
assert_eq!(revoked_local_txn[0].output.len(), if no_to_remote { 1 } else { 2 });
29792980
// Revoke the old state
29802981
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
29812982

2982-
let (_, first_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
2983-
let (_, second_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
2984-
let (_, third_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 3000000);
2983+
let value = if use_dust {
2984+
// The dust limit applied to HTLC outputs considers the fee of the HTLC transaction as
2985+
// well, so HTLCs at exactly the dust limit will not be included in commitment txn.
2986+
nodes[2].node.channel_state.lock().unwrap().by_id.get(&chan_2.2).unwrap().our_dust_limit_satoshis * 1000
2987+
} else { 3000000 };
2988+
2989+
let (_, first_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], value);
2990+
let (_, second_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], value);
2991+
let (_, third_payment_hash) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], value);
29852992

29862993
assert!(nodes[2].node.fail_htlc_backwards(&first_payment_hash, 0));
29872994
expect_pending_htlcs_forwardable!(nodes[2]);
@@ -3043,8 +3050,8 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool) {
30433050

30443051
if deliver_bs_raa {
30453052
nodes[1].node.handle_revoke_and_ack(&nodes[2].node.get_our_node_id(), &bs_raa).unwrap();
3046-
// One monitor for the new revocation preimage, one as we generate a commitment for
3047-
// nodes[0] to fail first_payment_hash backwards.
3053+
// One monitor for the new revocation preimage, no second on as we won't generate a new
3054+
// commitment transaction for nodes[0] until process_pending_htlc_forwards().
30483055
check_added_monitors!(nodes[1], 1);
30493056
let events = nodes[1].node.get_and_clear_pending_events();
30503057
assert_eq!(events.len(), 1);
@@ -3152,9 +3159,19 @@ fn do_test_commitment_revoked_fail_backward_exhaustive(deliver_bs_raa: bool) {
31523159
}
31533160

31543161
#[test]
3155-
fn test_commitment_revoked_fail_backward_exhaustive() {
3156-
do_test_commitment_revoked_fail_backward_exhaustive(false);
3157-
do_test_commitment_revoked_fail_backward_exhaustive(true);
3162+
fn test_commitment_revoked_fail_backward_exhaustive_a() {
3163+
do_test_commitment_revoked_fail_backward_exhaustive(false, true, false);
3164+
do_test_commitment_revoked_fail_backward_exhaustive(true, true, false);
3165+
do_test_commitment_revoked_fail_backward_exhaustive(false, false, false);
3166+
do_test_commitment_revoked_fail_backward_exhaustive(true, false, false);
3167+
}
3168+
3169+
#[test]
3170+
fn test_commitment_revoked_fail_backward_exhaustive_b() {
3171+
do_test_commitment_revoked_fail_backward_exhaustive(false, true, true);
3172+
do_test_commitment_revoked_fail_backward_exhaustive(true, true, true);
3173+
do_test_commitment_revoked_fail_backward_exhaustive(false, false, true);
3174+
do_test_commitment_revoked_fail_backward_exhaustive(true, false, true);
31583175
}
31593176

31603177
#[test]

0 commit comments

Comments
 (0)