@@ -6497,8 +6497,7 @@ fn get_v2_channel_reserve_satoshis(channel_value_satoshis: u64, dust_limit_satos
64976497fn check_splice_contribution_sufficient(
64986498 contribution: &SpliceContribution, is_initiator: bool, funding_feerate: FeeRate,
64996499) -> Result<SignedAmount, String> {
6500- let contribution_amount = contribution.value();
6501- if contribution_amount < SignedAmount::ZERO {
6500+ if contribution.inputs().is_empty() {
65026501 let estimated_fee = Amount::from_sat(estimate_v2_funding_transaction_fee(
65036502 contribution.inputs(),
65046503 contribution.outputs(),
@@ -6507,20 +6506,26 @@ fn check_splice_contribution_sufficient(
65076506 funding_feerate.to_sat_per_kwu() as u32,
65086507 ));
65096508
6509+ let contribution_amount = contribution.net_value();
65106510 contribution_amount
65116511 .checked_sub(
65126512 estimated_fee.to_signed().expect("fees should never exceed Amount::MAX_MONEY"),
65136513 )
6514- .ok_or(format!("Our {contribution_amount} contribution plus the fee estimate exceeds the total bitcoin supply"))
6514+ .ok_or(format!(
6515+ "{} splice-out amount plus {} fee estimate exceeds the total bitcoin supply",
6516+ contribution_amount.unsigned_abs(),
6517+ estimated_fee,
6518+ ))
65156519 } else {
65166520 check_v2_funding_inputs_sufficient(
6517- contribution_amount.to_sat (),
6521+ contribution.input_value (),
65186522 contribution.inputs(),
6523+ contribution.outputs(),
65196524 is_initiator,
65206525 true,
65216526 funding_feerate.to_sat_per_kwu() as u32,
65226527 )
6523- .map(|_| contribution_amount )
6528+ .map(|_| contribution.net_value() )
65246529 }
65256530}
65266531
@@ -6579,16 +6584,16 @@ fn estimate_v2_funding_transaction_fee(
65796584/// Returns estimated (partial) fees as additional information
65806585#[rustfmt::skip]
65816586fn check_v2_funding_inputs_sufficient(
6582- contribution_amount: i64 , funding_inputs: &[FundingTxInput], is_initiator: bool ,
6583- is_splice: bool, funding_feerate_sat_per_1000_weight: u32,
6584- ) -> Result<u64 , String> {
6585- let estimated_fee = estimate_v2_funding_transaction_fee(
6586- funding_inputs, &[] , is_initiator, is_splice, funding_feerate_sat_per_1000_weight,
6587- );
6588-
6589- let mut total_input_sats = 0u64 ;
6587+ contributed_input_value: Amount , funding_inputs: &[FundingTxInput], outputs: &[TxOut] ,
6588+ is_initiator: bool, is_splice: bool, funding_feerate_sat_per_1000_weight: u32,
6589+ ) -> Result<Amount , String> {
6590+ let estimated_fee = Amount::from_sat( estimate_v2_funding_transaction_fee(
6591+ funding_inputs, outputs , is_initiator, is_splice, funding_feerate_sat_per_1000_weight,
6592+ )) ;
6593+
6594+ let mut total_input_value = Amount::ZERO ;
65906595 for FundingTxInput { utxo, .. } in funding_inputs.iter() {
6591- total_input_sats = total_input_sats .checked_add(utxo.output.value.to_sat() )
6596+ total_input_value = total_input_value .checked_add(utxo.output.value)
65926597 .ok_or("Sum of input values is greater than the total bitcoin supply")?;
65936598 }
65946599
@@ -6603,13 +6608,11 @@ fn check_v2_funding_inputs_sufficient(
66036608 // TODO(splicing): refine check including the fact wether a change will be added or not.
66046609 // Can be done once dual funding preparation is included.
66056610
6606- let minimal_input_amount_needed = contribution_amount.checked_add(estimated_fee as i64)
6607- .ok_or(format!("Our {contribution_amount} contribution plus the fee estimate exceeds the total bitcoin supply"))?;
6608- if i64::try_from(total_input_sats).map_err(|_| "Sum of input values is greater than the total bitcoin supply")?
6609- < minimal_input_amount_needed
6610- {
6611+ let minimal_input_amount_needed = contributed_input_value.checked_add(estimated_fee)
6612+ .ok_or(format!("{contributed_input_value} contribution plus {estimated_fee} fee estimate exceeds the total bitcoin supply"))?;
6613+ if total_input_value < minimal_input_amount_needed {
66116614 Err(format!(
6612- "Total input amount {total_input_sats } is lower than needed for contribution {contribution_amount }, considering fees of {estimated_fee}. Need more inputs.",
6615+ "Total input amount {total_input_value } is lower than needed for splice-in contribution {contributed_input_value }, considering fees of {estimated_fee}. Need more inputs.",
66136616 ))
66146617 } else {
66156618 Ok(estimated_fee)
@@ -6675,7 +6678,7 @@ impl FundingNegotiationContext {
66756678 };
66766679
66776680 // Optionally add change output
6678- let change_value_opt = if self.our_funding_contribution > SignedAmount::ZERO {
6681+ let change_value_opt = if ! self.our_funding_inputs.is_empty() {
66796682 match calculate_change_output_value(
66806683 &self,
66816684 self.shared_funding_input.is_some(),
@@ -11956,7 +11959,7 @@ where
1195611959 });
1195711960 }
1195811961
11959- let our_funding_contribution = contribution.value ();
11962+ let our_funding_contribution = contribution.net_value ();
1196011963 if our_funding_contribution == SignedAmount::ZERO {
1196111964 return Err(APIError::APIMisuseError {
1196211965 err: format!(
@@ -18254,6 +18257,13 @@ mod tests {
1825418257 FundingTxInput::new_p2wpkh(prevtx, 0).unwrap()
1825518258 }
1825618259
18260+ fn funding_output_sats(output_value_sats: u64) -> TxOut {
18261+ TxOut {
18262+ value: Amount::from_sat(output_value_sats),
18263+ script_pubkey: ScriptBuf::new_p2wpkh(&WPubkeyHash::all_zeros()),
18264+ }
18265+ }
18266+
1825718267 #[test]
1825818268 #[rustfmt::skip]
1825918269 fn test_check_v2_funding_inputs_sufficient() {
@@ -18264,16 +18274,83 @@ mod tests {
1826418274 let expected_fee = if cfg!(feature = "grind_signatures") { 2278 } else { 2284 };
1826518275 assert_eq!(
1826618276 check_v2_funding_inputs_sufficient(
18267- 220_000,
18277+ Amount::from_sat(220_000),
18278+ &[
18279+ funding_input_sats(200_000),
18280+ funding_input_sats(100_000),
18281+ ],
18282+ &[],
18283+ true,
18284+ true,
18285+ 2000,
18286+ ).unwrap(),
18287+ Amount::from_sat(expected_fee),
18288+ );
18289+ }
18290+
18291+ // Net splice-in
18292+ {
18293+ let expected_fee = if cfg!(feature = "grind_signatures") { 2526 } else { 2532 };
18294+ assert_eq!(
18295+ check_v2_funding_inputs_sufficient(
18296+ Amount::from_sat(220_000),
18297+ &[
18298+ funding_input_sats(200_000),
18299+ funding_input_sats(100_000),
18300+ ],
18301+ &[
18302+ funding_output_sats(200_000),
18303+ ],
18304+ true,
18305+ true,
18306+ 2000,
18307+ ).unwrap(),
18308+ Amount::from_sat(expected_fee),
18309+ );
18310+ }
18311+
18312+ // Net splice-out
18313+ {
18314+ let expected_fee = if cfg!(feature = "grind_signatures") { 2526 } else { 2532 };
18315+ assert_eq!(
18316+ check_v2_funding_inputs_sufficient(
18317+ Amount::from_sat(220_000),
1826818318 &[
1826918319 funding_input_sats(200_000),
1827018320 funding_input_sats(100_000),
1827118321 ],
18322+ &[
18323+ funding_output_sats(400_000),
18324+ ],
1827218325 true,
1827318326 true,
1827418327 2000,
1827518328 ).unwrap(),
18276- expected_fee,
18329+ Amount::from_sat(expected_fee),
18330+ );
18331+ }
18332+
18333+ // Net splice-out, inputs insufficient to cover fees
18334+ {
18335+ let expected_fee = if cfg!(feature = "grind_signatures") { 113670 } else { 113940 };
18336+ assert_eq!(
18337+ check_v2_funding_inputs_sufficient(
18338+ Amount::from_sat(220_000),
18339+ &[
18340+ funding_input_sats(200_000),
18341+ funding_input_sats(100_000),
18342+ ],
18343+ &[
18344+ funding_output_sats(400_000),
18345+ ],
18346+ true,
18347+ true,
18348+ 90000,
18349+ ),
18350+ Err(format!(
18351+ "Total input amount 0.00300000 BTC is lower than needed for splice-in contribution 0.00220000 BTC, considering fees of {}. Need more inputs.",
18352+ Amount::from_sat(expected_fee),
18353+ )),
1827718354 );
1827818355 }
1827918356
@@ -18282,17 +18359,18 @@ mod tests {
1828218359 let expected_fee = if cfg!(feature = "grind_signatures") { 1736 } else { 1740 };
1828318360 assert_eq!(
1828418361 check_v2_funding_inputs_sufficient(
18285- 220_000,
18362+ Amount::from_sat( 220_000) ,
1828618363 &[
1828718364 funding_input_sats(100_000),
1828818365 ],
18366+ &[],
1828918367 true,
1829018368 true,
1829118369 2000,
1829218370 ),
1829318371 Err(format!(
18294- "Total input amount 100000 is lower than needed for contribution 220000 , considering fees of {}. Need more inputs.",
18295- expected_fee,
18372+ "Total input amount 0.00100000 BTC is lower than needed for splice-in contribution 0.00220000 BTC , considering fees of {}. Need more inputs.",
18373+ Amount::from_sat( expected_fee) ,
1829618374 )),
1829718375 );
1829818376 }
@@ -18302,16 +18380,17 @@ mod tests {
1830218380 let expected_fee = if cfg!(feature = "grind_signatures") { 2278 } else { 2284 };
1830318381 assert_eq!(
1830418382 check_v2_funding_inputs_sufficient(
18305- (300_000 - expected_fee - 20) as i64 ,
18383+ Amount::from_sat (300_000 - expected_fee - 20),
1830618384 &[
1830718385 funding_input_sats(200_000),
1830818386 funding_input_sats(100_000),
1830918387 ],
18388+ &[],
1831018389 true,
1831118390 true,
1831218391 2000,
1831318392 ).unwrap(),
18314- expected_fee,
18393+ Amount::from_sat( expected_fee) ,
1831518394 );
1831618395 }
1831718396
@@ -18320,18 +18399,19 @@ mod tests {
1832018399 let expected_fee = if cfg!(feature = "grind_signatures") { 2506 } else { 2513 };
1832118400 assert_eq!(
1832218401 check_v2_funding_inputs_sufficient(
18323- 298032,
18402+ Amount::from_sat( 298032) ,
1832418403 &[
1832518404 funding_input_sats(200_000),
1832618405 funding_input_sats(100_000),
1832718406 ],
18407+ &[],
1832818408 true,
1832918409 true,
1833018410 2200,
1833118411 ),
1833218412 Err(format!(
18333- "Total input amount 300000 is lower than needed for contribution 298032 , considering fees of {}. Need more inputs.",
18334- expected_fee
18413+ "Total input amount 0.00300000 BTC is lower than needed for splice-in contribution 0.00298032 BTC , considering fees of {}. Need more inputs.",
18414+ Amount::from_sat( expected_fee),
1833518415 )),
1833618416 );
1833718417 }
@@ -18341,16 +18421,17 @@ mod tests {
1834118421 let expected_fee = if cfg!(feature = "grind_signatures") { 1084 } else { 1088 };
1834218422 assert_eq!(
1834318423 check_v2_funding_inputs_sufficient(
18344- (300_000 - expected_fee - 20) as i64 ,
18424+ Amount::from_sat (300_000 - expected_fee - 20),
1834518425 &[
1834618426 funding_input_sats(200_000),
1834718427 funding_input_sats(100_000),
1834818428 ],
18429+ &[],
1834918430 false,
1835018431 false,
1835118432 2000,
1835218433 ).unwrap(),
18353- expected_fee,
18434+ Amount::from_sat( expected_fee) ,
1835418435 );
1835518436 }
1835618437 }
0 commit comments