From 71e8f238334806a488805ea2d094523111d9ca59 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Fri, 9 Sep 2022 15:04:53 +0200 Subject: [PATCH 1/3] fix fee estimate --- .../src/output_manager_service/service.rs | 23 +++++++++++++++++-- .../output_manager_service_tests/service.rs | 6 ++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/base_layer/wallet/src/output_manager_service/service.rs b/base_layer/wallet/src/output_manager_service/service.rs index d5bf4dd067..b2d344b66e 100644 --- a/base_layer/wallet/src/output_manager_service/service.rs +++ b/base_layer/wallet/src/output_manager_service/service.rs @@ -865,7 +865,7 @@ where Covenant::new().consensus_encode_exact_size(), ); - let utxo_selection = self + let utxo_selection = match self .select_utxos( amount, selection_criteria, @@ -873,7 +873,26 @@ where num_outputs, metadata_byte_size * num_outputs, ) - .await?; + .await + { + Ok(v) => Ok(v), + Err(OutputManagerError::FundsPending | OutputManagerError::NotEnoughFunds) => { + debug!( + target: LOG_TARGET, + "We dont have enough funds available to make a fee estimate, so we estimate 1 input, no change" + ); + let fee_calc = self.get_fee_calc(); + let output_features_estimate = OutputFeatures::default(); + let default_metadata_size = fee_calc.weighting().round_up_metadata_size( + output_features_estimate.consensus_encode_exact_size() + + Covenant::new().consensus_encode_exact_size() + + script![Nop].consensus_encode_exact_size(), + ); + let fee = fee_calc.calculate(fee_per_gram, 1, 1, num_outputs, default_metadata_size); + return Ok(Fee::normalize(fee)); + }, + Err(e) => Err(e), + }?; debug!(target: LOG_TARGET, "{} utxos selected.", utxo_selection.utxos.len()); diff --git a/base_layer/wallet/tests/output_manager_service_tests/service.rs b/base_layer/wallet/tests/output_manager_service_tests/service.rs index de60490199..4ce176e172 100644 --- a/base_layer/wallet/tests/output_manager_service_tests/service.rs +++ b/base_layer/wallet/tests/output_manager_service_tests/service.rs @@ -397,7 +397,7 @@ async fn fee_estimate() { } // not enough funds - let err = oms + let fee = oms .output_manager_handle .fee_estimate( MicroTari::from(2750), @@ -407,8 +407,8 @@ async fn fee_estimate() { 1, ) .await - .unwrap_err(); - assert!(matches!(err, OutputManagerError::NotEnoughFunds)); + .unwrap(); + assert_eq!(fee, MicroTari::from(360)); } #[allow(clippy::identity_op)] From a4c85a56f26225c1017608455a2aee0d0dd65ef6 Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Mon, 12 Sep 2022 15:22:24 +0200 Subject: [PATCH 2/3] fix test --- .../output_manager_service_tests/service.rs | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/base_layer/wallet/tests/output_manager_service_tests/service.rs b/base_layer/wallet/tests/output_manager_service_tests/service.rs index 4ce176e172..1c9b58dca8 100644 --- a/base_layer/wallet/tests/output_manager_service_tests/service.rs +++ b/base_layer/wallet/tests/output_manager_service_tests/service.rs @@ -496,23 +496,21 @@ async fn test_utxo_selection_no_chain_metadata() { let expected_fee = fee_calc.calculate(fee_per_gram, 1, 1, 3, default_metadata_byte_size() * 3); assert_eq!(fee, expected_fee); - // test if a fee estimate would be possible with pending funds included - // at this point 52000 uT is still spendable, with pending change incoming of 1690 uT - // so instead of returning "not enough funds".to_string(), return "funds pending" + let spendable_amount = (3..=10).sum::() * amount; - let err = oms + let fee = oms .fee_estimate(spendable_amount, UtxoSelectionCriteria::default(), fee_per_gram, 1, 2) .await - .unwrap_err(); - assert!(matches!(err, OutputManagerError::FundsPending)); + .unwrap(); + assert_eq!(fee,MicroTari::from(250)); + - // test not enough funds let broke_amount = spendable_amount + MicroTari::from(2000); - let err = oms + let fee = oms .fee_estimate(broke_amount, UtxoSelectionCriteria::default(), fee_per_gram, 1, 2) .await - .unwrap_err(); - assert!(matches!(err, OutputManagerError::NotEnoughFunds)); + .unwrap(); + assert_eq!(fee,MicroTari::from(250)); // coin split uses the "Largest" selection strategy let (_, tx, utxos_total_value) = oms.create_coin_split(vec![], amount, 5, fee_per_gram).await.unwrap(); @@ -593,14 +591,12 @@ async fn test_utxo_selection_with_chain_metadata() { let expected_fee = fee_calc.calculate(fee_per_gram, 1, 2, 3, default_metadata_byte_size() * 3); assert_eq!(fee, expected_fee); - // test fee estimates are maturity aware - // even though we have utxos for the fee, they can't be spent because they are not mature yet let spendable_amount = (1..=6).sum::() * amount; - let err = oms + let fee = oms .fee_estimate(spendable_amount, UtxoSelectionCriteria::default(), fee_per_gram, 1, 2) .await - .unwrap_err(); - assert!(matches!(err, OutputManagerError::NotEnoughFunds)); + .unwrap(); + assert_eq!(fee,MicroTari::from(250)); // test coin split is maturity aware let (_, tx, utxos_total_value) = oms.create_coin_split(vec![], amount, 5, fee_per_gram).await.unwrap(); From eaf2cae61e76af50c85447f2ea41a58fc74e801c Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Mon, 12 Sep 2022 15:54:49 +0200 Subject: [PATCH 3/3] fmt --- .../wallet/tests/output_manager_service_tests/service.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/base_layer/wallet/tests/output_manager_service_tests/service.rs b/base_layer/wallet/tests/output_manager_service_tests/service.rs index 1c9b58dca8..bb2d5e5e30 100644 --- a/base_layer/wallet/tests/output_manager_service_tests/service.rs +++ b/base_layer/wallet/tests/output_manager_service_tests/service.rs @@ -496,21 +496,19 @@ async fn test_utxo_selection_no_chain_metadata() { let expected_fee = fee_calc.calculate(fee_per_gram, 1, 1, 3, default_metadata_byte_size() * 3); assert_eq!(fee, expected_fee); - let spendable_amount = (3..=10).sum::() * amount; let fee = oms .fee_estimate(spendable_amount, UtxoSelectionCriteria::default(), fee_per_gram, 1, 2) .await .unwrap(); - assert_eq!(fee,MicroTari::from(250)); - + assert_eq!(fee, MicroTari::from(250)); let broke_amount = spendable_amount + MicroTari::from(2000); let fee = oms .fee_estimate(broke_amount, UtxoSelectionCriteria::default(), fee_per_gram, 1, 2) .await .unwrap(); - assert_eq!(fee,MicroTari::from(250)); + assert_eq!(fee, MicroTari::from(250)); // coin split uses the "Largest" selection strategy let (_, tx, utxos_total_value) = oms.create_coin_split(vec![], amount, 5, fee_per_gram).await.unwrap(); @@ -596,7 +594,7 @@ async fn test_utxo_selection_with_chain_metadata() { .fee_estimate(spendable_amount, UtxoSelectionCriteria::default(), fee_per_gram, 1, 2) .await .unwrap(); - assert_eq!(fee,MicroTari::from(250)); + assert_eq!(fee, MicroTari::from(250)); // test coin split is maturity aware let (_, tx, utxos_total_value) = oms.create_coin_split(vec![], amount, 5, fee_per_gram).await.unwrap();