@@ -41,6 +41,8 @@ use bitcoin::blockdata::script::Builder;
41
41
use bitcoin::blockdata::opcodes;
42
42
use bitcoin::blockdata::constants::genesis_block;
43
43
use bitcoin::network::constants::Network;
44
+ use bitcoin::{Transaction, TxIn, TxOut, Witness};
45
+ use bitcoin::OutPoint as BitcoinOutPoint;
44
46
45
47
use bitcoin::secp256k1::Secp256k1;
46
48
use bitcoin::secp256k1::{PublicKey,SecretKey};
@@ -10329,3 +10331,45 @@ fn test_max_dust_htlc_exposure() {
10329
10331
do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, false);
10330
10332
do_test_max_dust_htlc_exposure(false, ExposureEvent::AtUpdateFeeOutbound, true);
10331
10333
}
10334
+
10335
+ #[test]
10336
+ fn test_non_final_funding_tx() {
10337
+ let chanmon_cfgs = create_chanmon_cfgs(2);
10338
+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
10339
+ let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
10340
+ let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
10341
+
10342
+ let temp_channel_id = nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100_000, 0, 42, None).unwrap();
10343
+ let open_channel_message = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
10344
+ nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_channel_message);
10345
+ let accept_channel_message = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
10346
+ nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel_message);
10347
+
10348
+ let best_height = nodes[0].node.best_block.read().unwrap().height();
10349
+
10350
+ let chan_id = *nodes[0].network_chan_count.borrow();
10351
+ let events = nodes[0].node.get_and_clear_pending_events();
10352
+ let input = TxIn { previous_output: BitcoinOutPoint::null(), script_sig: bitcoin::Script::new(), sequence: 0x1, witness: Witness::from_vec(vec!(vec!(1))) };
10353
+ assert_eq!(events.len(), 1);
10354
+ let mut tx = match events[0] {
10355
+ Event::FundingGenerationReady { ref channel_value_satoshis, ref output_script, .. } => {
10356
+ // Timelock the transaction _beyond_ the best client height + 2.
10357
+ Transaction { version: chan_id as i32, lock_time: best_height + 3, input: vec![input], output: vec![TxOut {
10358
+ value: *channel_value_satoshis, script_pubkey: output_script.clone(),
10359
+ }]}
10360
+ },
10361
+ _ => panic!("Unexpected event"),
10362
+ };
10363
+ // Transaction should fail as it's evaluated as non-final for propagation.
10364
+ match nodes[0].node.funding_transaction_generated(&temp_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()) {
10365
+ Err(APIError::APIMisuseError { err }) => {
10366
+ assert_eq!(format!("Funding transaction absolute timelock is non-final"), err);
10367
+ },
10368
+ _ => panic!()
10369
+ }
10370
+
10371
+ // However, transaction should be accepted if it's in a +2 headroom from best block.
10372
+ tx.lock_time -= 1;
10373
+ assert!(nodes[0].node.funding_transaction_generated(&temp_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).is_ok());
10374
+ nodes[0].node.get_and_clear_pending_msg_events();
10375
+ }
0 commit comments