Skip to content

Commit 0eb0621

Browse files
author
Antoine Riard
committed
Bound incoming HTLC witnessScript to min/max limits
Fix a crash where previously we weren't able to detect any accepted HTLC if its witness-encoded cltv expiry was different from expected ACCEPTED_HTLC_SCRIPT_WEIGHT. This should work for any cltv expiry included between 0 and 16777216 on mainnet, testnet and regtest.
1 parent f8b06ec commit 0eb0621

File tree

5 files changed

+31
-15
lines changed

5 files changed

+31
-15
lines changed

lightning/src/ln/chan_utils.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,25 @@ use secp256k1;
2525
pub(super) const HTLC_SUCCESS_TX_WEIGHT: u64 = 703;
2626
pub(super) const HTLC_TIMEOUT_TX_WEIGHT: u64 = 663;
2727

28+
#[derive(PartialEq)]
29+
pub(super) enum HTLCType {
30+
AcceptedHTLC,
31+
OfferedHTLC,
32+
NoneHTLC,
33+
}
34+
35+
impl HTLCType {
36+
pub(super) fn weight_to_htlctype(witness_script_len: usize) -> HTLCType {
37+
if witness_script_len == 133 {
38+
HTLCType::OfferedHTLC
39+
} else if witness_script_len >= 136 && witness_script_len <= 139 {
40+
HTLCType::AcceptedHTLC
41+
} else {
42+
HTLCType::NoneHTLC
43+
}
44+
}
45+
}
46+
2847
// Various functions for key derivation and transaction creation for use within channels. Primarily
2948
// used in Channel and ChannelMonitor.
3049

lightning/src/ln/channel.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,6 @@ const B_OUTPUT_PLUS_SPENDING_INPUT_WEIGHT: u64 = 104; // prevout: 40, nSequence:
367367
/// it's 2^24.
368368
pub const MAX_FUNDING_SATOSHIS: u64 = (1 << 24);
369369

370-
#[cfg(test)]
371-
pub const ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 138; //Here we have a diff due to HTLC CLTV expiry being < 2^15 in test
372-
#[cfg(not(test))]
373-
pub const ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 139;
374-
pub const OFFERED_HTLC_SCRIPT_WEIGHT: usize = 133;
375-
376370
/// Used to return a simple Error back to ChannelManager. Will get converted to a
377371
/// msgs::ErrorAction::SendErrorMessage or msgs::ErrorAction::IgnoreError as appropriate with our
378372
/// channel_id in ChannelManager.

lightning/src/ln/channelmonitor.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,8 @@ use secp256k1;
3131

3232
use ln::msgs::DecodeError;
3333
use ln::chan_utils;
34-
use ln::chan_utils::{HTLCOutputInCommitment, LocalCommitmentTransaction};
34+
use ln::chan_utils::{HTLCOutputInCommitment, LocalCommitmentTransaction, HTLCType};
3535
use ln::channelmanager::{HTLCSource, PaymentPreimage, PaymentHash};
36-
use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT};
3736
use chain::chaininterface::{ChainListener, ChainWatchInterface, BroadcasterInterface, FeeEstimator, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT};
3837
use chain::transaction::OutPoint;
3938
use chain::keysinterface::SpendableOutputDescriptor;
@@ -2676,10 +2675,10 @@ impl ChannelMonitor {
26762675

26772676
'outer_loop: for input in &tx.input {
26782677
let mut payment_data = None;
2679-
let revocation_sig_claim = (input.witness.len() == 3 && input.witness[2].len() == OFFERED_HTLC_SCRIPT_WEIGHT && input.witness[1].len() == 33)
2680-
|| (input.witness.len() == 3 && input.witness[2].len() == ACCEPTED_HTLC_SCRIPT_WEIGHT && input.witness[1].len() == 33);
2681-
let accepted_preimage_claim = input.witness.len() == 5 && input.witness[4].len() == ACCEPTED_HTLC_SCRIPT_WEIGHT;
2682-
let offered_preimage_claim = input.witness.len() == 3 && input.witness[2].len() == OFFERED_HTLC_SCRIPT_WEIGHT;
2678+
let revocation_sig_claim = (input.witness.len() == 3 && HTLCType::weight_to_htlctype(input.witness[2].len()) == HTLCType::OfferedHTLC && input.witness[1].len() == 33)
2679+
|| (input.witness.len() == 3 && HTLCType::weight_to_htlctype(input.witness[2].len()) == HTLCType::AcceptedHTLC && input.witness[1].len() == 33);
2680+
let accepted_preimage_claim = input.witness.len() == 5 && HTLCType::weight_to_htlctype(input.witness[4].len()) == HTLCType::AcceptedHTLC;
2681+
let offered_preimage_claim = input.witness.len() == 3 && HTLCType::weight_to_htlctype(input.witness[2].len()) == HTLCType::OfferedHTLC;
26832682

26842683
macro_rules! log_claim {
26852684
($tx_info: expr, $local_tx: expr, $htlc: expr, $source_avail: expr) => {
@@ -2870,7 +2869,8 @@ impl ChannelMonitor {
28702869
for per_outp_material in cached_claim_datas.per_input_material.values() {
28712870
match per_outp_material {
28722871
&InputMaterial::Revoked { ref script, ref is_htlc, ref amount, .. } => {
2873-
inputs_witnesses_weight += Self::get_witnesses_weight(if !is_htlc { &[InputDescriptors::RevokedOutput] } else if script.len() == OFFERED_HTLC_SCRIPT_WEIGHT { &[InputDescriptors::RevokedOfferedHTLC] } else if script.len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { &[InputDescriptors::RevokedReceivedHTLC] } else { &[] });
2872+
log_trace!(self, "Is HLTC ? {}", is_htlc);
2873+
inputs_witnesses_weight += Self::get_witnesses_weight(if !is_htlc { &[InputDescriptors::RevokedOutput] } else if HTLCType::weight_to_htlctype(script.len()) == HTLCType::OfferedHTLC { &[InputDescriptors::RevokedOfferedHTLC] } else if HTLCType::weight_to_htlctype(script.len()) == HTLCType::AcceptedHTLC { &[InputDescriptors::RevokedReceivedHTLC] } else { unreachable!() });
28742874
amt += *amount;
28752875
},
28762876
&InputMaterial::RemoteHTLC { ref preimage, ref amount, .. } => {
@@ -2910,7 +2910,7 @@ impl ChannelMonitor {
29102910
bumped_tx.input[i].witness.push(vec!(1));
29112911
}
29122912
bumped_tx.input[i].witness.push(script.clone().into_bytes());
2913-
log_trace!(self, "Going to broadcast bumped Penalty Transaction {} claiming revoked {} output {} from {} with new feerate {}", bumped_tx.txid(), if !is_htlc { "to_local" } else if script.len() == OFFERED_HTLC_SCRIPT_WEIGHT { "offered" } else if script.len() == ACCEPTED_HTLC_SCRIPT_WEIGHT { "received" } else { "" }, outp.vout, outp.txid, new_feerate);
2913+
log_trace!(self, "Going to broadcast bumped Penalty Transaction {} claiming revoked {} output {} from {} with new feerate {}", bumped_tx.txid(), if !is_htlc { "to_local" } else if HTLCType::weight_to_htlctype(script.len()) == HTLCType::OfferedHTLC { "offered" } else if HTLCType::weight_to_htlctype(script.len()) == HTLCType::AcceptedHTLC { "received" } else { "" }, outp.vout, outp.txid, new_feerate);
29142914
},
29152915
&InputMaterial::RemoteHTLC { ref script, ref key, ref preimage, ref amount, ref locktime } => {
29162916
if !preimage.is_some() { bumped_tx.lock_time = *locktime };

lightning/src/ln/functional_test_utils.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,9 @@ pub fn create_network(node_count: usize, node_config: &[Option<UserConfig>]) ->
875875
nodes
876876
}
877877

878+
pub const ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 138; //Here we have a diff due to HTLC CLTV expiry being < 2^15 in test
879+
pub const OFFERED_HTLC_SCRIPT_WEIGHT: usize = 133;
880+
878881
#[derive(PartialEq)]
879882
pub enum HTLCType { NONE, TIMEOUT, SUCCESS }
880883
/// Tests that the given node has broadcast transactions for the given Channel

lightning/src/ln/functional_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use chain::keysinterface::{KeysInterface, SpendableOutputDescriptor};
88
use ln::channel::{COMMITMENT_TX_BASE_WEIGHT, COMMITMENT_TX_WEIGHT_PER_HTLC};
99
use ln::channelmanager::{ChannelManager,ChannelManagerReadArgs,HTLCForwardInfo,RAACommitmentOrder, PaymentPreimage, PaymentHash, BREAKDOWN_TIMEOUT};
1010
use ln::channelmonitor::{ChannelMonitor, CLTV_CLAIM_BUFFER, LATENCY_GRACE_PERIOD_BLOCKS, ManyChannelMonitor, ANTI_REORG_DELAY};
11-
use ln::channel::{ACCEPTED_HTLC_SCRIPT_WEIGHT, OFFERED_HTLC_SCRIPT_WEIGHT, Channel, ChannelError};
11+
use ln::channel::{Channel, ChannelError};
1212
use ln::onion_utils;
1313
use ln::router::{Route, RouteHop};
1414
use ln::msgs;

0 commit comments

Comments
 (0)