Skip to content

Commit ff0874a

Browse files
authored
Merge pull request #3153 from alecchendev/2024-07-async-closing-signed
Allow sending closing tx signatures asynchronously
2 parents 688147a + 6e2071a commit ff0874a

File tree

4 files changed

+280
-98
lines changed

4 files changed

+280
-98
lines changed

lightning/src/ln/async_signer_tests.rs

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! properly with a signer implementation that asynchronously derives signatures.
1212
1313
use std::collections::HashSet;
14-
14+
use bitcoin::key::Secp256k1;
1515
use bitcoin::{Transaction, TxOut, TxIn, Amount};
1616
use bitcoin::locktime::absolute::LockTime;
1717
use bitcoin::transaction::Version;
@@ -20,9 +20,13 @@ use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS;
2020
use crate::chain::ChannelMonitorUpdateStatus;
2121
use crate::events::bump_transaction::WalletSource;
2222
use crate::events::{ClosureReason, Event, MessageSendEvent, MessageSendEventsProvider};
23-
use crate::ln::{functional_test_utils::*, msgs};
24-
use crate::ln::msgs::ChannelMessageHandler;
23+
use crate::ln::chan_utils::ClosingTransaction;
24+
use crate::ln::channel_state::{ChannelDetails, ChannelShutdownState};
2525
use crate::ln::channelmanager::{PaymentId, RAACommitmentOrder, RecipientOnionFields};
26+
use crate::ln::msgs::ChannelMessageHandler;
27+
use crate::ln::{functional_test_utils::*, msgs};
28+
use crate::sign::ecdsa::EcdsaChannelSigner;
29+
use crate::sign::SignerProvider;
2630
use crate::util::test_channel_signer::SignerOp;
2731
use crate::util::logger::Logger;
2832

@@ -847,3 +851,105 @@ fn test_async_holder_signatures_anchors() {
847851
fn test_async_holder_signatures_remote_commitment_anchors() {
848852
do_test_async_holder_signatures(true, true);
849853
}
854+
855+
#[test]
856+
fn test_closing_signed() {
857+
do_test_closing_signed(false);
858+
do_test_closing_signed(true);
859+
}
860+
861+
fn do_test_closing_signed(extra_closing_signed: bool) {
862+
// Based off of `expect_channel_shutdown_state`.
863+
// Test that we can asynchronously sign closing transactions.
864+
let chanmon_cfgs = create_chanmon_cfgs(2);
865+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
866+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
867+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
868+
let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
869+
870+
expect_channel_shutdown_state!(nodes[0], chan_1.2, ChannelShutdownState::NotShuttingDown);
871+
872+
nodes[0].node.close_channel(&chan_1.2, &nodes[1].node.get_our_node_id()).unwrap();
873+
874+
expect_channel_shutdown_state!(nodes[0], chan_1.2, ChannelShutdownState::ShutdownInitiated);
875+
expect_channel_shutdown_state!(nodes[1], chan_1.2, ChannelShutdownState::NotShuttingDown);
876+
877+
let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
878+
nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_0_shutdown);
879+
880+
expect_channel_shutdown_state!(nodes[0], chan_1.2, ChannelShutdownState::ShutdownInitiated);
881+
expect_channel_shutdown_state!(nodes[1], chan_1.2, ChannelShutdownState::NegotiatingClosingFee);
882+
883+
let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
884+
nodes[0].disable_channel_signer_op(&nodes[1].node.get_our_node_id(), &chan_1.2, SignerOp::SignClosingTransaction);
885+
nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_1_shutdown);
886+
887+
expect_channel_shutdown_state!(nodes[0], chan_1.2, ChannelShutdownState::NegotiatingClosingFee);
888+
expect_channel_shutdown_state!(nodes[1], chan_1.2, ChannelShutdownState::NegotiatingClosingFee);
889+
890+
let events = nodes[0].node.get_and_clear_pending_msg_events();
891+
assert!(events.is_empty(), "Expected no events, got {:?}", events);
892+
nodes[0].enable_channel_signer_op(&nodes[1].node.get_our_node_id(), &chan_1.2, SignerOp::SignClosingTransaction);
893+
nodes[0].node.signer_unblocked(None);
894+
895+
let node_0_closing_signed = get_event_msg!(nodes[0], MessageSendEvent::SendClosingSigned, nodes[1].node.get_our_node_id());
896+
nodes[1].disable_channel_signer_op(&nodes[0].node.get_our_node_id(), &chan_1.2, SignerOp::SignClosingTransaction);
897+
nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_closing_signed);
898+
899+
let events = nodes[1].node.get_and_clear_pending_msg_events();
900+
assert!(events.is_empty(), "Expected no events, got {:?}", events);
901+
nodes[1].enable_channel_signer_op(&nodes[0].node.get_our_node_id(), &chan_1.2, SignerOp::SignClosingTransaction);
902+
nodes[1].node.signer_unblocked(None);
903+
904+
let node_1_closing_signed = get_event_msg!(nodes[1], MessageSendEvent::SendClosingSigned, nodes[0].node.get_our_node_id());
905+
906+
nodes[0].disable_channel_signer_op(&nodes[1].node.get_our_node_id(), &chan_1.2, SignerOp::SignClosingTransaction);
907+
nodes[0].node.handle_closing_signed(&nodes[1].node.get_our_node_id(), &node_1_closing_signed);
908+
let events = nodes[0].node.get_and_clear_pending_msg_events();
909+
assert!(events.is_empty(), "Expected no events, got {:?}", events);
910+
nodes[0].enable_channel_signer_op(&nodes[1].node.get_our_node_id(), &chan_1.2, SignerOp::SignClosingTransaction);
911+
912+
if extra_closing_signed {
913+
let node_1_closing_signed_2_bad = {
914+
let mut node_1_closing_signed_2 = node_1_closing_signed.clone();
915+
let holder_script = nodes[0].keys_manager.get_shutdown_scriptpubkey().unwrap();
916+
let counterparty_script = nodes[1].keys_manager.get_shutdown_scriptpubkey().unwrap();
917+
let funding_outpoint = bitcoin::OutPoint { txid: chan_1.3.txid(), vout: 0 };
918+
let closing_tx_2 = ClosingTransaction::new(50000, 0, holder_script.into(),
919+
counterparty_script.into(), funding_outpoint);
920+
921+
let per_peer_state = nodes[1].node.per_peer_state.read().unwrap();
922+
let mut chan_lock = per_peer_state.get(&nodes[0].node.get_our_node_id()).unwrap().lock().unwrap();
923+
let chan = chan_lock.channel_by_id.get_mut(&chan_1.2).map(|phase| phase.context_mut()).unwrap();
924+
925+
let signer = chan.get_mut_signer().as_mut_ecdsa().unwrap();
926+
let signature = signer.sign_closing_transaction(&closing_tx_2, &Secp256k1::new()).unwrap();
927+
node_1_closing_signed_2.signature = signature;
928+
node_1_closing_signed_2
929+
};
930+
nodes[0].node.handle_closing_signed(&nodes[1].node.get_our_node_id(), &node_1_closing_signed_2_bad);
931+
932+
let events = nodes[0].node.get_and_clear_pending_msg_events();
933+
assert_eq!(events.len(), 1);
934+
match events[0] {
935+
MessageSendEvent::HandleError {
936+
action: msgs::ErrorAction::SendWarningMessage { .. }, ref node_id
937+
} => {
938+
assert_eq!(node_id, &nodes[1].node.get_our_node_id());
939+
},
940+
_ => panic!("Unexpected event: {:?}", events[0]),
941+
};
942+
}
943+
944+
nodes[0].node.signer_unblocked(None);
945+
let (_, node_0_2nd_closing_signed) = get_closing_signed_broadcast!(nodes[0].node, nodes[1].node.get_our_node_id());
946+
947+
nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &node_0_2nd_closing_signed.unwrap());
948+
let (_, node_1_closing_signed) = get_closing_signed_broadcast!(nodes[1].node, nodes[0].node.get_our_node_id());
949+
assert!(node_1_closing_signed.is_none());
950+
951+
assert!(nodes[0].node.list_channels().is_empty());
952+
assert!(nodes[1].node.list_channels().is_empty());
953+
check_closed_event!(nodes[0], 1, ClosureReason::LocallyInitiatedCooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
954+
check_closed_event!(nodes[1], 1, ClosureReason::CounterpartyInitiatedCooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
955+
}

0 commit comments

Comments
 (0)