Skip to content

Commit 0432e42

Browse files
author
Antoine Riard
committed
Integrate PackageTemplate
This commit replaces InputMaterial in both ChannelMonitor/OnchainTxHandler. This doesn't change behavior.
1 parent a243862 commit 0432e42

File tree

2 files changed

+82
-320
lines changed

2 files changed

+82
-320
lines changed

lightning/src/ln/channelmonitor.rs

Lines changed: 24 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ use ln::chan_utils;
3232
use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, LocalCommitmentTransaction, HTLCType};
3333
use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash};
3434
use ln::onchaintx::OnchainTxHandler;
35-
use ln::onchain_utils::InputDescriptors;
35+
use ln::onchain_utils;
36+
use ln::onchain_utils::{InputDescriptors, PackageTemplate, LocalFundingOutput, LocalHTLCOutput, RemoteHTLCOutput, RevokedOutput};
3637
use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInterface, FeeEstimator};
3738
use chain::transaction::OutPoint;
3839
use chain::keysinterface::{SpendableOutputDescriptor, ChannelKeys};
@@ -428,129 +429,6 @@ impl Readable for RemoteCommitmentTransaction {
428429
}
429430
}
430431

431-
/// When ChannelMonitor discovers an onchain outpoint being a step of a channel and that it needs
432-
/// to generate a tx to push channel state forward, we cache outpoint-solving tx material to build
433-
/// a new bumped one in case of lenghty confirmation delay
434-
#[derive(Clone, PartialEq)]
435-
pub(crate) enum InputMaterial {
436-
Revoked {
437-
per_commitment_point: PublicKey,
438-
remote_delayed_payment_base_key: PublicKey,
439-
remote_htlc_base_key: PublicKey,
440-
per_commitment_key: SecretKey,
441-
input_descriptor: InputDescriptors,
442-
amount: u64,
443-
htlc: Option<HTLCOutputInCommitment>,
444-
on_remote_tx_csv: u16,
445-
},
446-
RemoteHTLC {
447-
per_commitment_point: PublicKey,
448-
remote_delayed_payment_base_key: PublicKey,
449-
remote_htlc_base_key: PublicKey,
450-
preimage: Option<PaymentPreimage>,
451-
htlc: HTLCOutputInCommitment
452-
},
453-
LocalHTLC {
454-
preimage: Option<PaymentPreimage>,
455-
amount: u64,
456-
},
457-
Funding {
458-
funding_redeemscript: Script,
459-
}
460-
}
461-
462-
impl Writeable for InputMaterial {
463-
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ::std::io::Error> {
464-
match self {
465-
&InputMaterial::Revoked { ref per_commitment_point, ref remote_delayed_payment_base_key, ref remote_htlc_base_key, ref per_commitment_key, ref input_descriptor, ref amount, ref htlc, ref on_remote_tx_csv} => {
466-
writer.write_all(&[0; 1])?;
467-
per_commitment_point.write(writer)?;
468-
remote_delayed_payment_base_key.write(writer)?;
469-
remote_htlc_base_key.write(writer)?;
470-
writer.write_all(&per_commitment_key[..])?;
471-
input_descriptor.write(writer)?;
472-
writer.write_all(&byte_utils::be64_to_array(*amount))?;
473-
htlc.write(writer)?;
474-
on_remote_tx_csv.write(writer)?;
475-
},
476-
&InputMaterial::RemoteHTLC { ref per_commitment_point, ref remote_delayed_payment_base_key, ref remote_htlc_base_key, ref preimage, ref htlc} => {
477-
writer.write_all(&[1; 1])?;
478-
per_commitment_point.write(writer)?;
479-
remote_delayed_payment_base_key.write(writer)?;
480-
remote_htlc_base_key.write(writer)?;
481-
preimage.write(writer)?;
482-
htlc.write(writer)?;
483-
},
484-
&InputMaterial::LocalHTLC { ref preimage, ref amount } => {
485-
writer.write_all(&[2; 1])?;
486-
preimage.write(writer)?;
487-
writer.write_all(&byte_utils::be64_to_array(*amount))?;
488-
},
489-
&InputMaterial::Funding { ref funding_redeemscript } => {
490-
writer.write_all(&[3; 1])?;
491-
funding_redeemscript.write(writer)?;
492-
}
493-
}
494-
Ok(())
495-
}
496-
}
497-
498-
impl Readable for InputMaterial {
499-
fn read<R: ::std::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
500-
let input_material = match <u8 as Readable>::read(reader)? {
501-
0 => {
502-
let per_commitment_point = Readable::read(reader)?;
503-
let remote_delayed_payment_base_key = Readable::read(reader)?;
504-
let remote_htlc_base_key = Readable::read(reader)?;
505-
let per_commitment_key = Readable::read(reader)?;
506-
let input_descriptor = Readable::read(reader)?;
507-
let amount = Readable::read(reader)?;
508-
let htlc = Readable::read(reader)?;
509-
let on_remote_tx_csv = Readable::read(reader)?;
510-
InputMaterial::Revoked {
511-
per_commitment_point,
512-
remote_delayed_payment_base_key,
513-
remote_htlc_base_key,
514-
per_commitment_key,
515-
input_descriptor,
516-
amount,
517-
htlc,
518-
on_remote_tx_csv
519-
}
520-
},
521-
1 => {
522-
let per_commitment_point = Readable::read(reader)?;
523-
let remote_delayed_payment_base_key = Readable::read(reader)?;
524-
let remote_htlc_base_key = Readable::read(reader)?;
525-
let preimage = Readable::read(reader)?;
526-
let htlc = Readable::read(reader)?;
527-
InputMaterial::RemoteHTLC {
528-
per_commitment_point,
529-
remote_delayed_payment_base_key,
530-
remote_htlc_base_key,
531-
preimage,
532-
htlc
533-
}
534-
},
535-
2 => {
536-
let preimage = Readable::read(reader)?;
537-
let amount = Readable::read(reader)?;
538-
InputMaterial::LocalHTLC {
539-
preimage,
540-
amount,
541-
}
542-
},
543-
3 => {
544-
InputMaterial::Funding {
545-
funding_redeemscript: Readable::read(reader)?,
546-
}
547-
}
548-
_ => return Err(DecodeError::InvalidValue),
549-
};
550-
Ok(input_material)
551-
}
552-
}
553-
554432
/// ClaimRequest is a descriptor structure to communicate between detection
555433
/// and reaction module. They are generated by ChannelMonitor while parsing
556434
/// onchain txn leaked from a channel and handed over to OnchainTxHandler which
@@ -566,11 +444,9 @@ pub(crate) struct ClaimRequest {
566444
// of a sooner-HTLC could be swallowed by the highest nLocktime of the HTLC set.
567445
// Do simplify we mark them as non-aggregable.
568446
pub(crate) aggregable: bool,
569-
// Basic bitcoin outpoint (txid, vout)
570-
pub(crate) outpoint: BitcoinOutPoint,
571-
// Following outpoint type, set of data needed to generate transaction digest
572-
// and satisfy witness program.
573-
pub(crate) witness_data: InputMaterial
447+
// Template (list of outpoint and set of data needed to generate transaction digest
448+
// and satisfy witness program).
449+
pub(crate) package_template: PackageTemplate,
574450
}
575451

576452
/// Upon discovering of some classes of onchain tx by ChannelMonitor, we may have to take actions on it
@@ -1508,8 +1384,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
15081384
// First, process non-htlc outputs (to_local & to_remote)
15091385
for (idx, outp) in tx.output.iter().enumerate() {
15101386
if outp.script_pubkey == revokeable_p2wsh {
1511-
let witness_data = InputMaterial::Revoked { per_commitment_point, remote_delayed_payment_base_key: self.remote_tx_cache.remote_delayed_payment_base_key, remote_htlc_base_key: self.remote_tx_cache.remote_htlc_base_key, per_commitment_key, input_descriptor: InputDescriptors::RevokedOutput, amount: outp.value, htlc: None, on_remote_tx_csv: self.remote_tx_cache.on_remote_tx_csv};
1512-
claimable_outpoints.push(ClaimRequest { absolute_timelock: height + self.remote_tx_cache.on_remote_tx_csv as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: idx as u32 }, witness_data});
1387+
let malleable_justice_tx = PackageTemplate::build_malleable_justice_tx(per_commitment_point, per_commitment_key, self.remote_tx_cache.remote_delayed_payment_base_key, self.remote_tx_cache.remote_htlc_base_key, InputDescriptors::RevokedOutput, commitment_txid, idx as u32, outp.value, None, self.remote_tx_cache.on_remote_tx_csv);
1388+
claimable_outpoints.push(ClaimRequest { absolute_timelock: height + self.remote_tx_cache.on_remote_tx_csv as u32, aggregable: true, package_template: malleable_justice_tx});
15131389
}
15141390
}
15151391

@@ -1521,8 +1397,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
15211397
tx.output[transaction_output_index as usize].value != htlc.amount_msat / 1000 {
15221398
return (claimable_outpoints, (commitment_txid, watch_outputs)); // Corrupted per_commitment_data, fuck this user
15231399
}
1524-
let witness_data = InputMaterial::Revoked { per_commitment_point, remote_delayed_payment_base_key: self.remote_tx_cache.remote_delayed_payment_base_key, remote_htlc_base_key: self.remote_tx_cache.remote_htlc_base_key, per_commitment_key, input_descriptor: if htlc.offered { InputDescriptors::RevokedOfferedHTLC } else { InputDescriptors::RevokedReceivedHTLC }, amount: tx.output[transaction_output_index as usize].value, htlc: Some(htlc.clone()), on_remote_tx_csv: self.remote_tx_cache.on_remote_tx_csv};
1525-
claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable: true, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
1400+
let malleable_justice_tx = PackageTemplate::build_malleable_justice_tx(per_commitment_point, per_commitment_key, self.remote_tx_cache.remote_delayed_payment_base_key, self.remote_tx_cache.remote_htlc_base_key, if htlc.offered { InputDescriptors::RevokedOfferedHTLC } else { InputDescriptors::RevokedReceivedHTLC }, commitment_txid, transaction_output_index, htlc.amount_msat / 1000, Some(htlc.clone()), self.remote_tx_cache.on_remote_tx_csv);
1401+
claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable: true, package_template: malleable_justice_tx});
15261402
}
15271403
}
15281404
}
@@ -1656,8 +1532,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
16561532
let preimage = if htlc.offered { if let Some(p) = self.payment_preimages.get(&htlc.payment_hash) { Some(*p) } else { None } } else { None };
16571533
let aggregable = if !htlc.offered { false } else { true };
16581534
if preimage.is_some() || !htlc.offered {
1659-
let witness_data = InputMaterial::RemoteHTLC { per_commitment_point: *revocation_point, remote_delayed_payment_base_key: self.remote_tx_cache.remote_delayed_payment_base_key, remote_htlc_base_key: self.remote_tx_cache.remote_htlc_base_key, preimage, htlc: htlc.clone() };
1660-
claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable, outpoint: BitcoinOutPoint { txid: commitment_txid, vout: transaction_output_index }, witness_data });
1535+
let remote_htlc_tx = PackageTemplate::build_remote_htlc_tx(*revocation_point, self.remote_tx_cache.remote_delayed_payment_base_key, self.remote_tx_cache.remote_htlc_base_key, preimage, htlc.clone(), commitment_txid, transaction_output_index);
1536+
claimable_outpoints.push(ClaimRequest { absolute_timelock: htlc.cltv_expiry, aggregable, package_template: remote_htlc_tx });
16611537
}
16621538
}
16631539
}
@@ -1688,8 +1564,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
16881564
let per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &per_commitment_key);
16891565

16901566
log_trace!(logger, "Remote HTLC broadcast {}:{}", htlc_txid, 0);
1691-
let witness_data = InputMaterial::Revoked { per_commitment_point, remote_delayed_payment_base_key: self.remote_tx_cache.remote_delayed_payment_base_key, remote_htlc_base_key: self.remote_tx_cache.remote_htlc_base_key, per_commitment_key, input_descriptor: InputDescriptors::RevokedOutput, amount: tx.output[0].value, htlc: None, on_remote_tx_csv: self.remote_tx_cache.on_remote_tx_csv };
1692-
let claimable_outpoints = vec!(ClaimRequest { absolute_timelock: height + self.remote_tx_cache.on_remote_tx_csv as u32, aggregable: true, outpoint: BitcoinOutPoint { txid: htlc_txid, vout: 0}, witness_data });
1567+
let malleable_justice_tx = PackageTemplate::build_malleable_justice_tx(per_commitment_point, per_commitment_key, self.remote_tx_cache.remote_delayed_payment_base_key, self.remote_tx_cache.remote_htlc_base_key, InputDescriptors::RevokedOutput, htlc_txid, 0, tx.output[0].value, None, self.remote_tx_cache.on_remote_tx_csv);
1568+
let claimable_outpoints = vec!(ClaimRequest { absolute_timelock: height + self.remote_tx_cache.on_remote_tx_csv as u32, aggregable: true, package_template: malleable_justice_tx });
16931569
(claimable_outpoints, Some((htlc_txid, tx.output.clone())))
16941570
}
16951571

@@ -1702,18 +1578,15 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
17021578

17031579
for &(ref htlc, _, _) in local_tx.htlc_outputs.iter() {
17041580
if let Some(transaction_output_index) = htlc.transaction_output_index {
1705-
claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, outpoint: BitcoinOutPoint { txid: local_tx.txid, vout: transaction_output_index as u32 },
1706-
witness_data: InputMaterial::LocalHTLC {
1707-
preimage: if !htlc.offered {
1708-
if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) {
1709-
Some(preimage.clone())
1710-
} else {
1711-
// We can't build an HTLC-Success transaction without the preimage
1712-
continue;
1713-
}
1714-
} else { None },
1715-
amount: htlc.amount_msat,
1716-
}});
1581+
let local_htlc_tx = PackageTemplate::build_local_htlc_tx(if !htlc.offered {
1582+
if let Some(preimage) = self.payment_preimages.get(&htlc.payment_hash) {
1583+
Some(preimage.clone())
1584+
} else {
1585+
// We can't build an HTLC-Success transaction without the preimage
1586+
continue;
1587+
}
1588+
} else { None }, htlc.amount_msat, local_tx.txid, transaction_output_index);
1589+
claim_requests.push(ClaimRequest { absolute_timelock: ::std::u32::MAX, aggregable: false, package_template: local_htlc_tx });
17171590
watch_outputs.push(commitment_tx.output[transaction_output_index as usize].clone());
17181591
}
17191592
}
@@ -1926,7 +1799,8 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
19261799
}
19271800
let should_broadcast = self.would_broadcast_at_height(height, &logger);
19281801
if should_broadcast {
1929-
claimable_outpoints.push(ClaimRequest { absolute_timelock: height, aggregable: false, outpoint: BitcoinOutPoint { txid: self.funding_info.0.txid.clone(), vout: self.funding_info.0.index as u32 }, witness_data: InputMaterial::Funding { funding_redeemscript: self.funding_redeemscript.clone() }});
1802+
let local_commitment_tx = PackageTemplate::build_local_commitment_tx(self.funding_redeemscript.clone(), self.funding_info.0.txid.clone(), self.funding_info.0.index as u32);
1803+
claimable_outpoints.push(ClaimRequest { absolute_timelock: height, aggregable: false, package_template: local_commitment_tx });
19301804
}
19311805
if should_broadcast {
19321806
if let Some(commitment_tx) = self.onchain_tx_handler.get_fully_signed_local_tx(&self.funding_redeemscript) {

0 commit comments

Comments
 (0)