From 3219926258a4a7651abab105d843599574e1ccfc Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 18 Sep 2020 18:28:19 -0400 Subject: [PATCH] Test that txn pay at least a minimum relay fee in functional tests This also pays a fee on the transactions we generate in response to SpendableOutputDescriptors in tests. This fixes the known issues in #630, though we should test for standardness in other ways as well. --- lightning/src/ln/functional_test_utils.rs | 16 ++++++++++++++-- lightning/src/ln/functional_tests.rs | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 366627b65..7d54b6a92 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -505,14 +505,26 @@ pub fn create_announced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: &'a macro_rules! check_spends { ($tx: expr, $($spends_txn: expr),*) => { { - $tx.verify(|out_point| { + let get_output = |out_point: &bitcoin::blockdata::transaction::OutPoint| { $( if out_point.txid == $spends_txn.txid() { return $spends_txn.output.get(out_point.vout as usize).cloned() } )* None - }).unwrap(); + }; + let mut total_value_in = 0; + for input in $tx.input.iter() { + total_value_in += get_output(&input.previous_output).unwrap().value; + } + let mut total_value_out = 0; + for output in $tx.output.iter() { + total_value_out += output.value; + } + let min_fee = ($tx.get_weight() as u64 + 3) / 4; // One sat per vbyte (ie per weight/4, rounded up) + // Input amount - output amount = fee, so check that out + min_fee is smaller than input + assert!(total_value_out + min_fee <= total_value_in); + $tx.verify(get_output).unwrap(); } } } diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index c71811fa8..c94b220ce 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -4708,6 +4708,7 @@ macro_rules! check_spendable_outputs { input: vec![input], output: vec![outp], }; + spend_tx.output[0].value -= (spend_tx.get_weight() + 2 + 1 + 73 + 35 + 3) as u64 / 4; // (Max weight + 3 (to round up)) / 4 let secp_ctx = Secp256k1::new(); let keys = $keysinterface.derive_channel_keys($chan_value, key_derivation_params.0, key_derivation_params.1); let remotepubkey = keys.pubkeys().payment_point; @@ -4742,6 +4743,7 @@ macro_rules! check_spendable_outputs { let delayed_payment_pubkey = PublicKey::from_secret_key(&secp_ctx, &delayed_payment_key); let witness_script = chan_utils::get_revokeable_redeemscript(revocation_pubkey, *to_self_delay, &delayed_payment_pubkey); + spend_tx.output[0].value -= (spend_tx.get_weight() + 2 + 1 + 73 + 1 + witness_script.len() + 1 + 3) as u64 / 4; // (Max weight + 3 (to round up)) / 4 let sighash = Message::from_slice(&bip143::SigHashCache::new(&spend_tx).signature_hash(0, &witness_script, output.value, SigHashType::All)[..]).unwrap(); let local_delayedsig = secp_ctx.sign(&sighash, &delayed_payment_key); spend_tx.input[0].witness.push(local_delayedsig.serialize_der().to_vec()); @@ -4769,6 +4771,7 @@ macro_rules! check_spendable_outputs { input: vec![input], output: vec![outp.clone()], }; + spend_tx.output[0].value -= (spend_tx.get_weight() + 2 + 1 + 73 + 35 + 3) as u64 / 4; // (Max weight + 3 (to round up)) / 4 let secret = { match ExtendedPrivKey::new_master(Network::Testnet, &$node.node_seed) { Ok(master_key) => { -- 2.39.5