@@ -1941,23 +1941,41 @@ pub fn update_nodes_with_chan_announce<'a, 'b, 'c, 'd>(
19411941pub fn do_check_spends < F : Fn ( & bitcoin:: transaction:: OutPoint ) -> Option < TxOut > > (
19421942 tx : & Transaction , get_output : F ,
19431943) {
1944+ let mut p2a_output_below_dust = false ;
1945+ let mut has_p2a_output = false ;
19441946 for outp in tx. output . iter ( ) {
1945- assert ! (
1946- outp. value >= outp. script_pubkey. minimal_non_dust( ) ,
1947- "Spending tx output didn't meet dust limit"
1948- ) ;
1947+ let is_p2a = outp. script_pubkey == crate :: ln:: chan_utils:: shared_anchor_script_pubkey ( ) ;
1948+ has_p2a_output |= is_p2a;
1949+ if outp. value < outp. script_pubkey . minimal_non_dust ( ) {
1950+ if p2a_output_below_dust || !is_p2a {
1951+ panic ! ( "Spending tx output didn't meet dust limit" ) ;
1952+ }
1953+ p2a_output_below_dust = true ;
1954+ } ;
19491955 }
19501956 let mut total_value_in = 0 ;
19511957 for input in tx. input . iter ( ) {
1952- total_value_in += get_output ( & input. previous_output ) . unwrap ( ) . value . to_sat ( ) ;
1958+ let output = get_output ( & input. previous_output ) . unwrap ( ) ;
1959+ if output. script_pubkey == crate :: ln:: chan_utils:: shared_anchor_script_pubkey ( ) {
1960+ assert ! ( input. witness. is_empty( ) ) ;
1961+ }
1962+ total_value_in += output. value . to_sat ( ) ;
19531963 }
19541964 let mut total_value_out = 0 ;
19551965 for output in tx. output . iter ( ) {
19561966 total_value_out += output. value . to_sat ( ) ;
19571967 }
1958- let min_fee = ( tx. weight ( ) . to_wu ( ) as u64 + 3 ) / 4 ; // One sat per vbyte (ie per weight/4, rounded up)
1959- // Input amount - output amount = fee, so check that out + min_fee is smaller than input
1960- assert ! ( total_value_out + min_fee <= total_value_in) ;
1968+ if p2a_output_below_dust {
1969+ assert_eq ! (
1970+ total_value_in, total_value_out,
1971+ "Spending tx has one output below dust, while not zero fee"
1972+ ) ;
1973+ // 0FC commitment transactions will have their fee bumped by a child, so don't require that
1974+ // they meet the 1sat/vB minimum.
1975+ } else if !has_p2a_output {
1976+ let min_fee = ( tx. weight ( ) . to_wu ( ) as u64 + 3 ) / 4 ; // One sat per vbyte (ie per weight/4, rounded up)
1977+ assert ! ( total_value_out + min_fee <= total_value_in) ;
1978+ }
19611979 tx. verify ( get_output) . unwrap ( ) ;
19621980}
19631981
@@ -1966,8 +1984,15 @@ macro_rules! check_spends {
19661984 ( $tx: expr, $( $spends_txn: expr) ,* ) => {
19671985 {
19681986 $(
1987+ let mut single_output_below_dust = false ;
19691988 for outp in $spends_txn. output. iter( ) {
1970- assert!( outp. value >= outp. script_pubkey. minimal_non_dust( ) , "Input tx output didn't meet dust limit" ) ;
1989+ if outp. value < outp. script_pubkey. minimal_non_dust( ) {
1990+ if single_output_below_dust || outp. script_pubkey != $crate:: ln:: chan_utils:: shared_anchor_script_pubkey( ) {
1991+ panic!( "Input tx output didn't meet dust limit" ) ;
1992+ } else {
1993+ single_output_below_dust = true ;
1994+ }
1995+ }
19711996 }
19721997 ) *
19731998 let get_output = |out_point: & bitcoin:: transaction:: OutPoint | {
0 commit comments