Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 29 additions & 19 deletions lightning/src/ln/chan_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use bitcoin::blockdata::script::{Script,Builder};
use bitcoin::blockdata::opcodes;
use bitcoin::blockdata::transaction::{TxIn,TxOut,OutPoint,Transaction, EcdsaSighashType};
use bitcoin::util::sighash;
use bitcoin::util::address::Payload;

use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
Expand All @@ -25,11 +26,11 @@ use crate::ln::msgs::DecodeError;
use crate::util::ser::{Readable, Writeable, Writer};
use crate::util::{byte_utils, transaction_utils};

use bitcoin::hash_types::WPubkeyHash;
use bitcoin::secp256k1::{SecretKey, PublicKey, Scalar};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Message};
use bitcoin::secp256k1::Error as SecpError;
use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
use bitcoin::PublicKey as BitcoinPublicKey;

use crate::io;
use crate::prelude::*;
Expand All @@ -41,13 +42,20 @@ use core::ops::Deref;
use crate::chain;
use crate::util::crypto::sign;

pub(crate) const MAX_HTLCS: u16 = 483;
pub(crate) const OFFERED_HTLC_SCRIPT_WEIGHT: usize = 133;
pub(crate) const OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS: usize = 136;
// The weight of `accepted_htlc_script` can vary in function of its CLTV argument value. We define a
// range that encompasses both its non-anchors and anchors variants.
/// Maximum number of one-way in-flight HTLC (protocol-level value).
pub const MAX_HTLCS: u16 = 483;
/// The weight of a BIP141 witnessScript for a BOLT3's "offered HTLC output" on a commitment transaction, non-anchor variant.
pub const OFFERED_HTLC_SCRIPT_WEIGHT: usize = 133;
/// The weight of a BIP141 witnessScript for a BOLT3's "offered HTLC output" on a commitment transaction, anchor variant.
pub const OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS: usize = 136;

/// The weight of a BIP141 witnessScript for a BOLT3's "received HTLC output" can vary in function of its CLTV argument value.
/// We define a range that encompasses both its non-anchors and anchors variants.
pub(crate) const MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 136;
pub(crate) const MAX_ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 143;
/// The weight of a BIP141 witnessScript for a BOLT3's "received HTLC output" can vary in function of its CLTV argument value.
/// We define a range that encompasses both its non-anchors and anchors variants.
/// This is the maximum post-anchor value.
pub const MAX_ACCEPTED_HTLC_SCRIPT_WEIGHT: usize = 143;

/// Gets the weight for an HTLC-Success transaction.
#[inline]
Expand All @@ -65,18 +73,24 @@ pub fn htlc_timeout_tx_weight(opt_anchors: bool) -> u64 {
if opt_anchors { HTLC_TIMEOUT_ANCHOR_TX_WEIGHT } else { HTLC_TIMEOUT_TX_WEIGHT }
}

/// Describes the type of HTLC claim as determined by analyzing the witness.
#[derive(PartialEq, Eq)]
pub(crate) enum HTLCClaim {
pub enum HTLCClaim {
/// Claims an offered output on a commitment transaction through the timeout path.
OfferedTimeout,
/// Claims an offered output on a commitment transaction through the success path.
OfferedPreimage,
/// Claims an accepted output on a commitment transaction through the timeout path.
AcceptedTimeout,
/// Claims an accepted output on a commitment transaction through the success path.
AcceptedPreimage,
/// Claims an offered/accepted output on a commitment transaction through the revocation path.
Revocation,
}

impl HTLCClaim {
/// Check if a given input witness attempts to claim a HTLC.
pub(crate) fn from_witness(witness: &Witness) -> Option<Self> {
pub fn from_witness(witness: &Witness) -> Option<Self> {
debug_assert_eq!(OFFERED_HTLC_SCRIPT_WEIGHT_ANCHORS, MIN_ACCEPTED_HTLC_SCRIPT_WEIGHT);
if witness.len() < 2 {
return None;
Expand Down Expand Up @@ -700,7 +714,7 @@ pub fn build_htlc_transaction(commitment_txid: &Txid, feerate_per_kw: u32, conte

/// Gets the witnessScript for the to_remote output when anchors are enabled.
#[inline]
pub(crate) fn get_to_countersignatory_with_anchors_redeemscript(payment_point: &PublicKey) -> Script {
pub fn get_to_countersignatory_with_anchors_redeemscript(payment_point: &PublicKey) -> Script {
Builder::new()
.push_slice(&payment_point.serialize()[..])
.push_opcode(opcodes::all::OP_CHECKSIGVERIFY)
Expand Down Expand Up @@ -1266,7 +1280,7 @@ impl CommitmentTransaction {
let script = if opt_anchors {
get_to_countersignatory_with_anchors_redeemscript(&countersignatory_pubkeys.payment_point).to_v0_p2wsh()
} else {
get_p2wpkh_redeemscript(&countersignatory_pubkeys.payment_point)
Payload::p2wpkh(&BitcoinPublicKey::new(countersignatory_pubkeys.payment_point)).unwrap().script_pubkey()
};
txouts.push((
TxOut {
Expand Down Expand Up @@ -1572,25 +1586,21 @@ pub fn get_commitment_transaction_number_obscure_factor(
| ((res[31] as u64) << 0 * 8)
}

fn get_p2wpkh_redeemscript(key: &PublicKey) -> Script {
Builder::new().push_opcode(opcodes::all::OP_PUSHBYTES_0)
.push_slice(&WPubkeyHash::hash(&key.serialize())[..])
.into_script()
}

#[cfg(test)]
mod tests {
use super::CounterpartyCommitmentSecrets;
use crate::{hex, chain};
use crate::prelude::*;
use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, get_p2wpkh_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
use crate::util::test_utils;
use crate::chain::keysinterface::{KeysInterface, BaseSign};
use bitcoin::{Network, Txid};
use bitcoin::hashes::Hash;
use crate::ln::PaymentHash;
use bitcoin::hashes::hex::ToHex;
use bitcoin::util::address::Payload;
use bitcoin::PublicKey as BitcoinPublicKey;

#[test]
fn test_anchors() {
Expand Down Expand Up @@ -1629,7 +1639,7 @@ mod tests {
&mut htlcs_with_aux, &channel_parameters.as_holder_broadcastable()
);
assert_eq!(tx.built.transaction.output.len(), 2);
assert_eq!(tx.built.transaction.output[1].script_pubkey, get_p2wpkh_redeemscript(&counterparty_pubkeys.payment_point));
assert_eq!(tx.built.transaction.output[1].script_pubkey, Payload::p2wpkh(&BitcoinPublicKey::new(counterparty_pubkeys.payment_point)).unwrap().script_pubkey());

// Generate broadcaster and counterparty outputs as well as two anchors
let tx = CommitmentTransaction::new_with_auxiliary_htlc_data(
Expand Down