Skip to content

Commit 53d53c2

Browse files
committed
Allow holder commitment and HTLC signature requests to fail
As part of the ongoing async signer work, our holder signatures must also be capable of being obtained asynchronously. We rely on our existing `ChainMonitor::rebroadcast_pending_claims` method to retry pending onchain claims by re-signing and rebroadcasting transactions. Unfortunately, we cannot retry said claims without them being registered first, so if we're not able to obtain the signature synchronously, we must return the transaction as unsigned and ensure it is not broadcast.
1 parent 3c0420c commit 53d53c2

File tree

7 files changed

+204
-54
lines changed

7 files changed

+204
-54
lines changed

lightning/src/chain/channelmonitor.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,8 +1396,8 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
13961396
/// Loads the funding txo and outputs to watch into the given `chain::Filter` by repeatedly
13971397
/// calling `chain::Filter::register_output` and `chain::Filter::register_tx` until all outputs
13981398
/// have been registered.
1399-
pub fn load_outputs_to_watch<F: Deref, L: Deref>(&self, filter: &F, logger: &L)
1400-
where
1399+
pub fn load_outputs_to_watch<F: Deref, L: Deref>(&self, filter: &F, logger: &L)
1400+
where
14011401
F::Target: chain::Filter, L::Target: Logger,
14021402
{
14031403
let lock = self.inner.lock().unwrap();
@@ -1542,21 +1542,16 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
15421542
self.inner.lock().unwrap().counterparty_node_id
15431543
}
15441544

1545-
/// Used by [`ChannelManager`] deserialization to broadcast the latest holder state if its copy
1546-
/// of the channel state was out-of-date.
1547-
///
1548-
/// You may also use this to broadcast the latest local commitment transaction, either because
1545+
/// You may use this to broadcast the latest local commitment transaction, either because
15491546
/// a monitor update failed or because we've fallen behind (i.e. we've received proof that our
15501547
/// counterparty side knows a revocation secret we gave them that they shouldn't know).
15511548
///
1552-
/// Broadcasting these transactions in the second case is UNSAFE, as they allow counterparty
1549+
/// Broadcasting these transactions in this manner is UNSAFE, as they allow counterparty
15531550
/// side to punish you. Nevertheless you may want to broadcast them if counterparty doesn't
15541551
/// close channel with their commitment transaction after a substantial amount of time. Best
15551552
/// may be to contact the other node operator out-of-band to coordinate other options available
15561553
/// to you.
1557-
///
1558-
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
1559-
pub fn get_latest_holder_commitment_txn<L: Deref>(&self, logger: &L) -> Vec<Transaction>
1554+
pub fn get_latest_holder_commitment_txn<L: Deref>(&self, logger: &L) -> Result<Vec<Transaction>, ()>
15601555
where L::Target: Logger {
15611556
let mut inner = self.inner.lock().unwrap();
15621557
let logger = WithChannelMonitor::from_impl(logger, &*inner);
@@ -1789,6 +1784,12 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitor<Signer> {
17891784
pub fn set_counterparty_payment_script(&self, script: ScriptBuf) {
17901785
self.inner.lock().unwrap().counterparty_payment_script = script;
17911786
}
1787+
1788+
#[cfg(test)]
1789+
pub fn do_signer_call<F: FnMut(&Signer) -> ()>(&self, mut f: F) {
1790+
let inner = self.inner.lock().unwrap();
1791+
f(&inner.onchain_tx_handler.signer);
1792+
}
17921793
}
17931794

17941795
impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
@@ -3462,16 +3463,19 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34623463

34633464
fn get_latest_holder_commitment_txn<L: Deref>(
34643465
&mut self, logger: &WithChannelMonitor<L>,
3465-
) -> Vec<Transaction> where L::Target: Logger {
3466+
) -> Result<Vec<Transaction>, ()> where L::Target: Logger {
34663467
log_debug!(logger, "Getting signed latest holder commitment transaction!");
34673468
self.holder_tx_signed = true;
3468-
let commitment_tx = self.onchain_tx_handler.get_fully_signed_holder_tx(&self.funding_redeemscript);
3469+
let commitment_tx = self.onchain_tx_handler.get_maybe_signed_holder_tx(&self.funding_redeemscript);
3470+
if commitment_tx.input.iter().any(|input| input.witness.is_empty()) {
3471+
return Err(());
3472+
}
34693473
let txid = commitment_tx.txid();
34703474
let mut holder_transactions = vec![commitment_tx];
34713475
// When anchor outputs are present, the HTLC transactions are only valid once the commitment
34723476
// transaction confirms.
34733477
if self.onchain_tx_handler.channel_type_features().supports_anchors_zero_fee_htlc_tx() {
3474-
return holder_transactions;
3478+
return Ok(holder_transactions);
34753479
}
34763480
for htlc in self.current_holder_commitment_tx.htlc_outputs.iter() {
34773481
if let Some(vout) = htlc.0.transaction_output_index {
@@ -3488,15 +3492,18 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
34883492
// confirmed in the next block.
34893493
continue;
34903494
} else { None };
3491-
if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(
3492-
&::bitcoin::OutPoint { txid, vout }, &preimage) {
3493-
holder_transactions.push(htlc_tx);
3495+
if let Some(htlc_tx) = self.onchain_tx_handler.get_maybe_signed_htlc_tx(
3496+
&::bitcoin::OutPoint { txid, vout }, &preimage
3497+
) {
3498+
if !htlc_tx.input.iter().any(|input| input.witness.is_empty()) {
3499+
holder_transactions.push(htlc_tx);
3500+
}
34943501
}
34953502
}
34963503
}
34973504
// 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.
34983505
// The data will be re-generated and tracked in check_spend_holder_transaction if we get a confirmation.
3499-
holder_transactions
3506+
Ok(holder_transactions)
35003507
}
35013508

35023509
#[cfg(any(test,feature = "unsafe_revoked_tx_signing"))]
@@ -3521,9 +3528,12 @@ impl<Signer: WriteableEcdsaChannelSigner> ChannelMonitorImpl<Signer> {
35213528
continue;
35223529
}
35233530
} else { None };
3524-
if let Some(htlc_tx) = self.onchain_tx_handler.get_fully_signed_htlc_tx(
3525-
&::bitcoin::OutPoint { txid, vout }, &preimage) {
3526-
holder_transactions.push(htlc_tx);
3531+
if let Some(htlc_tx) = self.onchain_tx_handler.get_maybe_signed_htlc_tx(
3532+
&::bitcoin::OutPoint { txid, vout }, &preimage
3533+
) {
3534+
if !htlc_tx.input.iter().any(|input| input.witness.is_empty()) {
3535+
holder_transactions.push(htlc_tx);
3536+
}
35273537
}
35283538
}
35293539
}

lightning/src/chain/onchaintx.rs

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,8 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
636636
let commitment_tx_feerate_sat_per_1000_weight =
637637
compute_feerate_sat_per_1000_weight(fee_sat, tx.weight().to_wu());
638638
if commitment_tx_feerate_sat_per_1000_weight >= package_target_feerate_sat_per_1000_weight {
639-
log_debug!(logger, "Pre-signed {} already has feerate {} sat/kW above required {} sat/kW",
640-
log_tx!(tx), commitment_tx_feerate_sat_per_1000_weight,
639+
log_debug!(logger, "Pre-signed commitment {} already has feerate {} sat/kW above required {} sat/kW",
640+
tx.txid(), commitment_tx_feerate_sat_per_1000_weight,
641641
package_target_feerate_sat_per_1000_weight);
642642
return Some((new_timer, 0, OnchainClaim::Tx(tx.clone())));
643643
}
@@ -776,8 +776,12 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
776776
// `OnchainClaim`.
777777
let claim_id = match claim {
778778
OnchainClaim::Tx(tx) => {
779-
log_info!(logger, "Broadcasting onchain {}", log_tx!(tx));
780-
broadcaster.broadcast_transactions(&[&tx]);
779+
if tx.input.iter().any(|input| input.witness.is_empty()) {
780+
log_info!(logger, "Waiting for signature of unsigned onchain transaction {}", tx.txid());
781+
} else {
782+
log_info!(logger, "Broadcasting onchain {}", log_tx!(tx));
783+
broadcaster.broadcast_transactions(&[&tx]);
784+
}
781785
ClaimId(tx.txid().to_byte_array())
782786
},
783787
OnchainClaim::Event(claim_event) => {
@@ -969,8 +973,13 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
969973
) {
970974
match bump_claim {
971975
OnchainClaim::Tx(bump_tx) => {
972-
log_info!(logger, "Broadcasting RBF-bumped onchain {}", log_tx!(bump_tx));
973-
broadcaster.broadcast_transactions(&[&bump_tx]);
976+
if bump_tx.input.iter().any(|input| input.witness.is_empty()) {
977+
log_info!(logger, "Waiting for signature of RBF-bumped unsigned onchain transaction {}",
978+
bump_tx.txid());
979+
} else {
980+
log_info!(logger, "Broadcasting RBF-bumped onchain {}", log_tx!(bump_tx));
981+
broadcaster.broadcast_transactions(&[&bump_tx]);
982+
}
974983
},
975984
OnchainClaim::Event(claim_event) => {
976985
log_info!(logger, "Yielding RBF-bumped onchain event to spend inputs {:?}", request.outpoints());
@@ -1106,13 +1115,10 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
11061115
&self.holder_commitment.trust().built_transaction().transaction
11071116
}
11081117

1109-
//TODO: getting lastest holder transactions should be infallible and result in us "force-closing the channel", but we may
1110-
// have empty holder commitment transaction if a ChannelMonitor is asked to force-close just after OutboundV1Channel::get_funding_created,
1111-
// before providing a initial commitment transaction. For outbound channel, init ChannelMonitor at Channel::funding_signed, there is nothing
1112-
// to monitor before.
1113-
pub(crate) fn get_fully_signed_holder_tx(&mut self, funding_redeemscript: &Script) -> Transaction {
1114-
let sig = self.signer.sign_holder_commitment(&self.holder_commitment, &self.secp_ctx).expect("signing holder commitment");
1115-
self.holder_commitment.add_holder_sig(funding_redeemscript, sig)
1118+
pub(crate) fn get_maybe_signed_holder_tx(&mut self, funding_redeemscript: &Script) -> Transaction {
1119+
self.signer.sign_holder_commitment(&self.holder_commitment, &self.secp_ctx)
1120+
.map(|sig| self.holder_commitment.add_holder_sig(funding_redeemscript, sig))
1121+
.unwrap_or_else(|_| self.get_unsigned_holder_commitment_tx().clone())
11161122
}
11171123

11181124
#[cfg(any(test, feature="unsafe_revoked_tx_signing"))]
@@ -1121,7 +1127,7 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
11211127
self.holder_commitment.add_holder_sig(funding_redeemscript, sig)
11221128
}
11231129

1124-
pub(crate) fn get_fully_signed_htlc_tx(&mut self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>) -> Option<Transaction> {
1130+
pub(crate) fn get_maybe_signed_htlc_tx(&mut self, outp: &::bitcoin::OutPoint, preimage: &Option<PaymentPreimage>) -> Option<Transaction> {
11251131
let get_signed_htlc_tx = |holder_commitment: &HolderCommitmentTransaction| {
11261132
let trusted_tx = holder_commitment.trust();
11271133
if trusted_tx.txid() != outp.txid {
@@ -1149,10 +1155,11 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
11491155
preimage: preimage.clone(),
11501156
counterparty_sig: counterparty_htlc_sig.clone(),
11511157
};
1152-
let htlc_sig = self.signer.sign_holder_htlc_transaction(&htlc_tx, 0, &htlc_descriptor, &self.secp_ctx).unwrap();
1153-
htlc_tx.input[0].witness = trusted_tx.build_htlc_input_witness(
1154-
htlc_idx, &counterparty_htlc_sig, &htlc_sig, preimage,
1155-
);
1158+
if let Ok(htlc_sig) = self.signer.sign_holder_htlc_transaction(&htlc_tx, 0, &htlc_descriptor, &self.secp_ctx) {
1159+
htlc_tx.input[0].witness = trusted_tx.build_htlc_input_witness(
1160+
htlc_idx, &counterparty_htlc_sig, &htlc_sig, preimage,
1161+
);
1162+
}
11561163
Some(htlc_tx)
11571164
};
11581165

lightning/src/chain/package.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,10 +637,10 @@ impl PackageSolvingData {
637637
match self {
638638
PackageSolvingData::HolderHTLCOutput(ref outp) => {
639639
debug_assert!(!outp.channel_type_features.supports_anchors_zero_fee_htlc_tx());
640-
return onchain_handler.get_fully_signed_htlc_tx(outpoint, &outp.preimage);
640+
return onchain_handler.get_maybe_signed_htlc_tx(outpoint, &outp.preimage);
641641
}
642642
PackageSolvingData::HolderFundingOutput(ref outp) => {
643-
return Some(onchain_handler.get_fully_signed_holder_tx(&outp.funding_redeemscript));
643+
Some(onchain_handler.get_maybe_signed_holder_tx(&outp.funding_redeemscript))
644644
}
645645
_ => { panic!("API Error!"); }
646646
}

lightning/src/ln/async_signer_tests.rs

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,12 @@
1010
//! Tests for asynchronous signing. These tests verify that the channel state machine behaves
1111
//! properly with a signer implementation that asynchronously derives signatures.
1212
13-
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider};
13+
use bitcoin::{Transaction, TxOut, TxIn, Amount};
14+
use bitcoin::blockdata::locktime::absolute::LockTime;
15+
16+
use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS;
17+
use crate::events::bump_transaction::WalletSource;
18+
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
1419
use crate::ln::functional_test_utils::*;
1520
use crate::ln::msgs::ChannelMessageHandler;
1621
use crate::ln::channelmanager::{PaymentId, RecipientOnionFields};
@@ -321,3 +326,107 @@ fn test_async_commitment_signature_for_peer_disconnect() {
321326
};
322327
}
323328
}
329+
330+
fn do_test_async_holder_signatures(anchors: bool) {
331+
// Ensures that we can obtain holder signatures for commitment and HTLC transactions
332+
// asynchronously by allowing their retrieval to fail and retrying via
333+
// `ChainMonitor::rebroadcast_pending_claims`.
334+
let mut config = test_default_channel_config();
335+
if anchors {
336+
config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
337+
config.manually_accept_inbound_channels = true;
338+
}
339+
340+
let chanmon_cfgs = create_chanmon_cfgs(2);
341+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
342+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(config), Some(config)]);
343+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
344+
345+
let coinbase_tx = Transaction {
346+
version: 2,
347+
lock_time: LockTime::ZERO,
348+
input: vec![TxIn { ..Default::default() }],
349+
output: vec![
350+
TxOut {
351+
value: Amount::ONE_BTC.to_sat(),
352+
script_pubkey: nodes[0].wallet_source.get_change_script().unwrap(),
353+
},
354+
],
355+
};
356+
if anchors {
357+
*nodes[0].fee_estimator.sat_per_kw.lock().unwrap() *= 2;
358+
nodes[0].wallet_source.add_utxo(bitcoin::OutPoint { txid: coinbase_tx.txid(), vout: 0 }, coinbase_tx.output[0].value);
359+
}
360+
361+
// Route an HTLC and set the signer as unavailable.
362+
let (_, _, chan_id, funding_tx) = create_announced_chan_between_nodes(&nodes, 0, 1);
363+
route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
364+
365+
nodes[0].set_channel_signer_available(&nodes[1].node.get_our_node_id(), &chan_id, false);
366+
367+
// We'll connect blocks until the sender has to go onchain to time out the HTLC.
368+
connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + 1);
369+
370+
// No transaction should be broadcast since the signer is not available yet.
371+
assert!(nodes[0].tx_broadcaster.txn_broadcast().is_empty());
372+
assert!(nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
373+
374+
// Mark it as available now, we should see the signed commitment transaction.
375+
nodes[0].set_channel_signer_available(&nodes[1].node.get_our_node_id(), &chan_id, true);
376+
nodes[0].chain_monitor.chain_monitor.rebroadcast_pending_claims();
377+
378+
let commitment_tx = {
379+
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
380+
if anchors {
381+
assert_eq!(txn.len(), 1);
382+
check_spends!(txn[0], funding_tx);
383+
txn.remove(0)
384+
} else {
385+
assert_eq!(txn.len(), 2);
386+
if txn[0].input[0].previous_output.txid == funding_tx.txid() {
387+
check_spends!(txn[0], funding_tx);
388+
check_spends!(txn[1], txn[0]);
389+
txn.remove(0)
390+
} else {
391+
check_spends!(txn[1], funding_tx);
392+
check_spends!(txn[0], txn[1]);
393+
txn.remove(1)
394+
}
395+
}
396+
};
397+
398+
// Mark it as unavailable again to now test the HTLC transaction. We'll mine the commitment such
399+
// that the HTLC transaction is retried.
400+
nodes[0].set_channel_signer_available(&nodes[1].node.get_our_node_id(), &chan_id, false);
401+
mine_transaction(&nodes[0], &commitment_tx);
402+
403+
check_added_monitors(&nodes[0], 1);
404+
check_closed_broadcast(&nodes[0], 1, true);
405+
check_closed_event(&nodes[0], 1, ClosureReason::CommitmentTxConfirmed, false, &[nodes[1].node.get_our_node_id()], 100_000);
406+
407+
// No HTLC transaction should be broadcast as the signer is not available yet.
408+
if anchors {
409+
handle_bump_htlc_event(&nodes[0], 1);
410+
}
411+
assert!(nodes[0].tx_broadcaster.txn_broadcast().is_empty());
412+
413+
// Mark it as available now, we should see the signed HTLC transaction.
414+
nodes[0].set_channel_signer_available(&nodes[1].node.get_our_node_id(), &chan_id, true);
415+
nodes[0].chain_monitor.chain_monitor.rebroadcast_pending_claims();
416+
417+
if anchors {
418+
handle_bump_htlc_event(&nodes[0], 1);
419+
}
420+
{
421+
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
422+
assert_eq!(txn.len(), 1);
423+
check_spends!(txn[0], commitment_tx, coinbase_tx);
424+
txn.remove(0)
425+
};
426+
}
427+
428+
#[test]
429+
fn test_async_holder_signatures() {
430+
do_test_async_holder_signatures(false);
431+
do_test_async_holder_signatures(true);
432+
}

lightning/src/ln/functional_test_utils.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! nodes for functional tests.
1212
1313
use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch, chainmonitor::Persist};
14-
use crate::sign::EntropySource;
14+
use crate::sign::{ChannelSigner, EntropySource};
1515
use crate::chain::channelmonitor::ChannelMonitor;
1616
use crate::chain::transaction::OutPoint;
1717
use crate::events::{ClaimedHTLC, ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, PaymentFailureReason};
@@ -454,16 +454,34 @@ impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
454454
/// `release_commitment_secret` are affected by this setting.
455455
#[cfg(test)]
456456
pub fn set_channel_signer_available(&self, peer_id: &PublicKey, chan_id: &ChannelId, available: bool) {
457+
log_debug!(self.logger, "Setting channel signer for {} as available={}", chan_id, available);
458+
457459
let per_peer_state = self.node.per_peer_state.read().unwrap();
458460
let chan_lock = per_peer_state.get(peer_id).unwrap().lock().unwrap();
459-
let signer = (|| {
460-
match chan_lock.channel_by_id.get(chan_id) {
461-
Some(phase) => phase.context().get_signer(),
462-
None => panic!("Couldn't find a channel with id {}", chan_id),
461+
let mut funding_txo = None;
462+
if let Some(chan) = chan_lock.channel_by_id.get(chan_id).map(|phase| phase.context()) {
463+
funding_txo = chan.get_funding_txo();
464+
chan.get_signer().as_ecdsa().unwrap().set_available(available);
465+
}
466+
467+
if let Some(funding_txo) = funding_txo {
468+
if let Ok(monitor) = self.chain_monitor.chain_monitor.get_monitor(funding_txo) {
469+
let mut channel_keys_id = None;
470+
monitor.do_signer_call(|signer| {
471+
channel_keys_id = Some(signer.inner.channel_keys_id());
472+
signer.set_available(available)
473+
});
474+
475+
if available {
476+
self.keys_manager.unavailable_signers.lock().unwrap()
477+
.remove(channel_keys_id.as_ref().unwrap());
478+
} else {
479+
self.keys_manager.unavailable_signers.lock().unwrap()
480+
.insert(channel_keys_id.unwrap());
481+
}
463482
}
464-
})();
465-
log_debug!(self.logger, "Setting channel signer for {} as available={}", chan_id, available);
466-
signer.as_ecdsa().unwrap().set_available(available);
483+
484+
}
467485
}
468486
}
469487

lightning/src/util/test_channel_signer.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ impl TestChannelSigner {
117117
/// When `true`, methods are forwarded to the underlying signer as normal. When `false`, some
118118
/// methods will return `Err` indicating that the signer is unavailable. Intended to be used for
119119
/// testing asynchronous signing.
120-
#[cfg(test)]
121120
pub fn set_available(&self, available: bool) {
122121
*self.available.lock().unwrap() = available;
123122
}
@@ -221,6 +220,9 @@ impl EcdsaChannelSigner for TestChannelSigner {
221220
&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor,
222221
secp_ctx: &Secp256k1<secp256k1::All>
223222
) -> Result<Signature, ()> {
223+
if !*self.available.lock().unwrap() {
224+
return Err(());
225+
}
224226
let state = self.state.lock().unwrap();
225227
if state.last_holder_revoked_commitment - 1 != htlc_descriptor.per_commitment_number &&
226228
state.last_holder_revoked_commitment - 2 != htlc_descriptor.per_commitment_number

0 commit comments

Comments
 (0)