Skip to content

Commit df9bd93

Browse files
committed
Tests WIP
1 parent ec13ed2 commit df9bd93

File tree

4 files changed

+274
-60
lines changed

4 files changed

+274
-60
lines changed

lightning/src/ln/functional_test_utils.rs

+20
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ use crate::chain::{BestBlock, ChannelMonitorUpdateStatus, Confirm, Listen, Watch
1414
use crate::sign::EntropySource;
1515
use crate::chain::channelmonitor::ChannelMonitor;
1616
use crate::chain::transaction::OutPoint;
17+
#[cfg(anchors)]
18+
use crate::events::bump_transaction::{BumpTransactionEventHandler, Wallet};
1719
use crate::events::{ClosureReason, Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, PathFailure, PaymentPurpose, PaymentFailureReason};
1820
use crate::ln::{PaymentPreimage, PaymentHash, PaymentSecret};
1921
use crate::ln::channelmanager::{AChannelManager, ChainParameters, ChannelManager, ChannelManagerReadArgs, RAACommitmentOrder, PaymentSendFailure, RecipientOnionFields, PaymentId, MIN_CLTV_EXPIRY_DELTA};
@@ -354,6 +356,8 @@ pub struct NodeCfg<'a> {
354356
pub network_graph: Arc<NetworkGraph<&'a test_utils::TestLogger>>,
355357
pub node_seed: [u8; 32],
356358
pub override_init_features: Rc<RefCell<Option<InitFeatures>>>,
359+
#[cfg(anchors)]
360+
pub wallet_utxo_source: Arc<test_utils::TestWalletUtxoSource>,
357361
}
358362

359363
type TestChannelManager<'a, 'b, 'c> = ChannelManager<&'b TestChainMonitor<'c>, &'c test_utils::TestBroadcaster, &'b test_utils::TestKeysInterface, &'b test_utils::TestKeysInterface, &'b test_utils::TestKeysInterface, &'c test_utils::TestFeeEstimator, &'b test_utils::TestRouter<'c>, &'c test_utils::TestLogger>;
@@ -375,6 +379,13 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> {
375379
pub blocks: Arc<Mutex<Vec<(Block, u32)>>>,
376380
pub connect_style: Rc<RefCell<ConnectStyle>>,
377381
pub override_init_features: Rc<RefCell<Option<InitFeatures>>>,
382+
#[cfg(anchors)]
383+
pub wallet_utxo_source: Arc<test_utils::TestWalletUtxoSource>,
384+
#[cfg(anchors)]
385+
pub bump_tx_handler: BumpTransactionEventHandler<
386+
&'c test_utils::TestBroadcaster, Arc<Wallet<Arc<test_utils::TestWalletUtxoSource>>>,
387+
&'b test_utils::TestKeysInterface, &'c test_utils::TestLogger
388+
>,
378389
}
379390
impl<'a, 'b, 'c> Node<'a, 'b, 'c> {
380391
pub fn best_block_hash(&self) -> BlockHash {
@@ -2510,6 +2521,8 @@ pub fn create_node_cfgs<'a>(node_count: usize, chanmon_cfgs: &'a Vec<TestChanMon
25102521
node_seed: seed,
25112522
network_graph,
25122523
override_init_features: Rc::new(RefCell::new(None)),
2524+
#[cfg(anchors)]
2525+
wallet_utxo_source: Arc::new(test_utils::TestWalletUtxoSource::new()),
25132526
});
25142527
}
25152528

@@ -2566,6 +2579,13 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
25662579
blocks: Arc::clone(&cfgs[i].tx_broadcaster.blocks),
25672580
connect_style: Rc::clone(&connect_style),
25682581
override_init_features: Rc::clone(&cfgs[i].override_init_features),
2582+
#[cfg(anchors)]
2583+
wallet_utxo_source: Arc::clone(&cfgs[i].wallet_utxo_source),
2584+
#[cfg(anchors)]
2585+
bump_tx_handler: BumpTransactionEventHandler::new(
2586+
&cfgs[i].tx_broadcaster, Arc::new(Wallet::new(Arc::clone(&cfgs[i].wallet_utxo_source))),
2587+
&cfgs[i].keys_manager, &cfgs[i].logger,
2588+
)
25692589
})
25702590
}
25712591

lightning/src/ln/functional_tests.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -5319,7 +5319,20 @@ fn test_key_derivation_params() {
53195319
let network_graph = Arc::new(NetworkGraph::new(Network::Testnet, &chanmon_cfgs[0].logger));
53205320
let scorer = Mutex::new(test_utils::TestScorer::new());
53215321
let router = test_utils::TestRouter::new(network_graph.clone(), &scorer);
5322-
let node = NodeCfg { chain_source: &chanmon_cfgs[0].chain_source, logger: &chanmon_cfgs[0].logger, tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster, fee_estimator: &chanmon_cfgs[0].fee_estimator, router, chain_monitor, keys_manager: &keys_manager, network_graph, node_seed: seed, override_init_features: alloc::rc::Rc::new(core::cell::RefCell::new(None)) };
5322+
let node = NodeCfg {
5323+
chain_source: &chanmon_cfgs[0].chain_source,
5324+
logger: &chanmon_cfgs[0].logger,
5325+
tx_broadcaster: &chanmon_cfgs[0].tx_broadcaster,
5326+
fee_estimator: &chanmon_cfgs[0].fee_estimator,
5327+
router,
5328+
chain_monitor,
5329+
keys_manager: &keys_manager,
5330+
network_graph,
5331+
node_seed: seed,
5332+
override_init_features: alloc::rc::Rc::new(core::cell::RefCell::new(None)),
5333+
#[cfg(anchors)]
5334+
wallet_utxo_source: Arc::new(test_utils::TestWalletUtxoSource::new()),
5335+
};
53235336
let mut node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
53245337
node_cfgs.remove(0);
53255338
node_cfgs.insert(0, node);

lightning/src/ln/monitor_tests.rs

+158-59
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::chain::channelmonitor::{ANTI_REORG_DELAY, Balance};
1717
use crate::chain::transaction::OutPoint;
1818
use crate::chain::chaininterface::LowerBoundedFeeEstimator;
1919
#[cfg(anchors)]
20-
use crate::events::bump_transaction::BumpTransactionEvent;
20+
use crate::events::bump_transaction::{BumpTransactionEvent, BumpTransactionEventHandler, Wallet, WalletSource};
2121
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason, HTLCDestination};
2222
use crate::ln::channel;
2323
#[cfg(anchors)]
@@ -27,6 +27,8 @@ use crate::ln::channelmanager::ChannelManager;
2727
use crate::ln::channelmanager::{BREAKDOWN_TIMEOUT, PaymentId, RecipientOnionFields};
2828
use crate::ln::msgs::ChannelMessageHandler;
2929
#[cfg(anchors)]
30+
use crate::sync::Arc;
31+
#[cfg(anchors)]
3032
use crate::util::config::UserConfig;
3133
#[cfg(anchors)]
3234
use crate::util::crypto::sign;
@@ -1888,7 +1890,6 @@ fn test_yield_anchors_events() {
18881890
// allowing the consumer to provide additional fees to the commitment transaction to be
18891891
// broadcast. Once the commitment transaction confirms, events for the HTLC resolution should be
18901892
// emitted by LDK, such that the consumer can attach fees to the zero fee HTLC transactions.
1891-
let secp = Secp256k1::new();
18921893
let mut chanmon_cfgs = create_chanmon_cfgs(2);
18931894
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
18941895
let mut anchors_config = UserConfig::default();
@@ -1905,6 +1906,8 @@ fn test_yield_anchors_events() {
19051906

19061907
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
19071908

1909+
*nodes[0].fee_estimator.sat_per_kw.lock().unwrap() *= 2;
1910+
19081911
connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + 1);
19091912
check_closed_broadcast!(&nodes[0], true);
19101913
assert!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().is_empty());
@@ -1914,34 +1917,38 @@ fn test_yield_anchors_events() {
19141917
&LowerBoundedFeeEstimator::new(node_cfgs[0].fee_estimator), &nodes[0].logger
19151918
);
19161919

1920+
let coinbase_tx = Transaction {
1921+
version: 2,
1922+
lock_time: PackedLockTime::ZERO,
1923+
input: vec![TxIn { ..Default::default() }],
1924+
output: vec![TxOut { // UTXO to attach fees to `anchor_tx` and `htlc_txs`
1925+
value: Amount::ONE_BTC.to_sat(),
1926+
script_pubkey: nodes[0].wallet_utxo_source.get_change_script().unwrap(),
1927+
}],
1928+
};
1929+
nodes[0].wallet_utxo_source.add_utxo(
1930+
bitcoin::OutPoint { txid: coinbase_tx.txid(), vout: 0 }, coinbase_tx.output[0].value,
1931+
);
1932+
nodes[0].wallet_utxo_source.add_utxo(
1933+
bitcoin::OutPoint { txid: coinbase_tx.txid(), vout: 1 }, coinbase_tx.output[0].value * 2,
1934+
);
1935+
let wallet = Wallet::new(Arc::clone(&nodes[0].wallet_utxo_source));
1936+
let bump_event_handler = BumpTransactionEventHandler::new(
1937+
nodes[0].tx_broadcaster, &wallet, nodes[0].keys_manager, nodes[0].logger,
1938+
);
1939+
19171940
let mut holder_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
19181941
assert_eq!(holder_events.len(), 1);
1919-
let (commitment_tx, anchor_tx) = match holder_events.pop().unwrap() {
1920-
Event::BumpTransaction(BumpTransactionEvent::ChannelClose { commitment_tx, anchor_descriptor, .. }) => {
1921-
assert_eq!(commitment_tx.input.len(), 1);
1922-
assert_eq!(commitment_tx.output.len(), 6);
1923-
let mut anchor_tx = Transaction {
1924-
version: 2,
1925-
lock_time: PackedLockTime::ZERO,
1926-
input: vec![
1927-
TxIn { previous_output: anchor_descriptor.outpoint, ..Default::default() },
1928-
TxIn { ..Default::default() },
1929-
],
1930-
output: vec![TxOut {
1931-
value: Amount::ONE_BTC.to_sat(),
1932-
script_pubkey: Script::new_op_return(&[]),
1933-
}],
1934-
};
1935-
let signer = nodes[0].keys_manager.derive_channel_keys(
1936-
anchor_descriptor.channel_value_satoshis, &anchor_descriptor.channel_keys_id,
1937-
);
1938-
let funding_sig = signer.sign_holder_anchor_input(&mut anchor_tx, 0, &secp).unwrap();
1939-
anchor_tx.input[0].witness = chan_utils::build_anchor_input_witness(
1940-
&signer.pubkeys().funding_pubkey, &funding_sig
1941-
);
1942-
(commitment_tx, anchor_tx)
1943-
},
1944-
_ => panic!("Unexpected event"),
1942+
let (commitment_tx, anchor_tx) = {
1943+
bump_event_handler.handle_event(&holder_events[0]);
1944+
let mut txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
1945+
assert_eq!(txn.len(), 2);
1946+
let anchor_tx = txn.pop().unwrap();
1947+
let commitment_tx = txn.pop().unwrap();
1948+
assert_eq!(commitment_tx.input.len(), 1);
1949+
assert_eq!(commitment_tx.output.len(), 6);
1950+
check_spends!(anchor_tx, commitment_tx, coinbase_tx);
1951+
(commitment_tx, anchor_tx)
19451952
};
19461953

19471954
mine_transactions(&nodes[0], &[&commitment_tx, &anchor_tx]);
@@ -1960,37 +1967,13 @@ fn test_yield_anchors_events() {
19601967
_ => assert_eq!(holder_events.len(), 2),
19611968
};
19621969
let mut htlc_txs = Vec::with_capacity(2);
1963-
for event in holder_events {
1964-
match event {
1965-
Event::BumpTransaction(BumpTransactionEvent::HTLCResolution { htlc_descriptors, tx_lock_time, .. }) => {
1966-
assert_eq!(htlc_descriptors.len(), 1);
1967-
let htlc_descriptor = &htlc_descriptors[0];
1968-
let signer = nodes[0].keys_manager.derive_channel_keys(
1969-
htlc_descriptor.channel_value_satoshis, &htlc_descriptor.channel_keys_id
1970-
);
1971-
let per_commitment_point = signer.get_per_commitment_point(htlc_descriptor.per_commitment_number, &secp);
1972-
let mut htlc_tx = Transaction {
1973-
version: 2,
1974-
lock_time: tx_lock_time,
1975-
input: vec![
1976-
htlc_descriptor.unsigned_tx_input(), // HTLC input
1977-
TxIn { ..Default::default() } // Fee input
1978-
],
1979-
output: vec![
1980-
htlc_descriptor.tx_output(&per_commitment_point, &secp), // HTLC output
1981-
TxOut { // Fee input change
1982-
value: Amount::ONE_BTC.to_sat(),
1983-
script_pubkey: Script::new_op_return(&[]),
1984-
}
1985-
]
1986-
};
1987-
let our_sig = signer.sign_holder_htlc_transaction(&mut htlc_tx, 0, htlc_descriptor, &secp).unwrap();
1988-
let witness_script = htlc_descriptor.witness_script(&per_commitment_point, &secp);
1989-
htlc_tx.input[0].witness = htlc_descriptor.tx_input_witness(&our_sig, &witness_script);
1990-
htlc_txs.push(htlc_tx);
1991-
},
1992-
_ => panic!("Unexpected event"),
1993-
}
1970+
for event in &holder_events {
1971+
// Ideally we'd use the change UTXO from `anchor_tx` here to not reuse the same UTXO but it
1972+
// doesn't really matter since we're not validating against an actual chain backend anyway.
1973+
bump_event_handler.handle_event(&event);
1974+
let mut txn = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0);
1975+
assert_eq!(txn.len(), 1);
1976+
htlc_txs.push(txn.pop().unwrap());
19941977
}
19951978

19961979
mine_transactions(&nodes[0], &[&htlc_txs[0], &htlc_txs[1]]);
@@ -2353,3 +2336,119 @@ fn test_anchors_aggregated_revoked_htlc_tx() {
23532336
// revoked commitment which Bob has the preimage for.
23542337
assert_eq!(nodes[1].chain_monitor.chain_monitor.get_claimable_balances(&[]).len(), 6);
23552338
}
2339+
2340+
#[cfg(anchors)]
2341+
#[test]
2342+
fn test_anchors_split_htlc_claim() {
2343+
let mut chanmon_cfgs = create_chanmon_cfgs(2);
2344+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
2345+
let mut anchors_config = UserConfig::default();
2346+
anchors_config.channel_handshake_config.announced_channel = true;
2347+
anchors_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
2348+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[Some(anchors_config), Some(anchors_config)]);
2349+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
2350+
2351+
let chan_id = create_announced_chan_between_nodes_with_value(
2352+
&nodes, 0, 1, 1_000_000, 500_000_000
2353+
).2;
2354+
let (payment_preimage_a, payment_hash_a, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
2355+
let (payment_preimage_b, payment_hash_b, _) = route_payment(&nodes[0], &[&nodes[1]], 1_000_000);
2356+
2357+
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
2358+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
2359+
2360+
*nodes[0].fee_estimator.sat_per_kw.lock().unwrap() *= 2;
2361+
*nodes[1].fee_estimator.sat_per_kw.lock().unwrap() *= 2;
2362+
2363+
nodes[1].node.force_close_broadcasting_latest_txn(&chan_id, &nodes[0].node.get_our_node_id()).unwrap();
2364+
check_closed_broadcast!(&nodes[1], true);
2365+
assert_eq!(nodes[1].tx_broadcaster.txn_broadcast().len(), 1);
2366+
2367+
assert!(nodes[0].tx_broadcaster.txn_broadcast().is_empty());
2368+
assert!(nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
2369+
2370+
let mut holder_events = nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events();
2371+
assert_eq!(holder_events.len(), 1);
2372+
let (commitment_tx, anchor_tx) = {
2373+
nodes[1].bump_tx_handler.handle_event(&holder_events[0]);
2374+
let mut txn = nodes[1].tx_broadcaster.txn_broadcast();
2375+
assert_eq!(txn.len(), 2);
2376+
let commitment_tx = txn.remove(0);
2377+
assert_eq!(commitment_tx.input.len(), 1);
2378+
assert_eq!(commitment_tx.output.len(), 6);
2379+
let anchor_tx = txn.remove(0);
2380+
assert_eq!(anchor_tx.input.len(), 2);
2381+
assert_eq!(anchor_tx.output.len(), 1);
2382+
check_spends!(anchor_tx, commitment_tx);
2383+
(commitment_tx, anchor_tx)
2384+
};
2385+
2386+
mine_transactions(&nodes[0], &[&commitment_tx, &anchor_tx]);
2387+
mine_transactions(&nodes[1], &[&commitment_tx, &anchor_tx]);
2388+
2389+
connect_blocks(&nodes[0], TEST_FINAL_CLTV);
2390+
connect_blocks(&nodes[1], TEST_FINAL_CLTV);
2391+
2392+
get_monitor!(nodes[1], chan_id).provide_payment_preimage(
2393+
&payment_hash_a, &payment_preimage_a, &node_cfgs[1].tx_broadcaster,
2394+
&LowerBoundedFeeEstimator::new(node_cfgs[1].fee_estimator), &nodes[1].logger
2395+
);
2396+
get_monitor!(nodes[1], chan_id).provide_payment_preimage(
2397+
&payment_hash_b, &payment_preimage_b, &node_cfgs[1].tx_broadcaster,
2398+
&LowerBoundedFeeEstimator::new(node_cfgs[1].fee_estimator), &nodes[1].logger
2399+
);
2400+
2401+
let mut holder_events = nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events();
2402+
assert_eq!(holder_events.len(), 1);
2403+
let aggregate_htlc_preimage_tx = {
2404+
nodes[1].bump_tx_handler.handle_event(&holder_events[0]);
2405+
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
2406+
assert_eq!(txn.len(), 1);
2407+
let tx = txn.pop().unwrap();
2408+
assert_eq!(tx.input.len(), 3);
2409+
assert_eq!(tx.output.len(), 2);
2410+
check_spends!(tx, commitment_tx);
2411+
tx
2412+
};
2413+
2414+
let mut holder_events = nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events();
2415+
assert_eq!(holder_events.len(), 2);
2416+
let split_htlc_timeout_tx = {
2417+
for event in &holder_events {
2418+
nodes[0].bump_tx_handler.handle_event(event);
2419+
}
2420+
let txn = nodes[0].tx_broadcaster.txn_broadcast();
2421+
assert_eq!(txn.len(), 2);
2422+
for tx in &txn {
2423+
assert_eq!(tx.input.len(), 2);
2424+
assert_eq!(tx.output.len(), 1);
2425+
check_spends!(tx, commitment_tx);
2426+
}
2427+
txn
2428+
};
2429+
2430+
mine_transaction(&nodes[0], &split_htlc_timeout_tx[0]);
2431+
mine_transaction(&nodes[1], &split_htlc_timeout_tx[0]);
2432+
2433+
let mut holder_events = nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events();
2434+
assert_eq!(holder_events.len(), 1);
2435+
let split_htlc_preimage_tx = {
2436+
nodes[1].bump_tx_handler.handle_event(&holder_events[0]);
2437+
let mut txn = nodes[0].tx_broadcaster.txn_broadcast();
2438+
assert_eq!(txn.len(), 1);
2439+
let tx = txn.pop().unwrap();
2440+
assert_eq!(tx.input.len(), 2);
2441+
assert_eq!(tx.output.len(), 1);
2442+
check_spends!(tx, commitment_tx);
2443+
tx
2444+
};
2445+
2446+
mine_transaction(&nodes[0], &split_htlc_preimage_tx);
2447+
mine_transaction(&nodes[1], &split_htlc_preimage_tx);
2448+
2449+
connect_blocks(&nodes[0], ANTI_REORG_DELAY - 1);
2450+
connect_blocks(&nodes[1], ANTI_REORG_DELAY - 1);
2451+
2452+
assert!(nodes[0].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
2453+
assert!(nodes[1].chain_monitor.chain_monitor.get_and_clear_pending_events().is_empty());
2454+
}

0 commit comments

Comments
 (0)