mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 15:20:24 +01:00
Avoid claiming remote received HTLCs with preimage
In case of duplicate HTLCs with same hash going in opposite directions we may learn preimage of offered one, but we shouldn't claim received one to avoid invalidation of combined claim. The received HTLC is going to be claimed by a timeout tx at timelock expiration. Fix #337
This commit is contained in:
parent
2afd53148f
commit
543b0983f6
1 changed files with 40 additions and 38 deletions
|
@ -1643,46 +1643,48 @@ impl ChannelMonitor {
|
||||||
return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs); // Corrupted per_commitment_data, fuck this user
|
return (txn_to_broadcast, (commitment_txid, watch_outputs), spendable_outputs); // Corrupted per_commitment_data, fuck this user
|
||||||
}
|
}
|
||||||
if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
|
if let Some(payment_preimage) = self.payment_preimages.get(&htlc.payment_hash) {
|
||||||
let input = TxIn {
|
if htlc.offered {
|
||||||
previous_output: BitcoinOutPoint {
|
let input = TxIn {
|
||||||
txid: commitment_txid,
|
previous_output: BitcoinOutPoint {
|
||||||
vout: transaction_output_index,
|
txid: commitment_txid,
|
||||||
},
|
vout: transaction_output_index,
|
||||||
script_sig: Script::new(),
|
},
|
||||||
sequence: idx as u32, // reset to 0xfffffffd in sign_input
|
script_sig: Script::new(),
|
||||||
witness: Vec::new(),
|
sequence: idx as u32, // reset to 0xfffffffd in sign_input
|
||||||
};
|
witness: Vec::new(),
|
||||||
if htlc.cltv_expiry > height + CLTV_SHARED_CLAIM_BUFFER {
|
|
||||||
inputs.push(input);
|
|
||||||
inputs_desc.push(if htlc.offered { InputDescriptors::OfferedHTLC } else { InputDescriptors::ReceivedHTLC });
|
|
||||||
inputs_info.push((payment_preimage, tx.output[transaction_output_index as usize].value, htlc.cltv_expiry));
|
|
||||||
total_value += tx.output[transaction_output_index as usize].value;
|
|
||||||
} else {
|
|
||||||
let mut single_htlc_tx = Transaction {
|
|
||||||
version: 2,
|
|
||||||
lock_time: 0,
|
|
||||||
input: vec![input],
|
|
||||||
output: vec!(TxOut {
|
|
||||||
script_pubkey: self.destination_script.clone(),
|
|
||||||
value: htlc.amount_msat / 1000,
|
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
let predicted_weight = single_htlc_tx.get_weight() + Self::get_witnesses_weight(&[if htlc.offered { InputDescriptors::OfferedHTLC } else { InputDescriptors::ReceivedHTLC }]);
|
if htlc.cltv_expiry > height + CLTV_SHARED_CLAIM_BUFFER {
|
||||||
let height_timer = Self::get_height_timer(height, htlc.cltv_expiry);
|
inputs.push(input);
|
||||||
let mut used_feerate;
|
inputs_desc.push(if htlc.offered { InputDescriptors::OfferedHTLC } else { InputDescriptors::ReceivedHTLC });
|
||||||
if subtract_high_prio_fee!(self, fee_estimator, single_htlc_tx.output[0].value, predicted_weight, tx.txid(), used_feerate) {
|
inputs_info.push((payment_preimage, tx.output[transaction_output_index as usize].value, htlc.cltv_expiry));
|
||||||
let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx);
|
total_value += tx.output[transaction_output_index as usize].value;
|
||||||
let (redeemscript, htlc_key) = sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.0.to_vec());
|
} else {
|
||||||
assert!(predicted_weight >= single_htlc_tx.get_weight());
|
let mut single_htlc_tx = Transaction {
|
||||||
spendable_outputs.push(SpendableOutputDescriptor::StaticOutput {
|
version: 2,
|
||||||
outpoint: BitcoinOutPoint { txid: single_htlc_tx.txid(), vout: 0 },
|
lock_time: 0,
|
||||||
output: single_htlc_tx.output[0].clone(),
|
input: vec![input],
|
||||||
});
|
output: vec!(TxOut {
|
||||||
match self.our_claim_txn_waiting_first_conf.entry(single_htlc_tx.input[0].previous_output.clone()) {
|
script_pubkey: self.destination_script.clone(),
|
||||||
hash_map::Entry::Occupied(_) => {},
|
value: htlc.amount_msat / 1000,
|
||||||
hash_map::Entry::Vacant(entry) => { entry.insert((height_timer, TxMaterial::RemoteHTLC { script: redeemscript, key: htlc_key, preimage: Some(*payment_preimage), amount: htlc.amount_msat / 1000 }, used_feerate, htlc.cltv_expiry, height)); }
|
}),
|
||||||
|
};
|
||||||
|
let predicted_weight = single_htlc_tx.get_weight() + Self::get_witnesses_weight(&[if htlc.offered { InputDescriptors::OfferedHTLC } else { InputDescriptors::ReceivedHTLC }]);
|
||||||
|
let height_timer = Self::get_height_timer(height, htlc.cltv_expiry);
|
||||||
|
let mut used_feerate;
|
||||||
|
if subtract_high_prio_fee!(self, fee_estimator, single_htlc_tx.output[0].value, predicted_weight, tx.txid(), used_feerate) {
|
||||||
|
let sighash_parts = bip143::SighashComponents::new(&single_htlc_tx);
|
||||||
|
let (redeemscript, htlc_key) = sign_input!(sighash_parts, single_htlc_tx.input[0], htlc.amount_msat / 1000, payment_preimage.0.to_vec());
|
||||||
|
assert!(predicted_weight >= single_htlc_tx.get_weight());
|
||||||
|
spendable_outputs.push(SpendableOutputDescriptor::StaticOutput {
|
||||||
|
outpoint: BitcoinOutPoint { txid: single_htlc_tx.txid(), vout: 0 },
|
||||||
|
output: single_htlc_tx.output[0].clone(),
|
||||||
|
});
|
||||||
|
match self.our_claim_txn_waiting_first_conf.entry(single_htlc_tx.input[0].previous_output.clone()) {
|
||||||
|
hash_map::Entry::Occupied(_) => {},
|
||||||
|
hash_map::Entry::Vacant(entry) => { entry.insert((height_timer, TxMaterial::RemoteHTLC { script: redeemscript, key: htlc_key, preimage: Some(*payment_preimage), amount: htlc.amount_msat / 1000 }, used_feerate, htlc.cltv_expiry, height)); }
|
||||||
|
}
|
||||||
|
txn_to_broadcast.push(single_htlc_tx);
|
||||||
}
|
}
|
||||||
txn_to_broadcast.push(single_htlc_tx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue