cargo check --no-default-features --features=no-std --release
cargo check --no-default-features --features=futures --release
cargo doc --release
- RUSTDOCFLAGS="--cfg=anchors" cargo doc --release
- name: Run cargo check for Taproot build.
run: |
cargo check --release
cargo check --no-default-features --features=futures --release
cargo doc --release
env:
- RUSTFLAGS: '--cfg=anchors --cfg=taproot'
- RUSTDOCFLAGS: '--cfg=anchors --cfg=taproot'
+ RUSTFLAGS: '--cfg=taproot'
+ RUSTDOCFLAGS: '--cfg=taproot'
fuzz:
runs-on: ubuntu-latest
popd
fi
-echo -e "\n\nTest anchors builds"
-pushd lightning
-RUSTFLAGS="$RUSTFLAGS --cfg=anchors" cargo test --verbose --color always -p lightning
echo -e "\n\nTest Taproot builds"
-RUSTFLAGS="$RUSTFLAGS --cfg=anchors --cfg=taproot" cargo test --verbose --color always -p lightning
+pushd lightning
+RUSTFLAGS="$RUSTFLAGS --cfg=taproot" cargo test --verbose --color always -p lightning
popd
L::Target: Logger,
P::Target: Persist<ChannelSigner>,
{
- #[cfg(not(anchors))]
- /// Processes [`SpendableOutputs`] events produced from each [`ChannelMonitor`] upon maturity.
- ///
- /// An [`EventHandler`] may safely call back to the provider, though this shouldn't be needed in
- /// order to handle these events.
- ///
- /// [`SpendableOutputs`]: events::Event::SpendableOutputs
- fn process_pending_events<H: Deref>(&self, handler: H) where H::Target: EventHandler {
- let mut pending_events = Vec::new();
- for monitor_state in self.monitors.read().unwrap().values() {
- pending_events.append(&mut monitor_state.monitor.get_and_clear_pending_events());
- }
- for event in pending_events {
- handler.handle_event(event);
- }
- }
- #[cfg(anchors)]
/// Processes [`SpendableOutputs`] events produced from each [`ChannelMonitor`] upon maturity.
///
/// For channels featuring anchor outputs, this method will also process [`BumpTransaction`]
/// events produced from each [`ChannelMonitor`] while there is a balance to claim onchain
/// within each channel. As the confirmation of a commitment transaction may be critical to the
- /// safety of funds, this method must be invoked frequently, ideally once for every chain tip
- /// update (block connected or disconnected).
+ /// safety of funds, we recommend invoking this every 30 seconds, or lower if running in an
+ /// environment with spotty connections, like on mobile.
///
/// An [`EventHandler`] may safely call back to the provider, though this shouldn't be needed in
/// order to handle these events.
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
use crate::chain::transaction::{OutPoint, TransactionData};
use crate::sign::{SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
-#[cfg(anchors)]
-use crate::chain::onchaintx::ClaimEvent;
-use crate::chain::onchaintx::OnchainTxHandler;
+use crate::chain::onchaintx::{ClaimEvent, OnchainTxHandler};
use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
use crate::chain::Filter;
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, RequiredWrapper, MaybeReadable, UpgradableRequired, Writer, Writeable, U48};
use crate::util::byte_utils;
use crate::events::Event;
-#[cfg(anchors)]
use crate::events::bump_transaction::{AnchorDescriptor, HTLCDescriptor, BumpTransactionEvent};
use crate::prelude::*;
(14, htlc_outputs, vec_type)
});
-#[cfg(anchors)]
impl HolderSignedTx {
fn non_dust_htlcs(&self) -> Vec<HTLCOutputInCommitment> {
self.htlc_outputs.iter().filter_map(|(htlc, _, _)| {
pub fn get_and_clear_pending_events(&mut self) -> Vec<Event> {
let mut ret = Vec::new();
mem::swap(&mut ret, &mut self.pending_events);
- #[cfg(anchors)]
for (claim_id, claim_event) in self.onchain_tx_handler.get_and_clear_pending_claim_events().drain(..) {
match claim_event {
ClaimEvent::BumpCommitment {
//! OnchainTxHandler objects are fully-part of ChannelMonitor and encapsulates all
//! building, tracking, bumping and notifications functions.
-#[cfg(anchors)]
use bitcoin::PackedLockTime;
use bitcoin::blockdata::transaction::Transaction;
use bitcoin::blockdata::transaction::OutPoint as BitcoinOutPoint;
use bitcoin::blockdata::script::Script;
-use bitcoin::hashes::Hash;
-#[cfg(anchors)]
-use bitcoin::hashes::HashEngine;
-#[cfg(anchors)]
+use bitcoin::hashes::{Hash, HashEngine};
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hash_types::{Txid, BlockHash};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
use crate::sign::{ChannelSigner, EntropySource, SignerProvider};
use crate::ln::msgs::DecodeError;
use crate::ln::PaymentPreimage;
-#[cfg(anchors)]
-use crate::ln::chan_utils::{self, HTLCOutputInCommitment};
-use crate::ln::chan_utils::{ChannelTransactionParameters, HolderCommitmentTransaction};
+use crate::ln::chan_utils::{self, ChannelTransactionParameters, HTLCOutputInCommitment, HolderCommitmentTransaction};
use crate::chain::ClaimId;
-#[cfg(anchors)]
-use crate::chain::chaininterface::ConfirmationTarget;
-use crate::chain::chaininterface::{FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
+use crate::chain::chaininterface::{ConfirmationTarget, FeeEstimator, BroadcasterInterface, LowerBoundedFeeEstimator};
use crate::chain::channelmonitor::{ANTI_REORG_DELAY, CLTV_SHARED_CLAIM_BUFFER};
use crate::sign::WriteableEcdsaChannelSigner;
-#[cfg(anchors)]
-use crate::chain::package::PackageSolvingData;
-use crate::chain::package::PackageTemplate;
+use crate::chain::package::{PackageSolvingData, PackageTemplate};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, ReadableArgs, MaybeReadable, UpgradableRequired, Writer, Writeable, VecWriter};
use core::cmp;
use core::ops::Deref;
use core::mem::replace;
-#[cfg(anchors)]
use core::mem::swap;
use crate::ln::features::ChannelTypeFeatures;
}
}
-#[cfg(anchors)]
/// The claim commonly referred to as the pre-signed second-stage HTLC transaction.
pub(crate) struct ExternalHTLCClaim {
pub(crate) commitment_txid: Txid,
// Represents the different types of claims for which events are yielded externally to satisfy said
// claims.
-#[cfg(anchors)]
pub(crate) enum ClaimEvent {
/// Event yielded to signal that the commitment transaction fee must be bumped to claim any
/// encumbered funds and proceed to HTLC resolution, if any HTLCs exist.
pub(crate) enum OnchainClaim {
/// A finalized transaction pending confirmation spending the output to claim.
Tx(Transaction),
- #[cfg(anchors)]
/// An event yielded externally to signal additional inputs must be added to a transaction
/// pending confirmation spending the output to claim.
Event(ClaimEvent),
// - A channel has been force closed by broadcasting the holder's latest commitment transaction
// - A block being connected/disconnected
// - Learning the preimage for an HTLC we can claim onchain
- #[cfg(anchors)]
pending_claim_events: Vec<(ClaimId, ClaimEvent)>,
// Used to link outpoints claimed in a connected block to a pending claim request. The keys
locktimed_packages,
pending_claim_requests,
onchain_events_awaiting_threshold_conf,
- #[cfg(anchors)]
pending_claim_events: Vec::new(),
secp_ctx,
})
claimable_outpoints: HashMap::new(),
locktimed_packages: BTreeMap::new(),
onchain_events_awaiting_threshold_conf: Vec::new(),
- #[cfg(anchors)]
pending_claim_events: Vec::new(),
secp_ctx,
}
self.holder_commitment.to_broadcaster_value_sat()
}
- #[cfg(anchors)]
pub(crate) fn get_and_clear_pending_claim_events(&mut self) -> Vec<(ClaimId, ClaimEvent)> {
let mut events = Vec::new();
swap(&mut events, &mut self.pending_claim_events);
log_info!(logger, "{} onchain {}", log_start, log_tx!(tx));
broadcaster.broadcast_transactions(&[&tx]);
},
- #[cfg(anchors)]
OnchainClaim::Event(event) => {
let log_start = if bumped_feerate { "Yielding fee-bumped" } else { "Replaying" };
log_info!(logger, "{} onchain event to spend inputs {:?}", log_start,
// didn't receive confirmation of it before, or not enough reorg-safe depth on top of it).
let new_timer = cached_request.get_height_timer(cur_height);
if cached_request.is_malleable() {
- #[cfg(anchors)]
- { // Attributes are not allowed on if expressions on our current MSRV of 1.41.
- if cached_request.requires_external_funding() {
- let target_feerate_sat_per_1000_weight = cached_request.compute_package_feerate(
- fee_estimator, ConfirmationTarget::HighPriority, force_feerate_bump
- );
- if let Some(htlcs) = cached_request.construct_malleable_package_with_external_funding(self) {
- return Some((
- new_timer,
- target_feerate_sat_per_1000_weight as u64,
- OnchainClaim::Event(ClaimEvent::BumpHTLC {
- target_feerate_sat_per_1000_weight,
- htlcs,
- tx_lock_time: PackedLockTime(cached_request.package_locktime(cur_height)),
- }),
- ));
- } else {
- return None;
- }
+ if cached_request.requires_external_funding() {
+ let target_feerate_sat_per_1000_weight = cached_request.compute_package_feerate(
+ fee_estimator, ConfirmationTarget::HighPriority, force_feerate_bump
+ );
+ if let Some(htlcs) = cached_request.construct_malleable_package_with_external_funding(self) {
+ return Some((
+ new_timer,
+ target_feerate_sat_per_1000_weight as u64,
+ OnchainClaim::Event(ClaimEvent::BumpHTLC {
+ target_feerate_sat_per_1000_weight,
+ htlcs,
+ tx_lock_time: PackedLockTime(cached_request.package_locktime(cur_height)),
+ }),
+ ));
+ } else {
+ return None;
}
}
// Untractable packages cannot have their fees bumped through Replace-By-Fee. Some
// packages may support fee bumping through Child-Pays-For-Parent, indicated by those
// which require external funding.
- #[cfg(not(anchors))]
- let inputs = cached_request.inputs();
- #[cfg(anchors)]
let mut inputs = cached_request.inputs();
debug_assert_eq!(inputs.len(), 1);
let tx = match cached_request.finalize_untractable_package(self, logger) {
if !cached_request.requires_external_funding() {
return Some((new_timer, 0, OnchainClaim::Tx(tx)));
}
- #[cfg(anchors)]
return inputs.find_map(|input| match input {
// Commitment inputs with anchors support are the only untractable inputs supported
// thus far that require external funding.
broadcaster.broadcast_transactions(&[&tx]);
ClaimId(tx.txid().into_inner())
},
- #[cfg(anchors)]
OnchainClaim::Event(claim_event) => {
log_info!(logger, "Yielding onchain event to spend inputs {:?}", req.outpoints());
let claim_id = match claim_event {
// input(s) that already have a confirmed spend. If such spend is
// reorged out of the chain, then we'll attempt to re-spend the
// inputs once we see it.
- #[cfg(anchors)] {
- #[cfg(debug_assertions)] {
- let existing = self.pending_claim_events.iter()
- .filter(|entry| entry.0 == *claim_id).count();
- assert!(existing == 0 || existing == 1);
- }
- self.pending_claim_events.retain(|entry| entry.0 != *claim_id);
+ #[cfg(debug_assertions)] {
+ let existing = self.pending_claim_events.iter()
+ .filter(|entry| entry.0 == *claim_id).count();
+ assert!(existing == 0 || existing == 1);
}
+ self.pending_claim_events.retain(|entry| entry.0 != *claim_id);
}
}
break; //No need to iterate further, either tx is our or their
outpoint, log_bytes!(claim_id.0));
self.claimable_outpoints.remove(outpoint);
}
- #[cfg(anchors)] {
- #[cfg(debug_assertions)] {
- let num_existing = self.pending_claim_events.iter()
- .filter(|entry| entry.0 == claim_id).count();
- assert!(num_existing == 0 || num_existing == 1);
- }
- self.pending_claim_events.retain(|(id, _)| *id != claim_id);
+ #[cfg(debug_assertions)] {
+ let num_existing = self.pending_claim_events.iter()
+ .filter(|entry| entry.0 == claim_id).count();
+ assert!(num_existing == 0 || num_existing == 1);
}
+ self.pending_claim_events.retain(|(id, _)| *id != claim_id);
}
},
OnchainEvent::ContentiousOutpoint { package } => {
log_info!(logger, "Broadcasting RBF-bumped onchain {}", log_tx!(bump_tx));
broadcaster.broadcast_transactions(&[&bump_tx]);
},
- #[cfg(anchors)]
OnchainClaim::Event(claim_event) => {
log_info!(logger, "Yielding RBF-bumped onchain event to spend inputs {:?}", request.outpoints());
#[cfg(debug_assertions)] {
log_info!(logger, "Broadcasting onchain {}", log_tx!(bump_tx));
broadcaster.broadcast_transactions(&[&bump_tx]);
},
- #[cfg(anchors)]
OnchainClaim::Event(claim_event) => {
log_info!(logger, "Yielding onchain event after reorg to spend inputs {:?}", request.outpoints());
#[cfg(debug_assertions)] {
htlc_tx
}
- #[cfg(anchors)]
pub(crate) fn generate_external_htlc_claim(
&self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>
) -> Option<ExternalHTLCClaim> {
use crate::ln::msgs::DecodeError;
use crate::chain::chaininterface::{FeeEstimator, ConfirmationTarget, MIN_RELAY_FEE_SAT_PER_1000_WEIGHT};
use crate::sign::WriteableEcdsaChannelSigner;
-#[cfg(anchors)]
-use crate::chain::onchaintx::ExternalHTLCClaim;
-use crate::chain::onchaintx::OnchainTxHandler;
+use crate::chain::onchaintx::{ExternalHTLCClaim, OnchainTxHandler};
use crate::util::logger::Logger;
use crate::util::ser::{Readable, Writer, Writeable, RequiredWrapper};
use crate::io;
use crate::prelude::*;
use core::cmp;
-#[cfg(anchors)]
use core::convert::TryInto;
use core::mem;
use core::ops::Deref;
let output_weight = (8 + 1 + destination_script.len()) * WITNESS_SCALE_FACTOR;
inputs_weight + witnesses_weight + transaction_weight + output_weight
}
- #[cfg(anchors)]
pub(crate) fn construct_malleable_package_with_external_funding<Signer: WriteableEcdsaChannelSigner>(
&self, onchain_handler: &mut OnchainTxHandler<Signer>,
) -> Option<Vec<ExternalHTLCClaim>> {
None
}
- #[cfg(anchors)]
/// Computes a feerate based on the given confirmation target. If a previous feerate was used,
/// the new feerate is below it, and `force_feerate_bump` is set, we'll use a 25% increase of
/// the previous feerate instead of the new feerate.
use crate::chain::chaininterface::BroadcasterInterface;
use crate::chain::ClaimId;
-use crate::sign::{ChannelSigner, EcdsaChannelSigner, SignerProvider};
+use crate::events::Event;
use crate::io_extras::sink;
-use crate::ln::PaymentPreimage;
use crate::ln::chan_utils;
use crate::ln::chan_utils::{
ANCHOR_INPUT_WITNESS_WEIGHT, HTLC_SUCCESS_INPUT_ANCHOR_WITNESS_WEIGHT,
HTLC_TIMEOUT_INPUT_ANCHOR_WITNESS_WEIGHT, ChannelTransactionParameters, HTLCOutputInCommitment
};
-use crate::events::Event;
-use crate::prelude::HashMap;
+use crate::ln::features::ChannelTypeFeatures;
+use crate::ln::PaymentPreimage;
+use crate::prelude::*;
+use crate::sign::{ChannelSigner, EcdsaChannelSigner, SignerProvider};
use crate::sync::Mutex;
use crate::util::logger::Logger;
use bitcoin::secp256k1;
use bitcoin::secp256k1::{PublicKey, Secp256k1};
use bitcoin::secp256k1::ecdsa::Signature;
-use crate::ln::features::ChannelTypeFeatures;
const EMPTY_SCRIPT_SIG_WEIGHT: u64 = 1 /* empty script_sig */ * WITNESS_SCALE_FACTOR as u64;
//! future, as well as generate and broadcast funding transactions handle payment preimages and a
//! few other things.
-#[cfg(anchors)]
pub mod bump_transaction;
-#[cfg(anchors)]
pub use bump_transaction::BumpTransactionEvent;
use crate::sign::SpendableOutputDescriptor;
/// Destination of the HTLC that failed to be processed.
failed_next_destination: HTLCDestination,
},
- #[cfg(anchors)]
/// 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.
///
(2, failed_next_destination, required),
})
},
- #[cfg(anchors)]
&Event::BumpTransaction(ref event)=> {
27u8.write(writer)?;
match event {
.into_script()
}
-#[cfg(anchors)]
/// Locates the output with an anchor script paying to `funding_pubkey` within `commitment_tx`.
pub(crate) fn get_anchor_output<'a>(commitment_tx: &'a Transaction, funding_pubkey: &PublicKey) -> Option<(u32, &'a TxOut)> {
let anchor_script = chan_utils::get_anchor_redeemscript(funding_pubkey).to_v0_p2wsh();
// Optionally, if the user would like to negotiate the `anchors_zero_fee_htlc_tx` option, we
// set it now. If they don't understand it, we'll fall back to our default of
// `only_static_remotekey`.
- #[cfg(anchors)]
- { // Attributes are not allowed on if expressions on our current MSRV of 1.41.
- if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
- their_features.supports_anchors_zero_fee_htlc_tx() {
- ret.set_anchors_zero_fee_htlc_tx_required();
- }
+ if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx &&
+ their_features.supports_anchors_zero_fee_htlc_tx() {
+ ret.set_anchors_zero_fee_htlc_tx_required();
}
ret
use hex;
use crate::ln::PaymentHash;
use crate::ln::channelmanager::{self, HTLCSource, PaymentId};
- #[cfg(anchors)]
use crate::ln::channel::InitFeatures;
use crate::ln::channel::{Channel, InboundHTLCOutput, OutboundV1Channel, InboundV1Channel, OutboundHTLCOutput, InboundHTLCState, OutboundHTLCState, HTLCCandidate, HTLCInitiator, commit_tx_fee_msat};
use crate::ln::channel::{MAX_FUNDING_SATOSHIS_NO_WUMBO, TOTAL_BITCOIN_SUPPLY_SATOSHIS, MIN_THEIR_CHAN_RESERVE_SATOSHIS};
assert!(res.is_ok());
}
- #[cfg(anchors)]
#[test]
fn test_supports_anchors_zero_htlc_tx_fee() {
// Tests that if both sides support and negotiate `anchors_zero_fee_htlc_tx`, it is the
assert_eq!(channel_b.context.channel_type, expected_channel_type);
}
- #[cfg(anchors)]
#[test]
fn test_rejects_implicit_simple_anchors() {
// Tests that if `option_anchors` is being negotiated implicitly through the intersection of
assert!(channel_b.is_err());
}
- #[cfg(anchors)]
#[test]
fn test_rejects_simple_anchors_channel_type() {
// Tests that if `option_anchors` is being negotiated through the `channel_type` feature,
/// Fetches the set of [`InitFeatures`] flags which are provided by or required by
/// [`ChannelManager`].
-pub fn provided_init_features(_config: &UserConfig) -> InitFeatures {
+pub fn provided_init_features(config: &UserConfig) -> InitFeatures {
// Note that if new features are added here which other peers may (eventually) require, we
// should also add the corresponding (optional) bit to the [`ChannelMessageHandler`] impl for
// [`ErroringMessageHandler`].
features.set_channel_type_optional();
features.set_scid_privacy_optional();
features.set_zero_conf_optional();
- #[cfg(anchors)]
- { // Attributes are not allowed on if expressions on our current MSRV of 1.41.
- if _config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx {
- features.set_anchors_zero_fee_htlc_tx_optional();
- }
+ if config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx {
+ features.set_anchors_zero_fee_htlc_tx_optional();
}
features
}
sender_intended_amt_msat - extra_fee_msat, 42, None, true, Some(extra_fee_msat)).is_ok());
}
- #[cfg(anchors)]
#[test]
fn test_anchors_zero_fee_htlc_tx_fallback() {
// Tests that if both nodes support anchors, but the remote node does not want to accept
//! Further functional tests which test blockchain reorganizations.
-#[cfg(anchors)]
use crate::sign::{ChannelSigner, EcdsaChannelSigner};
-#[cfg(anchors)]
-use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS;
-use crate::chain::channelmonitor::{ANTI_REORG_DELAY, Balance};
+use crate::chain::channelmonitor::{ANTI_REORG_DELAY, LATENCY_GRACE_PERIOD_BLOCKS, Balance};
use crate::chain::transaction::OutPoint;
use crate::chain::chaininterface::LowerBoundedFeeEstimator;
-#[cfg(anchors)]
use crate::events::bump_transaction::BumpTransactionEvent;
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
use crate::ln::channel;
-#[cfg(anchors)]
use crate::ln::chan_utils;
-#[cfg(anchors)]
-use crate::ln::channelmanager::ChannelManager;
-use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, PaymentId, RecipientOnionFields};
+use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, ChannelManager, PaymentId, RecipientOnionFields};
use crate::ln::msgs::ChannelMessageHandler;
-#[cfg(anchors)]
use crate::util::config::UserConfig;
-#[cfg(anchors)]
use crate::util::crypto::sign;
use crate::util::ser::Writeable;
use crate::util::test_utils;
-#[cfg(anchors)]
use bitcoin::blockdata::transaction::EcdsaSighashType;
use bitcoin::blockdata::script::Builder;
use bitcoin::blockdata::opcodes;
-use bitcoin::secp256k1::Secp256k1;
-#[cfg(anchors)]
-use bitcoin::secp256k1::SecretKey;
-#[cfg(anchors)]
-use bitcoin::{Amount, PublicKey, Script, TxIn, TxOut, PackedLockTime, Witness};
-use bitcoin::Transaction;
-#[cfg(anchors)]
+use bitcoin::secp256k1::{Secp256k1, SecretKey};
+use bitcoin::{Amount, PublicKey, Script, Transaction, TxIn, TxOut, PackedLockTime, Witness};
use bitcoin::util::sighash::SighashCache;
use crate::prelude::*;
fn do_test_monitor_rebroadcast_pending_claims(anchors: bool) {
// Test that we will retry broadcasting pending claims for a force-closed channel on every
// `ChainMonitor::rebroadcast_pending_claims` call.
- if anchors {
- assert!(cfg!(anchors));
- }
let mut chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let mut config = test_default_channel_config();
if anchors {
- #[cfg(anchors)] {
- config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
- }
+ config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
}
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config), Some(config)]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
};
#[allow(unused_assignments)]
let mut feerate = 0;
- #[cfg(anchors)] {
- feerate = if let Event::BumpTransaction(BumpTransactionEvent::HTLCResolution {
- target_feerate_sat_per_1000_weight, mut htlc_descriptors, tx_lock_time, ..
- }) = events.pop().unwrap() {
- let secp = Secp256k1::new();
- assert_eq!(htlc_descriptors.len(), 1);
- let descriptor = htlc_descriptors.pop().unwrap();
- assert_eq!(descriptor.commitment_txid, commitment_txn[0].txid());
- let htlc_output_idx = descriptor.htlc.transaction_output_index.unwrap() as usize;
- assert!(htlc_output_idx < commitment_txn[0].output.len());
- tx.lock_time = tx_lock_time;
- // Note that we don't care about actually making the HTLC transaction meet the
- // feerate for the test, we just want to make sure the feerates we receive from
- // the events never decrease.
- tx.input.push(descriptor.unsigned_tx_input());
- let signer = nodes[0].keys_manager.derive_channel_keys(
- descriptor.channel_value_satoshis, &descriptor.channel_keys_id,
- );
- let per_commitment_point = signer.get_per_commitment_point(
- descriptor.per_commitment_number, &secp
- );
- tx.output.push(descriptor.tx_output(&per_commitment_point, &secp));
- let our_sig = signer.sign_holder_htlc_transaction(&mut tx, 0, &descriptor, &secp).unwrap();
- let witness_script = descriptor.witness_script(&per_commitment_point, &secp);
- tx.input[0].witness = descriptor.tx_input_witness(&our_sig, &witness_script);
- target_feerate_sat_per_1000_weight as u64
- } else { panic!("unexpected event"); };
- }
+ feerate = if let Event::BumpTransaction(BumpTransactionEvent::HTLCResolution {
+ target_feerate_sat_per_1000_weight, mut htlc_descriptors, tx_lock_time, ..
+ }) = events.pop().unwrap() {
+ let secp = Secp256k1::new();
+ assert_eq!(htlc_descriptors.len(), 1);
+ let descriptor = htlc_descriptors.pop().unwrap();
+ assert_eq!(descriptor.commitment_txid, commitment_txn[0].txid());
+ let htlc_output_idx = descriptor.htlc.transaction_output_index.unwrap() as usize;
+ assert!(htlc_output_idx < commitment_txn[0].output.len());
+ tx.lock_time = tx_lock_time;
+ // Note that we don't care about actually making the HTLC transaction meet the
+ // feerate for the test, we just want to make sure the feerates we receive from
+ // the events never decrease.
+ tx.input.push(descriptor.unsigned_tx_input());
+ let signer = nodes[0].keys_manager.derive_channel_keys(
+ descriptor.channel_value_satoshis, &descriptor.channel_keys_id,
+ );
+ let per_commitment_point = signer.get_per_commitment_point(
+ descriptor.per_commitment_number, &secp
+ );
+ tx.output.push(descriptor.tx_output(&per_commitment_point, &secp));
+ let our_sig = signer.sign_holder_htlc_transaction(&mut tx, 0, &descriptor, &secp).unwrap();
+ let witness_script = descriptor.witness_script(&per_commitment_point, &secp);
+ tx.input[0].witness = descriptor.tx_input_witness(&our_sig, &witness_script);
+ target_feerate_sat_per_1000_weight as u64
+ } else { panic!("unexpected event"); };
(tx, feerate)
} else {
assert!(nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
#[test]
fn test_monitor_timer_based_claim() {
do_test_monitor_rebroadcast_pending_claims(false);
- #[cfg(anchors)]
do_test_monitor_rebroadcast_pending_claims(true);
}
-#[cfg(anchors)]
#[test]
fn test_yield_anchors_events() {
// Tests that two parties supporting anchor outputs can open a channel, route payments over
nodes[0].node.get_and_clear_pending_events();
}
-#[cfg(anchors)]
#[test]
fn test_anchors_aggregated_revoked_htlc_tx() {
// Test that `ChannelMonitor`s can properly detect and claim funds from a counterparty claiming
use crate::util::crypto::{hkdf_extract_expand_twice, sign, sign_with_aux_rand};
use crate::util::ser::{Writeable, Writer, Readable, ReadableArgs};
use crate::chain::transaction::OutPoint;
-#[cfg(anchors)]
use crate::events::bump_transaction::HTLCDescriptor;
use crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI;
use crate::ln::{chan_utils, PaymentPreimage};
fn sign_justice_revoked_htlc(&self, justice_tx: &Transaction, input: usize, amount: u64,
per_commitment_key: &SecretKey, htlc: &HTLCOutputInCommitment,
secp_ctx: &Secp256k1<secp256k1::All>) -> Result<Signature, ()>;
- #[cfg(anchors)]
/// Computes the signature for a commitment transaction's HTLC output used as an input within
/// `htlc_tx`, which spends the commitment transaction at index `input`. The signature returned
/// must be be computed using [`EcdsaSighashType::All`]. Note that this should only be used to
return Ok(sign_with_aux_rand(secp_ctx, &sighash, &revocation_key, &self))
}
- #[cfg(anchors)]
fn sign_holder_htlc_transaction(
&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor,
secp_ctx: &Secp256k1<secp256k1::All>
/// Maximum value: 1,000,000, any values larger than 1 Million will be treated as 1 Million (or 100%)
/// instead, although channel negotiations will fail in that case.
pub their_channel_reserve_proportional_millionths: u32,
- #[cfg(anchors)]
- /// If set, we attempt to negotiate the `anchors_zero_fee_htlc_tx`option for outbound channels.
+ /// If set, we attempt to negotiate the `anchors_zero_fee_htlc_tx`option for all future
+ /// channels. This feature requires having a reserve of onchain funds readily available to bump
+ /// transactions in the event of a channel force close to avoid the possibility of losing funds.
///
/// If this option is set, channels may be created that will not be readable by LDK versions
- /// prior to 0.0.114, causing [`ChannelManager`]'s read method to return a
+ /// prior to 0.0.116, causing [`ChannelManager`]'s read method to return a
/// [`DecodeError::InvalidValue`].
///
/// Note that setting this to true does *not* prevent us from opening channels with
announced_channel: false,
commit_upfront_shutdown_pubkey: true,
their_channel_reserve_proportional_millionths: 10_000,
- #[cfg(anchors)]
negotiate_anchors_zero_fee_htlc_tx: false,
our_max_accepted_htlcs: 50,
}
use bitcoin::secp256k1;
use bitcoin::secp256k1::{SecretKey, PublicKey};
use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature};
-#[cfg(anchors)]
use crate::events::bump_transaction::HTLCDescriptor;
use crate::util::ser::{Writeable, Writer};
use crate::io::Error;
Ok(self.inner.sign_justice_revoked_htlc(justice_tx, input, amount, per_commitment_key, htlc, secp_ctx).unwrap())
}
- #[cfg(anchors)]
fn sign_holder_htlc_transaction(
&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor,
secp_ctx: &Secp256k1<secp256k1::All>