Skip to content

Commit 71f4749

Browse files
authored
Merge pull request #1685 from wpaulino/anchors-prep
2 parents d2a9ae0 + f3a5a72 commit 71f4749

9 files changed

+305
-314
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use bitcoin::secp256k1;
3737
use ln::{PaymentHash, PaymentPreimage};
3838
use ln::msgs::DecodeError;
3939
use ln::chan_utils;
40-
use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCType, ChannelTransactionParameters, HolderCommitmentTransaction};
40+
use ln::chan_utils::{CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HTLCClaim, ChannelTransactionParameters, HolderCommitmentTransaction};
4141
use ln::channelmanager::HTLCSource;
4242
use chain;
4343
use chain::{BestBlock, WatchedOutput};
@@ -793,7 +793,10 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
793793
// of block connection between ChannelMonitors and the ChannelManager.
794794
funding_spend_seen: bool,
795795

796+
/// Set to `Some` of the confirmed transaction spending the funding input of the channel after
797+
/// reaching `ANTI_REORG_DELAY` confirmations.
796798
funding_spend_confirmed: Option<Txid>,
799+
797800
confirmed_commitment_tx_counterparty_output: CommitmentTxCounterpartyOutputInfo,
798801
/// The set of HTLCs which have been either claimed or failed on chain and have reached
799802
/// the requisite confirmations on the claim/fail transaction (either ANTI_REORG_DELAY or the
@@ -2650,6 +2653,11 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
26502653
let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript);
26512654
let txid = commitment_tx.txid();
26522655
let mut holder_transactions = vec![commitment_tx];
2656+
// When anchor outputs are present, the HTLC transactions are only valid once the commitment
2657+
// transaction confirms.
2658+
if self.onchain_tx_handler.opt_anchors() {
2659+
return holder_transactions;
2660+
}
26532661
for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
26542662
if let Some(vout) = htlc.0.transaction_output_index {
26552663
let preimage = if !htlc.0.offered {
@@ -2683,6 +2691,11 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
26832691
let commitment_tx = self.onchain_tx_handler.get_fully_signed_copy_holder_tx(&self.funding_redeemscript);
26842692
let txid = commitment_tx.txid();
26852693
let mut holder_transactions = vec![commitment_tx];
2694+
// When anchor outputs are present, the HTLC transactions are only final once the commitment
2695+
// transaction confirms due to the CSV 1 encumberance.
2696+
if self.onchain_tx_handler.opt_anchors() {
2697+
return holder_transactions;
2698+
}
26862699
for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
26872700
if let Some(vout) = htlc.0.transaction_output_index {
26882701
let preimage = if !htlc.0.offered {
@@ -3068,6 +3081,16 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
30683081
}
30693082

30703083
fn should_broadcast_holder_commitment_txn<L: Deref>(&self, logger: &L) -> bool where L::Target: Logger {
3084+
// There's no need to broadcast our commitment transaction if we've seen one confirmed (even
3085+
// with 1 confirmation) as it'll be rejected as duplicate/conflicting.
3086+
if self.funding_spend_confirmed.is_some() ||
3087+
self.onchain_events_awaiting_threshold_conf.iter().find(|event| match event.event {
3088+
OnchainEvent::FundingSpendConfirmation { .. } => true,
3089+
_ => false,
3090+
}).is_some()
3091+
{
3092+
return false;
3093+
}
30713094
// We need to consider all HTLCs which are:
30723095
// * in any unrevoked counterparty commitment transaction, as they could broadcast said
30733096
// transactions and we'd end up in a race, or
@@ -3136,25 +3159,15 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
31363159
fn is_resolving_htlc_output<L: Deref>(&mut self, tx: &Transaction, height: u32, logger: &L) where L::Target: Logger {
31373160
'outer_loop: for input in &tx.input {
31383161
let mut payment_data = None;
3139-
let witness_items = input.witness.len();
3140-
let htlctype = input.witness.last().map(|w| w.len()).and_then(HTLCType::scriptlen_to_htlctype);
3141-
let prev_last_witness_len = input.witness.second_to_last().map(|w| w.len()).unwrap_or(0);
3142-
let revocation_sig_claim = (witness_items == 3 && htlctype == Some(HTLCType::OfferedHTLC) && prev_last_witness_len == 33)
3143-
|| (witness_items == 3 && htlctype == Some(HTLCType::AcceptedHTLC) && prev_last_witness_len == 33);
3144-
let accepted_preimage_claim = witness_items == 5 && htlctype == Some(HTLCType::AcceptedHTLC)
3145-
&& input.witness.second_to_last().unwrap().len() == 32;
3146-
#[cfg(not(fuzzing))]
3147-
let accepted_timeout_claim = witness_items == 3 && htlctype == Some(HTLCType::AcceptedHTLC) && !revocation_sig_claim;
3148-
let offered_preimage_claim = witness_items == 3 && htlctype == Some(HTLCType::OfferedHTLC) &&
3149-
!revocation_sig_claim && input.witness.second_to_last().unwrap().len() == 32;
3150-
3151-
#[cfg(not(fuzzing))]
3152-
let offered_timeout_claim = witness_items == 5 && htlctype == Some(HTLCType::OfferedHTLC);
3162+
let htlc_claim = HTLCClaim::from_witness(&input.witness);
3163+
let revocation_sig_claim = htlc_claim == Some(HTLCClaim::Revocation);
3164+
let accepted_preimage_claim = htlc_claim == Some(HTLCClaim::AcceptedPreimage);
3165+
let accepted_timeout_claim = htlc_claim == Some(HTLCClaim::AcceptedTimeout);
3166+
let offered_preimage_claim = htlc_claim == Some(HTLCClaim::OfferedPreimage);
3167+
let offered_timeout_claim = htlc_claim == Some(HTLCClaim::OfferedTimeout);
31533168

31543169
let mut payment_preimage = PaymentPreimage([0; 32]);
3155-
if accepted_preimage_claim {
3156-
payment_preimage.0.copy_from_slice(input.witness.second_to_last().unwrap());
3157-
} else if offered_preimage_claim {
3170+
if offered_preimage_claim || accepted_preimage_claim {
31583171
payment_preimage.0.copy_from_slice(input.witness.second_to_last().unwrap());
31593172
}
31603173

lightning/src/ln/chan_utils.rs

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ use chain;
4242
use util::crypto::sign;
4343

4444
pub(crate) const MAX_HTLCS: u16 = 483;
45+
pub(crate) const OFFERED_HTLC_SCRIPT_WEIGHT: usize = 133;
46+
pub(crate) const OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS: usize = 136;
47+
// The weight of `accepted_htlc_script` can vary in function of its CLTV argument value. We define a
48+
// range that encompasses both its non-anchors and anchors variants.
49+
pub(crate) const MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 136;
50+
pub(crate) const MAX_ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 143;
4551

4652
/// Gets the weight for an HTLC-Success transaction.
4753
#[inline]
@@ -60,18 +66,72 @@ pub fn htlc_timeout_tx_weight(opt_anchors: bool) -> u64 {
6066
}
6167

6268
#[derive(PartialEq)]
63-
pub(crate) enum HTLCType {
64-
AcceptedHTLC,
65-
OfferedHTLC
69+
pub(crate) enum HTLCClaim {
70+
OfferedTimeout,
71+
OfferedPreimage,
72+
AcceptedTimeout,
73+
AcceptedPreimage,
74+
Revocation,
6675
}
6776

68-
impl HTLCType {
69-
/// Check if a given tx witnessScript len matchs one of a pre-signed HTLC
70-
pub(crate) fn scriptlen_to_htlctype(witness_script_len: usize) -> Option<HTLCType> {
71-
if witness_script_len == 133 {
72-
Some(HTLCType::OfferedHTLC)
73-
} else if witness_script_len >= 136 && witness_script_len <= 139 {
74-
Some(HTLCType::AcceptedHTLC)
77+
impl HTLCClaim {
78+
/// Check if a given input witness attempts to claim a HTLC.
79+
pub(crate) fn from_witness(witness: &Witness) -> Option<Self> {
80+
debug_assert_eq!(OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS, MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT);
81+
if witness.len() < 2 {
82+
return None;
83+
}
84+
let witness_script = witness.last().unwrap();
85+
let second_to_last = witness.second_to_last().unwrap();
86+
if witness_script.len() == OFFERED_HTLC_SCRIPT_WEIGHT {
87+
if witness.len() == 3 && second_to_last.len() == 33 {
88+
// <revocation sig> <revocationpubkey> <witness_script>
89+
Some(Self::Revocation)
90+
} else if witness.len() == 3 && second_to_last.len() == 32 {
91+
// <remotehtlcsig> <payment_preimage> <witness_script>
92+
Some(Self::OfferedPreimage)
93+
} else if witness.len() == 5 && second_to_last.len() == 0 {
94+
// 0 <remotehtlcsig> <localhtlcsig> <> <witness_script>
95+
Some(Self::OfferedTimeout)
96+
} else {
97+
None
98+
}
99+
} else if witness_script.len() == OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS {
100+
// It's possible for the weight of `offered_htlc_script` and `accepted_htlc_script` to
101+
// match so we check for both here.
102+
if witness.len() == 3 && second_to_last.len() == 33 {
103+
// <revocation sig> <revocationpubkey> <witness_script>
104+
Some(Self::Revocation)
105+
} else if witness.len() == 3 && second_to_last.len() == 32 {
106+
// <remotehtlcsig> <payment_preimage> <witness_script>
107+
Some(Self::OfferedPreimage)
108+
} else if witness.len() == 5 && second_to_last.len() == 0 {
109+
// 0 <remotehtlcsig> <localhtlcsig> <> <witness_script>
110+
Some(Self::OfferedTimeout)
111+
} else if witness.len() == 3 && second_to_last.len() == 0 {
112+
// <remotehtlcsig> <> <witness_script>
113+
Some(Self::AcceptedTimeout)
114+
} else if witness.len() == 5 && second_to_last.len() == 32 {
115+
// 0 <remotehtlcsig> <localhtlcsig> <payment_preimage> <witness_script>
116+
Some(Self::AcceptedPreimage)
117+
} else {
118+
None
119+
}
120+
} else if witness_script.len() > MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT &&
121+
witness_script.len() <= MAX_ACCEPTED_HTLC_SCRIPT_WEIGHT {
122+
// Handle remaining range of ACCEPTED_HTLC_SCRIPT_WEIGHT.
123+
if witness.len() == 3 && second_to_last.len() == 33 {
124+
// <revocation sig> <revocationpubkey> <witness_script>
125+
Some(Self::Revocation)
126+
} else if witness.len() == 3 && second_to_last.len() == 0 {
127+
// <remotehtlcsig> <> <witness_script>
128+
Some(Self::AcceptedTimeout)
129+
} else if witness.len() == 5 && second_to_last.len() == 32 {
130+
// 0 <remotehtlcsig> <localhtlcsig> <payment_preimage> <witness_script>
131+
Some(Self::AcceptedPreimage)
132+
} else {
133+
None
134+
}
75135
} else {
76136
None
77137
}
@@ -285,7 +345,7 @@ pub fn derive_public_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1<T>, per_com
285345

286346
/// Derives a per-commitment-transaction revocation key from its constituent parts.
287347
///
288-
/// Only the cheating participant owns a valid witness to propagate a revoked
348+
/// Only the cheating participant owns a valid witness to propagate a revoked
289349
/// commitment transaction, thus per_commitment_secret always come from cheater
290350
/// and revocation_base_secret always come from punisher, which is the broadcaster
291351
/// of the transaction spending with this key knowledge.
@@ -320,7 +380,7 @@ pub fn derive_private_revocation_key<T: secp256k1::Signing>(secp_ctx: &Secp256k1
320380
/// the public equivalend of derive_private_revocation_key - using only public keys to derive a
321381
/// public key instead of private keys.
322382
///
323-
/// Only the cheating participant owns a valid witness to propagate a revoked
383+
/// Only the cheating participant owns a valid witness to propagate a revoked
324384
/// commitment transaction, thus per_commitment_point always come from cheater
325385
/// and revocation_base_point always come from punisher, which is the broadcaster
326386
/// of the transaction spending with this key knowledge.
@@ -616,12 +676,17 @@ pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, conte
616676
} else {
617677
htlc_success_tx_weight(opt_anchors)
618678
};
619-
let total_fee = feerate_per_kw as u64 * weight / 1000;
679+
let output_value = if opt_anchors {
680+
htlc.amount_msat / 1000
681+
} else {
682+
let total_fee = feerate_per_kw as u64 * weight / 1000;
683+
htlc.amount_msat / 1000 - total_fee
684+
};
620685

621686
let mut txouts: Vec<TxOut> = Vec::new();
622687
txouts.push(TxOut {
623688
script_pubkey: get_revokeable_redeemscript(revocation_key, contest_delay, broadcaster_delayed_payment_key).to_v0_p2wsh(),
624-
value: htlc.amount_msat / 1000 - total_fee //TODO: BOLT 3 does not specify if we should add amount_msat before dividing or if we should divide by 1000 before subtracting (as we do here)
689+
value: output_value,
625690
});
626691

627692
Transaction {
@@ -680,7 +745,8 @@ pub struct ChannelTransactionParameters {
680745
pub counterparty_parameters: Option<CounterpartyChannelTransactionParameters>,
681746
/// The late-bound funding outpoint
682747
pub funding_outpoint: Option<chain::transaction::OutPoint>,
683-
/// Are anchors used for this channel. Boolean is serialization backwards-compatible
748+
/// Are anchors (zero fee HTLC transaction variant) used for this channel. Boolean is
749+
/// serialization backwards-compatible.
684750
pub opt_anchors: Option<()>
685751
}
686752

0 commit comments

Comments
 (0)