Skip to content
Merged
Show file tree
Hide file tree
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
20 changes: 20 additions & 0 deletions lightning/src/chain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
use bitcoin::block::{Block, Header};
use bitcoin::constants::genesis_block;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::network::Network;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::secp256k1::PublicKey;
Expand All @@ -21,6 +23,7 @@ use crate::chain::transaction::{OutPoint, TransactionData};
use crate::impl_writeable_tlv_based;
use crate::ln::types::ChannelId;
use crate::sign::ecdsa::EcdsaChannelSigner;
use crate::sign::HTLCDescriptor;

#[allow(unused_imports)]
use crate::prelude::*;
Expand Down Expand Up @@ -442,3 +445,20 @@ where
/// This is not exported to bindings users as we just use [u8; 32] directly.
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct ClaimId(pub [u8; 32]);

impl ClaimId {
pub(crate) fn from_htlcs(htlcs: &[HTLCDescriptor]) -> ClaimId {
let mut engine = Sha256::engine();
for htlc in htlcs {
engine.input(&htlc.commitment_txid.to_byte_array());
engine.input(&htlc.htlc.transaction_output_index.unwrap().to_be_bytes());
}
ClaimId(Sha256::from_engine(engine).to_byte_array())
}
pub(crate) fn step_with_bytes(&self, bytes: &[u8]) -> ClaimId {
let mut engine = Sha256::engine();
engine.input(&self.0);
engine.input(bytes);
ClaimId(Sha256::from_engine(engine).to_byte_array())
}
}
10 changes: 2 additions & 8 deletions lightning/src/chain/onchaintx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@

use bitcoin::amount::Amount;
use bitcoin::hash_types::{BlockHash, Txid};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::Hash;
use bitcoin::locktime::absolute::LockTime;
use bitcoin::script::{Script, ScriptBuf};
use bitcoin::secp256k1;
Expand Down Expand Up @@ -882,12 +881,7 @@ impl<ChannelSigner: EcdsaChannelSigner> OnchainTxHandler<ChannelSigner> {
// claim, which will always be unique per request. Once a claim ID
// is generated, it is assigned and remains unchanged, even if the
// underlying set of HTLCs changes.
let mut engine = Sha256::engine();
for htlc in htlcs {
engine.input(&htlc.commitment_txid.to_byte_array());
engine.input(&htlc.htlc.transaction_output_index.unwrap().to_be_bytes());
}
ClaimId(Sha256::from_engine(engine).to_byte_array())
ClaimId::from_htlcs(htlcs)
},
};
debug_assert!(self.pending_claim_requests.get(&claim_id).is_none());
Expand Down
476 changes: 324 additions & 152 deletions lightning/src/events/bump_transaction/mod.rs

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions lightning/src/events/bump_transaction/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,14 @@ where
{
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32,
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()> {
let mut fut = self.wallet.select_confirmed_utxos(
claim_id,
must_spend,
must_pay_to,
target_feerate_sat_per_1000_weight,
max_tx_weight,
);
let mut waker = dummy_waker();
let mut ctx = task::Context::from_waker(&mut waker);
Expand Down Expand Up @@ -140,7 +141,7 @@ pub trait CoinSelectionSourceSync {
/// A synchronous version of [`CoinSelectionSource::select_confirmed_utxos`].
fn select_confirmed_utxos(
&self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &[TxOut],
target_feerate_sat_per_1000_weight: u32,
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> Result<CoinSelection, ()>;

/// A synchronous version of [`CoinSelectionSource::sign_psbt`].
Expand Down Expand Up @@ -169,13 +170,14 @@ where
{
fn select_confirmed_utxos<'a>(
&'a self, claim_id: ClaimId, must_spend: Vec<Input>, must_pay_to: &'a [TxOut],
target_feerate_sat_per_1000_weight: u32,
target_feerate_sat_per_1000_weight: u32, max_tx_weight: u64,
) -> AsyncResult<'a, CoinSelection> {
let coins = self.0.select_confirmed_utxos(
claim_id,
must_spend,
must_pay_to,
target_feerate_sat_per_1000_weight,
max_tx_weight,
);
Box::pin(async move { coins })
}
Expand Down
7 changes: 5 additions & 2 deletions lightning/src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1604,15 +1604,18 @@ pub enum Event {
/// Indicates that a transaction originating from LDK needs to have its fee bumped. This event
/// requires confirmed external funds to be readily available to spend.
///
/// LDK does not currently generate this event unless the
/// [`ChannelHandshakeConfig::negotiate_anchors_zero_fee_htlc_tx`] config flag is set to true.
/// LDK does not currently generate this event unless either the
/// [`ChannelHandshakeConfig::negotiate_anchors_zero_fee_htlc_tx`] or the
/// [`ChannelHandshakeConfig::negotiate_anchor_zero_fee_commitments`] config flags are set to
/// true.
/// It is limited to the scope of channels with anchor outputs.
///
/// # Failure Behavior and Persistence
/// This event will eventually be replayed after failures-to-handle (i.e., the event handler
/// returning `Err(ReplayEvent ())`), but will only be regenerated as needed after restarts.
///
/// [`ChannelHandshakeConfig::negotiate_anchors_zero_fee_htlc_tx`]: crate::util::config::ChannelHandshakeConfig::negotiate_anchors_zero_fee_htlc_tx
/// [`ChannelHandshakeConfig::negotiate_anchor_zero_fee_commitments`]: crate::util::config::ChannelHandshakeConfig::negotiate_anchor_zero_fee_commitments
BumpTransaction(BumpTransactionEvent),
/// We received an onion message that is intended to be forwarded to a peer
/// that is currently offline. This event will only be generated if the
Expand Down
44 changes: 42 additions & 2 deletions lightning/src/ln/chan_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! largely of interest for those implementing the traits on [`crate::sign`] by hand.

use bitcoin::amount::Amount;
use bitcoin::constants::WITNESS_SCALE_FACTOR;
use bitcoin::opcodes;
use bitcoin::script::{Builder, Script, ScriptBuf};
use bitcoin::sighash;
Expand Down Expand Up @@ -89,12 +90,18 @@ pub const ANCHOR_INPUT_WITNESS_WEIGHT: u64 = 114;
#[cfg(not(feature = "grind_signatures"))]
pub const ANCHOR_INPUT_WITNESS_WEIGHT: u64 = 115;

/// The weight of a P2A anchor witness.
pub const P2A_ANCHOR_INPUT_WITNESS_WEIGHT: u64 = 1;
/// The weight of an empty witness; used to spend a P2A output.
pub const EMPTY_WITNESS_WEIGHT: u64 = 1;

/// The maximum value of a P2A anchor.
pub const P2A_MAX_VALUE: u64 = 240;

/// The maximum weight of a TRUC transaction, see BIP431.
pub const TRUC_MAX_WEIGHT: u64 = 10_000 * WITNESS_SCALE_FACTOR as u64;

/// The maximum weight of a TRUC transaction with an unconfirmed TRUC ancestor, see BIP431.
pub const TRUC_CHILD_MAX_WEIGHT: u64 = 1000 * WITNESS_SCALE_FACTOR as u64;

/// The upper bound weight of an HTLC timeout input from a commitment transaction with keyed anchor outputs.
pub const HTLC_TIMEOUT_INPUT_KEYED_ANCHOR_WITNESS_WEIGHT: u64 = 288;
/// The upper bound weight of an HTLC timeout input from a commitment transaction with a p2a anchor output.
Expand Down Expand Up @@ -125,6 +132,15 @@ pub const FUNDING_TRANSACTION_WITNESS_WEIGHT: u64 = 1 + // number_of_witness_ele
1 + // witness_script_length
MULTISIG_SCRIPT_SIZE;

pub(crate) const BASE_TX_SIZE: u64 = 4 /* version */ + 1 /* input count */ + 1 /* output count */ + 4 /* locktime */;
pub(crate) const SEGWIT_MARKER_FLAG_WEIGHT: u64 = 2;
pub(crate) const EMPTY_SCRIPT_SIG_WEIGHT: u64 =
1 /* empty script_sig */ * WITNESS_SCALE_FACTOR as u64;
pub(crate) const BASE_INPUT_SIZE: u64 = 32 /* txid */ + 4 /* vout */ + 4 /* sequence */;
pub(crate) const BASE_INPUT_WEIGHT: u64 = BASE_INPUT_SIZE * WITNESS_SCALE_FACTOR as u64;
pub(crate) const P2WSH_TXOUT_WEIGHT: u64 =
(8 /* value */ + 1 /* var_int */ + 34/* p2wsh spk */) * WITNESS_SCALE_FACTOR as u64;

/// Gets the weight for an HTLC-Success transaction.
#[inline]
#[rustfmt::skip]
Expand All @@ -134,6 +150,18 @@ pub fn htlc_success_tx_weight(channel_type_features: &ChannelTypeFeatures) -> u6
if channel_type_features.supports_anchors_zero_fee_htlc_tx() { HTLC_SUCCESS_ANCHOR_TX_WEIGHT } else { HTLC_SUCCESS_TX_WEIGHT }
}

/// Gets the weight of a single input-output pair in externally funded HTLC-success transactions
pub fn aggregated_htlc_success_input_output_pair_weight(
channel_type_features: &ChannelTypeFeatures,
) -> u64 {
let satisfaction_weight = if channel_type_features.supports_anchors_zero_fee_htlc_tx() {
EMPTY_SCRIPT_SIG_WEIGHT + HTLC_SUCCESS_INPUT_KEYED_ANCHOR_WITNESS_WEIGHT
} else {
EMPTY_SCRIPT_SIG_WEIGHT + HTLC_SUCCESS_INPUT_P2A_ANCHOR_WITNESS_WEIGHT
};
BASE_INPUT_WEIGHT + P2WSH_TXOUT_WEIGHT + satisfaction_weight
}

/// Gets the weight for an HTLC-Timeout transaction.
#[inline]
#[rustfmt::skip]
Expand All @@ -143,6 +171,18 @@ pub fn htlc_timeout_tx_weight(channel_type_features: &ChannelTypeFeatures) -> u6
if channel_type_features.supports_anchors_zero_fee_htlc_tx() { HTLC_TIMEOUT_ANCHOR_TX_WEIGHT } else { HTLC_TIMEOUT_TX_WEIGHT }
}

/// Gets the weight of a single input-output pair in externally funded HTLC-timeout transactions
pub fn aggregated_htlc_timeout_input_output_pair_weight(
channel_type_features: &ChannelTypeFeatures,
) -> u64 {
let satisfaction_weight = if channel_type_features.supports_anchors_zero_fee_htlc_tx() {
EMPTY_SCRIPT_SIG_WEIGHT + HTLC_TIMEOUT_INPUT_KEYED_ANCHOR_WITNESS_WEIGHT
} else {
EMPTY_SCRIPT_SIG_WEIGHT + HTLC_TIMEOUT_INPUT_P2A_ANCHOR_WITNESS_WEIGHT
};
BASE_INPUT_WEIGHT + P2WSH_TXOUT_WEIGHT + satisfaction_weight
}

/// Describes the type of HTLC claim as determined by analyzing the witness.
#[derive(PartialEq, Eq)]
pub enum HTLCClaim {
Expand Down
3 changes: 1 addition & 2 deletions lightning/src/ln/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,14 @@ use crate::chain::channelmonitor::{
};
use crate::chain::transaction::{OutPoint, TransactionData};
use crate::chain::BestBlock;
use crate::events::bump_transaction::{BASE_INPUT_WEIGHT, EMPTY_SCRIPT_SIG_WEIGHT};
use crate::events::{ClosureReason, FundingInfo};
use crate::ln::chan_utils;
use crate::ln::chan_utils::{
get_commitment_transaction_number_obscure_factor, max_htlcs, second_stage_tx_fees_sat,
selected_commitment_sat_per_1000_weight, ChannelPublicKeys, ChannelTransactionParameters,
ClosingTransaction, CommitmentTransaction, CounterpartyChannelTransactionParameters,
CounterpartyCommitmentSecrets, HTLCOutputInCommitment, HolderCommitmentTransaction,
FUNDING_TRANSACTION_WITNESS_WEIGHT,
BASE_INPUT_WEIGHT, EMPTY_SCRIPT_SIG_WEIGHT, FUNDING_TRANSACTION_WITNESS_WEIGHT,
};
use crate::ln::channel_state::{
ChannelShutdownState, CounterpartyForwardingInfo, InboundHTLCDetails, InboundHTLCStateDetails,
Expand Down
24 changes: 19 additions & 5 deletions lightning/src/ln/functional_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ use crate::events::{
ClaimedHTLC, ClosureReason, Event, HTLCHandlingFailureType, PaidBolt12Invoice, PathFailure,
PaymentFailureReason, PaymentPurpose,
};
use crate::ln::chan_utils::{commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC};
use crate::ln::chan_utils::{
commitment_tx_base_weight, COMMITMENT_TX_WEIGHT_PER_HTLC, TRUC_MAX_WEIGHT,
};
use crate::ln::channelmanager::{
AChannelManager, ChainParameters, ChannelManager, ChannelManagerReadArgs, PaymentId,
RAACommitmentOrder, RecipientOnionFields, MIN_CLTV_EXPIRY_DELTA,
Expand Down Expand Up @@ -58,6 +60,7 @@ use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::Hash as _;
use bitcoin::locktime::absolute::{LockTime, LOCK_TIME_THRESHOLD};
use bitcoin::network::Network;
use bitcoin::policy::MAX_STANDARD_TX_WEIGHT;
use bitcoin::pow::CompactTarget;
use bitcoin::script::ScriptBuf;
use bitcoin::secp256k1::{PublicKey, SecretKey};
Expand Down Expand Up @@ -400,12 +403,18 @@ fn do_connect_block_without_consistency_checks<'a, 'b, 'c, 'd>(
}

pub fn provide_anchor_reserves<'a, 'b, 'c>(nodes: &[Node<'a, 'b, 'c>]) -> Transaction {
provide_anchor_utxo_reserves(nodes, 1, Amount::ONE_BTC)
}

pub fn provide_anchor_utxo_reserves<'a, 'b, 'c>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provide_anchor_reserves should call this now

nodes: &[Node<'a, 'b, 'c>], utxos: usize, amount: Amount,
) -> Transaction {
let mut output = Vec::with_capacity(nodes.len());
for node in nodes {
output.push(TxOut {
value: Amount::ONE_BTC,
script_pubkey: node.wallet_source.get_change_script().unwrap(),
});
let script_pubkey = node.wallet_source.get_change_script().unwrap();
for _ in 0..utxos {
output.push(TxOut { value: amount, script_pubkey: script_pubkey.clone() });
}
}
let tx = Transaction {
version: TxVersion::TWO,
Expand Down Expand Up @@ -1941,6 +1950,11 @@ pub fn update_nodes_with_chan_announce<'a, 'b, 'c, 'd>(
pub fn do_check_spends<F: Fn(&bitcoin::transaction::OutPoint) -> Option<TxOut>>(
tx: &Transaction, get_output: F,
) {
if tx.version == TxVersion::non_standard(3) {
assert!(tx.weight().to_wu() <= TRUC_MAX_WEIGHT);
} else {
assert!(tx.weight().to_wu() <= MAX_STANDARD_TX_WEIGHT as u64);
}
let mut p2a_output_below_dust = false;
let mut has_p2a_output = false;
for outp in tx.output.iter() {
Expand Down
3 changes: 2 additions & 1 deletion lightning/src/ln/funding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
use bitcoin::{Amount, ScriptBuf, SignedAmount, TxOut};
use bitcoin::{Script, Sequence, Transaction, Weight};

use crate::events::bump_transaction::{Utxo, EMPTY_SCRIPT_SIG_WEIGHT};
use crate::events::bump_transaction::Utxo;
use crate::ln::chan_utils::EMPTY_SCRIPT_SIG_WEIGHT;
use crate::prelude::Vec;
use crate::sign::{P2TR_KEY_PATH_WITNESS_WEIGHT, P2WPKH_WITNESS_WEIGHT};

Expand Down
5 changes: 3 additions & 2 deletions lightning/src/ln/interactivetxs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ use bitcoin::{
};

use crate::chain::chaininterface::fee_for_weight;
use crate::events::bump_transaction::{BASE_INPUT_WEIGHT, EMPTY_SCRIPT_SIG_WEIGHT};
use crate::ln::chan_utils::FUNDING_TRANSACTION_WITNESS_WEIGHT;
use crate::ln::chan_utils::{
BASE_INPUT_WEIGHT, EMPTY_SCRIPT_SIG_WEIGHT, FUNDING_TRANSACTION_WITNESS_WEIGHT,
};
use crate::ln::channel::{FundingNegotiationContext, TOTAL_BITCOIN_SUPPLY_SATOSHIS};
use crate::ln::funding::FundingTxInput;
use crate::ln::msgs;
Expand Down
Loading
Loading