fix fee percent calculation
MODIFY
WalletWasabi.Gui/Controls/WalletExplorer/TransactionViewerViewModel.cs
WalletWasabi.Gui/Controls/WalletExplorer/TransactionViewerViewModel.cs
@@ -11,6 +11,7 @@ using System.Reactive.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using WalletWasabi.Models;
+using WalletWasabi.Models.TransactionBuilding;
namespace WalletWasabi.Gui.Controls.WalletExplorer
{

MODIFY
WalletWasabi.Tests/RegTests.cs
WalletWasabi.Tests/RegTests.cs
@@ -1166,22 +1166,46 @@ namespace WalletWasabi.Tests
// covers:
// customchange
// feePc > 1
+ var k1 = new Key();
+ var k2 = new Key();
res = wallet.BuildTransaction(
password,
new PaymentIntent(
- new DestinationRequest(new Key(), MoneyRequest.CreateAllRemaining()),
- new DestinationRequest(new Key(), Money.Coins(0.0003m), "outgoing")),
+ new DestinationRequest(k1, MoneyRequest.CreateAllRemaining()),
+ new DestinationRequest(k2, Money.Coins(0.0003m), "outgoing")),
+ 2);
+
+ Assert.Contains(k1.ScriptPubKey, res.OuterWalletOutputs.Select(x => x.ScriptPubKey));
+ Assert.Contains(k2.ScriptPubKey, res.OuterWalletOutputs.Select(x => x.ScriptPubKey));
+
+ #endregion CustomChange
+
+ #region FeePcHigh
+
+ res = wallet.BuildTransaction(
+ password,
+ new PaymentIntent(new Key(), Money.Coins(0.0003m), "outgoing"),
2);
Assert.True(res.FeePercentOfSent > 1);
- Logger.LogDebug<RegTests>($"Fee: {res.Fee}");
- Logger.LogDebug<RegTests>($"FeePercentOfSent: {res.FeePercentOfSent} %");
- Logger.LogDebug<RegTests>($"SpendsUnconfirmed: {res.SpendsUnconfirmed}");
- Logger.LogDebug<RegTests>($"Active Output: {activeOutput.Amount.ToString(false, true)} {activeOutput.ScriptPubKey.GetDestinationAddress(network)}");
- Logger.LogDebug<RegTests>($"TxId: {res.Transaction.GetHash()}");
+ var newChangeK = keyManager.GenerateNewKey("foo", KeyState.Clean, isInternal: true);
+ res = wallet.BuildTransaction(
+ password,
+ new PaymentIntent(
+ new DestinationRequest(newChangeK.P2wpkhScript, MoneyRequest.CreateAllRemaining(), "boo"),
+ new DestinationRequest(new Key(), Money.Coins(0.0003m), "outgoing")),
+ 2);
- #endregion CustomChange
+ Assert.True(res.FeePercentOfSent > 1);
+ Assert.Single(res.OuterWalletOutputs);
+ Assert.Single(res.InnerWalletOutputs);
+ SmartCoin changeRes = res.InnerWalletOutputs.Single();
+ Assert.Equal(newChangeK.P2wpkhScript, changeRes.ScriptPubKey);
+ Assert.Equal(newChangeK.Label, changeRes.Label);
+ Assert.Equal(KeyState.Clean, newChangeK.KeyState); // Still clean, because the tx wasn't yet propagated.
+
+ #endregion FeePcHigh
}
finally
{

MODIFY
WalletWasabi/KeyManagement/HdPubKey.cs
WalletWasabi/KeyManagement/HdPubKey.cs
using NBitcoin;
using Newtonsoft.Json;
using System;
+using System.Linq;
using WalletWasabi.Helpers;
using WalletWasabi.JsonConverters;
@@ -114,6 +115,19 @@ namespace WalletWasabi.KeyManagement
public BitcoinScriptAddress GetP2shOverP2wpkhAddress(Network network) => P2wpkhScript.GetScriptAddress(network);
+ public bool ContainsScript(Script scriptPubKey)
+ {
+ var scripts = new[]
+ {
+ P2pkScript,
+ P2pkhScript,
+ P2wpkhScript,
+ P2shOverP2wpkhScript
+ };
+
+ return scripts.Contains(scriptPubKey);
+ }
+
#region Equality
public override bool Equals(object obj) => obj is HdPubKey pubKey && this == pubKey;

RENAME
WalletWasabi/Models/BuildTransactionResult.cs
WalletWasabi/Models/TransactionBuilding/BuildTransactionResult.cs
@@ -2,7 +2,7 @@ using NBitcoin;
using System.Collections.Generic;
using WalletWasabi.Helpers;
-namespace WalletWasabi.Models
+namespace WalletWasabi.Models.TransactionBuilding
{
public class BuildTransactionResult
{

MODIFY
WalletWasabi/Services/WalletService.cs
WalletWasabi/Services/WalletService.cs
@@ -1026,7 +1026,7 @@ namespace WalletWasabi.Services
var corrected = Guard.Correct(item.label);
sb.Append($"{corrected}, ");
}
- changeLabel = sb.ToString().TrimEnd(',', ' ');
+ changeLabel = sb.ToString().Trim(',', ' ');
changeHdPubKey.SetLabel(changeLabel, KeyManager);
}
@@ -1040,18 +1040,29 @@ namespace WalletWasabi.Services
Logger.LogInfo<WalletService>($"Estimated tx size: {vSize} vbytes.");
// 6. Do some checks
- Money totalOutgoingAmountNoFee = realToSend.Select(x => x.amount).Sum();
- if (totalOutgoingAmountNoFee == Money.Zero)
+ Money totalSendAmountNoFee = realToSend.Sum(x => x.amount);
+ if (totalSendAmountNoFee == Money.Zero)
{
throw new InvalidOperationException($"The amount after subtracting the fee is too small to be sent.");
}
- Money totalOutgoingAmount = totalOutgoingAmountNoFee + fee;
- decimal feePc = (100 * fee.ToDecimal(MoneyUnit.BTC)) / totalOutgoingAmountNoFee.ToDecimal(MoneyUnit.BTC);
+ Money totalSendAmount = totalSendAmountNoFee + fee;
+
+ Money totalOutgoingAmountNoFee;
+ if (changeHdPubKey is null)
+ {
+ totalOutgoingAmountNoFee = totalSendAmountNoFee;
+ }
+ else
+ {
+ totalOutgoingAmountNoFee = realToSend.Where(x => !changeHdPubKey.ContainsScript(x.destination.ScriptPubKey)).Sum(x => x.amount);
+ }
+ decimal totalOutgoingAmountNoFeeDecimal = totalOutgoingAmountNoFee.ToDecimal(MoneyUnit.BTC);
+ decimal feePc = (100 * fee.ToDecimal(MoneyUnit.BTC)) / (totalOutgoingAmountNoFeeDecimal == 0 ? decimal.MinValue : totalOutgoingAmountNoFeeDecimal);
if (feePc > 1)
{
- Logger.LogInfo<WalletService>($"The transaction fee is {feePc:0.#}% of your transaction amount.{Environment.NewLine}"
- + $"Sending:\t {totalOutgoingAmount.ToString(fplus: false, trimExcessZero: true)} BTC.{Environment.NewLine}"
+ Logger.LogInfo<WalletService>($"The transaction fee is {totalOutgoingAmountNoFee:0.#}% of your transaction amount.{Environment.NewLine}"
+ + $"Sending:\t {totalSendAmount.ToString(fplus: false, trimExcessZero: true)} BTC.{Environment.NewLine}"
+ $"Fee:\t\t {fee.Satoshi} Satoshi.");
}
if (feePc > 100)

fix fee percent calculation