|
9 | 9 |
|
10 | 10 | //! Further functional tests which test blockchain reorganizations.
|
11 | 11 |
|
| 12 | +#[cfg(anchors)] |
| 13 | +use crate::chain::keysinterface::BaseSign; |
| 14 | +#[cfg(anchors)] |
| 15 | +use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS; |
12 | 16 | use crate::chain::channelmonitor::{ANTI_REORG_DELAY, Balance};
|
13 | 17 | use crate::chain::transaction::OutPoint;
|
14 | 18 | use crate::chain::chaininterface::LowerBoundedFeeEstimator;
|
15 | 19 | use crate::ln::channel;
|
| 20 | +#[cfg(anchors)] |
| 21 | +use crate::ln::chan_utils; |
16 | 22 | use crate::ln::channelmanager::{self, BREAKDOWN_TIMEOUT, PaymentId};
|
17 | 23 | use crate::ln::msgs::ChannelMessageHandler;
|
| 24 | +#[cfg(anchors)] |
| 25 | +use crate::util::config::UserConfig; |
| 26 | +#[cfg(anchors)] |
| 27 | +use crate::util::events::BumpTransactionEvent; |
18 | 28 | use crate::util::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
|
19 | 29 |
|
20 | 30 | use bitcoin::blockdata::script::Builder;
|
21 | 31 | use bitcoin::blockdata::opcodes;
|
22 | 32 | use bitcoin::secp256k1::Secp256k1;
|
| 33 | +#[cfg(anchors)] |
| 34 | +use bitcoin::{Amount, Script, TxIn, TxOut, PackedLockTime}; |
23 | 35 | use bitcoin::Transaction;
|
24 | 36 |
|
25 | 37 | use crate::prelude::*;
|
@@ -1666,3 +1678,136 @@ fn test_revoked_counterparty_aggregated_claims() {
|
1666 | 1678 | assert!(nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
|
1667 | 1679 | assert!(nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances().is_empty());
|
1668 | 1680 | }
|
| 1681 | + |
| 1682 | +#[cfg(anchors)] |
| 1683 | +#[test] |
| 1684 | +fn test_yield_anchors_events() { |
| 1685 | + let secp = Secp256k1::new(); |
| 1686 | + let mut chanmon_cfgs = create_chanmon_cfgs(2); |
| 1687 | + let node_cfgs = create_node_cfgs(2, &chanmon_cfgs); |
| 1688 | + let mut anchors_config = UserConfig::default(); |
| 1689 | + anchors_config.channel_handshake_config.announced_channel = true; |
| 1690 | + anchors_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true; |
| 1691 | + let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(anchors_config), Some(anchors_config)]); |
| 1692 | + let nodes = create_network(2, &node_cfgs, &node_chanmgrs); |
| 1693 | + |
| 1694 | + let features = channelmanager::provided_init_features(); |
| 1695 | + let chan_id = create_announced_chan_between_nodes_with_value( |
| 1696 | + &nodes, 0, 1, 1_000_000, 500_000_000, features.clone(), features.clone(), |
| 1697 | + ).2; |
| 1698 | + route_payment(&nodes[0], &[&nodes[1]], 1_000_000); |
| 1699 | + let (payment_preimage, payment_hash, _) = route_payment(&nodes[1], &[&nodes[0]], 1_000_000); |
| 1700 | + |
| 1701 | + assert!(nodes[0].node.get_and_clear_pending_events().is_empty()); |
| 1702 | + |
| 1703 | + connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + 1); |
| 1704 | + check_closed_broadcast!(&nodes[0], true); |
| 1705 | + assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty()); |
| 1706 | + |
| 1707 | + get_monitor!(nodes[0], chan_id).provide_payment_preimage( |
| 1708 | + &payment_hash, &payment_preimage, &node_cfgs[0].tx_broadcaster, |
| 1709 | + &LowerBoundedFeeEstimator::new(node_cfgs[0].fee_estimator), &nodes[0].logger |
| 1710 | + ); |
| 1711 | + |
| 1712 | + let mut holder_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events(); |
| 1713 | + assert_eq!(holder_events.len(), 1); |
| 1714 | + let (commitment_tx, anchor_tx) = match holder_events.pop().unwrap() { |
| 1715 | + Event::BumpTransaction(BumpTransactionEvent::ChannelClose { commitment_tx, anchor_descriptor, .. }) => { |
| 1716 | + assert_eq!(commitment_tx.input.len(), 1); |
| 1717 | + assert_eq!(commitment_tx.output.len(), 6); |
| 1718 | + let mut anchor_tx = Transaction { |
| 1719 | + version: 2, |
| 1720 | + lock_time: PackedLockTime::ZERO, |
| 1721 | + input: vec![ |
| 1722 | + TxIn { previous_output: anchor_descriptor.outpoint, ..Default::default() }, |
| 1723 | + TxIn { ..Default::default() }, |
| 1724 | + ], |
| 1725 | + output: vec![TxOut { |
| 1726 | + value: Amount::ONE_BTC.to_sat(), |
| 1727 | + script_pubkey: Script::new_op_return(&[]), |
| 1728 | + }], |
| 1729 | + }; |
| 1730 | + let signer = nodes[0].keys_manager.derive_channel_keys( |
| 1731 | + anchor_descriptor.channel_value_satoshis, &anchor_descriptor.channel_keys_id, |
| 1732 | + ); |
| 1733 | + let funding_sig = signer.sign_holder_anchor_input(&mut anchor_tx, 0, &secp).unwrap(); |
| 1734 | + anchor_tx.input[0].witness = chan_utils::build_anchor_input_witness( |
| 1735 | + &signer.pubkeys().funding_pubkey, &funding_sig |
| 1736 | + ); |
| 1737 | + (commitment_tx, anchor_tx) |
| 1738 | + }, |
| 1739 | + _ => panic!("Unexpected event"), |
| 1740 | + }; |
| 1741 | + |
| 1742 | + mine_transactions(&nodes[0], &[&commitment_tx, &anchor_tx]); |
| 1743 | + check_added_monitors!(nodes[0], 1); |
| 1744 | + |
| 1745 | + let mut holder_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events(); |
| 1746 | + // Certain block ConnectStyle's cause an extra ChannelClose event to be emitted since the best |
| 1747 | + // block is being updated prior to the confirmed transactions. |
| 1748 | + match *nodes[0].connect_style.borrow() { |
| 1749 | + ConnectStyle::BestBlockFirst|ConnectStyle::BestBlockFirstReorgsOnlyTip|ConnectStyle::BestBlockFirstSkippingBlocks => { |
| 1750 | + assert_eq!(holder_events.len(), 3); |
| 1751 | + if let Event::BumpTransaction(BumpTransactionEvent::ChannelClose { .. }) = holder_events.remove(0) {} |
| 1752 | + else { panic!("unexpected event"); } |
| 1753 | + |
| 1754 | + }, |
| 1755 | + _ => assert_eq!(holder_events.len(), 2), |
| 1756 | + }; |
| 1757 | + let mut htlc_txs = Vec::with_capacity(2); |
| 1758 | + for event in holder_events { |
| 1759 | + match event { |
| 1760 | + Event::BumpTransaction(BumpTransactionEvent::HTLCResolution { htlc_descriptors, .. }) => { |
| 1761 | + assert_eq!(htlc_descriptors.len(), 1); |
| 1762 | + let htlc_descriptor = &htlc_descriptors[0]; |
| 1763 | + let signer = nodes[0].keys_manager.derive_channel_keys( |
| 1764 | + htlc_descriptor.channel_value_satoshis, &htlc_descriptor.channel_keys_id |
| 1765 | + ); |
| 1766 | + let per_commitment_point = signer.get_per_commitment_point(htlc_descriptor.per_commitment_number, &secp); |
| 1767 | + let mut htlc_tx = Transaction { |
| 1768 | + version: 2, |
| 1769 | + lock_time: if htlc_descriptor.htlc.offered { |
| 1770 | + PackedLockTime(htlc_descriptor.htlc.cltv_expiry) |
| 1771 | + } else { |
| 1772 | + PackedLockTime::ZERO |
| 1773 | + }, |
| 1774 | + input: vec![ |
| 1775 | + htlc_descriptor.unsigned_tx_input(), // HTLC input |
| 1776 | + TxIn { ..Default::default() } // Fee input |
| 1777 | + ], |
| 1778 | + output: vec![ |
| 1779 | + htlc_descriptor.tx_output(&per_commitment_point, &secp), // HTLC output |
| 1780 | + TxOut { // Fee input change |
| 1781 | + value: Amount::ONE_BTC.to_sat(), |
| 1782 | + script_pubkey: Script::new_op_return(&[]), |
| 1783 | + } |
| 1784 | + ] |
| 1785 | + }; |
| 1786 | + let our_sig = signer.sign_holder_htlc_transaction(&mut htlc_tx, 0, htlc_descriptor, &secp).unwrap(); |
| 1787 | + let witness_script = htlc_descriptor.witness_script(&per_commitment_point, &secp); |
| 1788 | + htlc_tx.input[0].witness = htlc_descriptor.tx_input_witness(&our_sig, &witness_script); |
| 1789 | + htlc_txs.push(htlc_tx); |
| 1790 | + }, |
| 1791 | + _ => panic!("Unexpected event"), |
| 1792 | + } |
| 1793 | + } |
| 1794 | + |
| 1795 | + mine_transactions(&nodes[0], &[&htlc_txs[0], &htlc_txs[1]]); |
| 1796 | + connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1); |
| 1797 | + |
| 1798 | + assert!(nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty()); |
| 1799 | + |
| 1800 | + connect_blocks(&nodes[0], BREAKDOWN_TIMEOUT as u32); |
| 1801 | + |
| 1802 | + let holder_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events(); |
| 1803 | + assert_eq!(holder_events.len(), 3); |
| 1804 | + for event in holder_events { |
| 1805 | + match event { |
| 1806 | + Event::SpendableOutputs { .. } => {}, |
| 1807 | + _ => panic!("Unexpected event"), |
| 1808 | + } |
| 1809 | + } |
| 1810 | + |
| 1811 | + // Clear the remaining events as they're not relevant to what we're testing. |
| 1812 | + nodes[0].node.get_and_clear_pending_events(); |
| 1813 | +} |
0 commit comments