Implement amount check
MODIFY
HiddenWallet.ChaumianTumbler/Configuration/Config.cs
HiddenWallet.ChaumianTumbler/Configuration/Config.cs
@@ -61,6 +61,9 @@ namespace HiddenWallet.ChaumianTumbler.Configuration
[JsonProperty(PropertyName = "MaximumInputsPerAlices")]
public int? MaximumInputsPerAlices { get; private set; }
+ [JsonProperty(PropertyName = "FallBackSatoshiFeePerBytes")]
+ public int? FallBackSatoshiFeePerBytes { get; private set; }
+
public Config()
{
@@ -95,6 +98,7 @@ namespace HiddenWallet.ChaumianTumbler.Configuration
OutputRegistrationPhaseTimeoutInSeconds = 60;
SigningPhaseTimeoutInSeconds = 60;
MaximumInputsPerAlices = 7;
+ FallBackSatoshiFeePerBytes = 300;
if (!File.Exists(path))
{
@@ -119,6 +123,7 @@ namespace HiddenWallet.ChaumianTumbler.Configuration
OutputRegistrationPhaseTimeoutInSeconds = config.OutputRegistrationPhaseTimeoutInSeconds ?? OutputRegistrationPhaseTimeoutInSeconds;
SigningPhaseTimeoutInSeconds = config.SigningPhaseTimeoutInSeconds ?? SigningPhaseTimeoutInSeconds;
MaximumInputsPerAlices = config.MaximumInputsPerAlices ?? MaximumInputsPerAlices;
+ FallBackSatoshiFeePerBytes = config.FallBackSatoshiFeePerBytes ?? FallBackSatoshiFeePerBytes;
}
await ToFileAsync(path, cancel);

MODIFY
HiddenWallet.ChaumianTumbler/Controllers/TumblerController.cs
HiddenWallet.ChaumianTumbler/Controllers/TumblerController.cs
@@ -55,7 +55,9 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
Denomination = Global.StateMachine.Denomination.ToString(fplus: false, trimExcessZero: true),
AnonymitySet = Global.StateMachine.AnonymitySet,
TimeSpentInInputRegistrationInSeconds = (int)Global.StateMachine.TimeSpentInInputRegistration.TotalSeconds,
- MaximumInputsPerAlices = (int)Global.Config.MaximumInputsPerAlices
+ MaximumInputsPerAlices = (int)Global.Config.MaximumInputsPerAlices,
+ FeePerInputs = Global.StateMachine.FeePerInputs.ToString(fplus: false, trimExcessZero: true),
+ FeePerOutputs = Global.StateMachine.FeePerOutputs.ToString(fplus: false, trimExcessZero: true),
});
}
catch (Exception ex)
@@ -113,6 +115,17 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
}
// Check if inputs have enough coins
+ Money amount = Money.Zero;
+ foreach(Money val in inputs.Select(x=>x.Value))
+ {
+ amount += val;
+ }
+ Money feeToPay = (inputs.Count() * Global.StateMachine.FeePerInputs + 2 * Global.StateMachine.FeePerOutputs);
+ if (amount < Global.StateMachine.Denomination + feeToPay)
+ {
+ throw new ArgumentException("Total provided inputs must be > denomination + fee");
+ }
+
// Check if inputs are confirmed or part of previous CoinJoin
// only enable requests in specific phases

MODIFY
HiddenWallet.ChaumianTumbler/Models/StatusResponse.cs
HiddenWallet.ChaumianTumbler/Models/StatusResponse.cs
@@ -13,6 +13,8 @@ namespace HiddenWallet.ChaumianTumbler.Models
public string Denomination { get; set; }
public int AnonymitySet { get; set; }
public int TimeSpentInInputRegistrationInSeconds { get; set; }
- public int MaximumInputsPerAlices { get; internal set; }
+ public int MaximumInputsPerAlices { get; set; }
+ public string FeePerInputs { get; set; }
+ public string FeePerOutputs { get; set; }
}
}

MODIFY
HiddenWallet.FullSpvWallet/WalletJob.cs
HiddenWallet.FullSpvWallet/WalletJob.cs
@@ -22,6 +22,7 @@ using HiddenWallet.FullSpv.MemPool;
using HiddenWallet.FullSpv.Fees;
using Nito.AsyncEx;
using HiddenWallet.WebClients.SmartBit;
+using HiddenWallet.Helpers;
namespace HiddenWallet.FullSpv
{
@@ -956,7 +957,7 @@ namespace HiddenWallet.FullSpv
}
else
{
- const int expectedMinTxSize = 1 * 41 + 1 * 33 + 10;
+ const int expectedMinTxSize = 1 * Constants.P2wpkhInputSizeInBytes + 1 * Constants.OutputSizeInBytes + 10;
try
{
inNum = SelectCoinsToSpend(unspentCoins, amount + feePerBytes * expectedMinTxSize).Count;
@@ -970,8 +971,8 @@ namespace HiddenWallet.FullSpv
// https://bitcoincore.org/en/segwit_wallet_dev/#transaction-fee-estimation
// https://bitcoin.stackexchange.com/a/46379/26859
int outNum = spendAll ? 1 : 2; // 1 address to send + 1 for change
- var origTxSize = inNum * 146 + outNum * 33 + 10;
- var newTxSize = inNum * 41 + outNum * 33 + 10; // BEWARE: This assumes segwit only inputs!
+ var origTxSize = inNum * Constants.P2pkhInputSizeInBytes + outNum * Constants.OutputSizeInBytes + 10;
+ var newTxSize = inNum * Constants.P2wpkhInputSizeInBytes + outNum * Constants.OutputSizeInBytes + 10; // BEWARE: This assumes segwit only inputs!
var vSize = (int)Math.Ceiling(((3 * newTxSize) + origTxSize) / 4m);
Debug.WriteLine($"Estimated tx size: {vSize} bytes");
Money fee = feePerBytes * vSize;

Implement amount check