Skip to content

Commit f98a652

Browse files
authored
Merge pull request #2816 from wpaulino/retryable-holder-sigs
Allow holder commitment and HTLC signature requests to fail
2 parents 0995de7 + e38dcca commit f98a652

13 files changed

+442
-174
lines changed

lightning/src/chain/chainmonitor.rs

+21
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,27 @@ where C::Target: chain::Filter,
635635
)
636636
}
637637
}
638+
639+
/// Triggers rebroadcasts of pending claims from force-closed channels after a transaction
640+
/// signature generation failure.
641+
///
642+
/// `monitor_opt` can be used as a filter to only trigger them for a specific channel monitor.
643+
pub fn signer_unblocked(&self, monitor_opt: Option<OutPoint>) {
644+
let monitors = self.monitors.read().unwrap();
645+
if let Some(funding_txo) = monitor_opt {
646+
if let Some(monitor_holder) = monitors.get(&funding_txo) {
647+
monitor_holder.monitor.signer_unblocked(
648+
&*self.broadcaster, &*self.fee_estimator, &self.logger
649+
)
650+
}
651+
} else {
652+
for (_, monitor_holder) in &*monitors {
653+
monitor_holder.monitor.signer_unblocked(
654+
&*self.broadcaster, &*self.fee_estimator, &self.logger
655+
)
656+
}
657+
}
658+
}
638659
}
639660

640661
impl<ChannelSigner: WriteableEcdsaChannelSigner, C: Deref, T: Deref, F: Deref, L: Deref, P: Deref>

lightning/src/chain/channelmonitor.rs

+47-56
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use crate::chain::{BestBlock, WatchedOutput};
4444
use crate::chain::chaininterface::{BroadcasterInterface, FeeEstimator, LowerBoundedFeeEstimator};
4545
use crate::chain::transaction::{OutPoint, TransactionData};
4646
use crate::sign::{ChannelDerivationParameters, HTLCDescriptor, SpendableOutputDescriptor, StaticPaymentOutputDescriptor, DelayedPaymentOutputDescriptor, ecdsa::WriteableEcdsaChannelSigner, SignerProvider, EntropySource};
47-
use crate::chain::onchaintx::{ClaimEvent, OnchainTxHandler};
47+
use crate::chain::onchaintx::{ClaimEvent, FeerateStrategy, OnchainTxHandler};
4848
use crate::chain::package::{CounterpartyOfferedHTLCOutput, CounterpartyReceivedHTLCOutput, HolderFundingOutput, HolderHTLCOutput, PackageSolvingData, PackageTemplate, RevokedOutput, RevokedHTLCOutput};
4949
use crate::chain::Filter;
5050
use crate::util::logger::{Logger, Record};
@@ -1562,28 +1562,30 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
15621562
self.inner.lock().unwrap().counterparty_node_id
15631563
}
15641564

1565-
/// Used by [`ChannelManager`] deserialization to broadcast the latest holder state if its copy
1566-
/// of the channel state was out-of-date.
1567-
///
1568-
/// You may also use this to broadcast the latest local commitment transaction, either because
1565+
/// You may use this to broadcast the latest local commitment transaction, either because
15691566
/// a monitor update failed or because we've fallen behind (i.e. we've received proof that our
15701567
/// counterparty side knows a revocation secret we gave them that they shouldn't know).
15711568
///
1572-
/// Broadcasting these transactions in the second case is UNSAFE, as they allow counterparty
1569+
/// Broadcasting these transactions in this manner is UNSAFE, as they allow counterparty
15731570
/// side to punish you. Nevertheless you may want to broadcast them if counterparty doesn't
15741571
/// close channel with their commitment transaction after a substantial amount of time. Best
15751572
/// may be to contact the other node operator out-of-band to coordinate other options available
15761573
/// to you.
1577-
///
1578-
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
1579-
pub fn get_latest_holder_commitment_txn<L: Deref>(&self, logger: &L) -> Vec<Transaction>
1580-
where L::Target: Logger {
1574+
pub fn broadcast_latest_holder_commitment_txn<B: Deref, F: Deref, L: Deref>(
1575+
&self, broadcaster: &B, fee_estimator: &F, logger: &L
1576+
)
1577+
where
1578+
B::Target: BroadcasterInterface,
1579+
F::Target: FeeEstimator,
1580+
L::Target: Logger
1581+
{
15811582
let mut inner = self.inner.lock().unwrap();
1583+
let fee_estimator = LowerBoundedFeeEstimator::new(&**fee_estimator);
15821584
let logger = WithChannelMonitor::from_impl(logger, &*inner);
1583-
inner.get_latest_holder_commitment_txn(&logger)
1585+
inner.queue_latest_holder_commitment_txn_for_broadcast(broadcaster, &fee_estimator, &logger);
15841586
}
15851587

1586-
/// Unsafe test-only version of get_latest_holder_commitment_txn used by our test framework
1588+
/// Unsafe test-only version of `broadcast_latest_holder_commitment_txn` used by our test framework
15871589
/// to bypass HolderCommitmentTransaction state update lockdown after signature and generate
15881590
/// revoked commitment transaction.
15891591
#[cfg(any(test, feature = "unsafe_revoked_tx_signing"))]
@@ -1763,7 +1765,26 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
17631765
let logger = WithChannelMonitor::from_impl(logger, &*inner);
17641766
let current_height = inner.best_block.height;
17651767
inner.onchain_tx_handler.rebroadcast_pending_claims(
1766-
current_height, &broadcaster, &fee_estimator, &logger,
1768+
current_height, FeerateStrategy::HighestOfPreviousOrNew, &broadcaster, &fee_estimator, &logger,
1769+
);
1770+
}
1771+
1772+
/// Triggers rebroadcasts of pending claims from a force-closed channel after a transaction
1773+
/// signature generation failure.
1774+
pub fn signer_unblocked<B: Deref, F: Deref, L: Deref>(
1775+
&self, broadcaster: B, fee_estimator: F, logger: &L,
1776+
)
1777+
where
1778+
B::Target: BroadcasterInterface,
1779+
F::Target: FeeEstimator,
1780+
L::Target: Logger,
1781+
{
1782+
let fee_estimator = LowerBoundedFeeEstimator::new(fee_estimator);
1783+
let mut inner = self.inner.lock().unwrap();
1784+
let logger = WithChannelMonitor::from_impl(logger, &*inner);
1785+
let current_height = inner.best_block.height;
1786+
inner.onchain_tx_handler.rebroadcast_pending_claims(
1787+
current_height, FeerateStrategy::RetryPrevious, &broadcaster, &fee_estimator, &logger,
17671788
);
17681789
}
17691790

@@ -1809,6 +1830,12 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
18091830
pub fn set_counterparty_payment_script(&self, script: ScriptBuf) {
18101831
self.inner.lock().unwrap().counterparty_payment_script = script;
18111832
}
1833+
1834+
#[cfg(test)]
1835+
pub fn do_signer_call<F: FnMut(&Signer) -> ()>(&self, mut f: F) {
1836+
let inner = self.inner.lock().unwrap();
1837+
f(&inner.onchain_tx_handler.signer);
1838+
}
18121839
}
18131840

18141841
impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
@@ -2855,7 +2882,7 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
28552882
} else if !self.holder_tx_signed {
28562883
log_error!(logger, "WARNING: You have a potentially-unsafe holder commitment transaction available to broadcast");
28572884
log_error!(logger, " in channel monitor for channel {}!", &self.channel_id());
2858-
log_error!(logger, " Read the docs for ChannelMonitor::get_latest_holder_commitment_txn and take manual action!");
2885+
log_error!(logger, " Read the docs for ChannelMonitor::broadcast_latest_holder_commitment_txn to take manual action!");
28592886
} else {
28602887
// If we generated a MonitorEvent::HolderForceClosed, the ChannelManager
28612888
// will still give us a ChannelForceClosed event with !should_broadcast, but we
@@ -3502,45 +3529,6 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35023529
}
35033530
}
35043531

3505-
fn get_latest_holder_commitment_txn<L: Deref>(
3506-
&mut self, logger: &WithChannelMonitor<L>,
3507-
) -> Vec<Transaction> where L::Target: Logger {
3508-
log_debug!(logger, "Getting signed latest holder commitment transaction!");
3509-
self.holder_tx_signed = true;
3510-
let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript);
3511-
let txid = commitment_tx.txid();
3512-
let mut holder_transactions = vec![commitment_tx];
3513-
// When anchor outputs are present, the HTLC transactions are only valid once the commitment
3514-
// transaction confirms.
3515-
if self.onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx() {
3516-
return holder_transactions;
3517-
}
3518-
for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
3519-
if let Some(vout) = htlc.0.transaction_output_index {
3520-
let preimage = if !htlc.0.offered {
3521-
if let Some(preimage) = self.payment_preimages.get(&htlc.0.payment_hash) { Some(preimage.clone()) } else {
3522-
// We can't build an HTLC-Success transaction without the preimage
3523-
continue;
3524-
}
3525-
} else if htlc.0.cltv_expiry > self.best_block.height() + 1 {
3526-
// Don't broadcast HTLC-Timeout transactions immediately as they don't meet the
3527-
// current locktime requirements on-chain. We will broadcast them in
3528-
// `block_confirmed` when `should_broadcast_holder_commitment_txn` returns true.
3529-
// Note that we add + 1 as transactions are broadcastable when they can be
3530-
// confirmed in the next block.
3531-
continue;
3532-
} else { None };
3533-
if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(
3534-
&::bitcoin::OutPoint { txid, vout }, &preimage) {
3535-
holder_transactions.push(htlc_tx);
3536-
}
3537-
}
3538-
}
3539-
// We throw away the generated waiting_first_conf data as we aren't (yet) confirmed and we don't actually know what the caller wants to do.
3540-
// The data will be re-generated and tracked in check_spend_holder_transaction if we get a confirmation.
3541-
holder_transactions
3542-
}
3543-
35443532
#[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
35453533
/// Note that this includes possibly-locktimed-in-the-future transactions!
35463534
fn unsafe_get_latest_holder_commitment_txn<L: Deref>(
@@ -3563,9 +3551,12 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35633551
continue;
35643552
}
35653553
} else { None };
3566-
if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(
3567-
&::bitcoin::OutPoint { txid, vout }, &preimage) {
3568-
holder_transactions.push(htlc_tx);
3554+
if let Some(htlc_tx) = self.onchain_tx_handler.get_maybe_signed_htlc_tx(
3555+
&::bitcoin::OutPoint { txid, vout }, &preimage
3556+
) {
3557+
if htlc_tx.is_fully_signed() {
3558+
holder_transactions.push(htlc_tx.0);
3559+
}
35693560
}
35703561
}
35713562
}

0 commit comments

Comments
 (0)