Enable registe unconfirmed if it spends previous CJ transaction
MODIFY
HiddenWallet.ChaumianTumbler/Controllers/TumblerController.cs
HiddenWallet.ChaumianTumbler/Controllers/TumblerController.cs
@@ -9,6 +9,7 @@ using HiddenWallet.ChaumianCoinJoin;
using Org.BouncyCastle.Utilities.Encoders;
using NBitcoin;
using NBitcoin.RPC;
+using HiddenWallet.ChaumianTumbler.Store;
namespace HiddenWallet.ChaumianTumbler.Controllers
{
@@ -58,6 +59,7 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
MaximumInputsPerAlices = (int)Global.Config.MaximumInputsPerAlices,
FeePerInputs = Global.StateMachine.FeePerInputs.ToString(fplus: false, trimExcessZero: true),
FeePerOutputs = Global.StateMachine.FeePerOutputs.ToString(fplus: false, trimExcessZero: true),
+ Version = "v1" // client should check and if the version is newer then client should update its software
});
}
catch (Exception ex)
@@ -93,9 +95,14 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
{
throw new ArgumentException("Provided input is not unspent");
}
+ // Check if inputs are confirmed or part of previous CoinJoin
if (txOutResponse.Result.Value<int>("confirmations") <= 0)
{
- throw new ArgumentException("Provided input is not confirmed");
+ if(!Global.CoinJoinStore.Transactions
+ .Any(x => x.State == CoinJoinTransactionState.Succeeded && x.Transaction.GetHash() == op.Hash))
+ {
+ throw new ArgumentException("Provided input is not confirmed, nor spends a previous CJ transaction");
+ }
}
// Check if inputs are native segwit
if (txOutResponse.Result["scriptPubKey"].Value<string>("type") != "witness_v0_keyhash")
@@ -126,7 +133,7 @@ namespace HiddenWallet.ChaumianTumbler.Controllers
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
throw new NotImplementedException();

MODIFY
HiddenWallet.ChaumianTumbler/Models/StatusResponse.cs
HiddenWallet.ChaumianTumbler/Models/StatusResponse.cs
@@ -16,5 +16,6 @@ namespace HiddenWallet.ChaumianTumbler.Models
public int MaximumInputsPerAlices { get; set; }
public string FeePerInputs { get; set; }
public string FeePerOutputs { get; set; }
+ public string Version { get; set; }
}
}

MODIFY
HiddenWallet.ChaumianTumbler/Program.cs
HiddenWallet.ChaumianTumbler/Program.cs
@@ -12,6 +12,7 @@ using NBitcoin;
using HiddenWallet.ChaumianTumbler.Configuration;
using NBitcoin.RPC;
using System.Net;
+using HiddenWallet.ChaumianTumbler.Store;
namespace HiddenWallet.ChaumianTumbler
{
@@ -23,7 +24,7 @@ namespace HiddenWallet.ChaumianTumbler
{
try
{
- var configFilePath = Path.Combine(Global.DataDir, "Config.json");
+ string configFilePath = Path.Combine(Global.DataDir, "Config.json");
Global.Config = new Config();
await Global.Config.LoadOrCreateDefaultFileAsync(configFilePath, CancellationToken.None);
@@ -35,6 +36,16 @@ namespace HiddenWallet.ChaumianTumbler
network: Global.Config.Network);
await AssertRpcNodeFullyInitializedAsync();
+ string coinJoinStorePath = Path.Combine(Global.DataDir, "CoinJoins.json");
+ if(File.Exists(coinJoinStorePath))
+ {
+ Global.CoinJoinStore = await CoinJoinStore.CreateFromFileAsync(coinJoinStorePath);
+ }
+ else
+ {
+ Global.CoinJoinStore = new CoinJoinStore();
+ }
+
Global.StateMachine = new TumblerStateMachine();
Global.StateMachineJobCancel = new CancellationTokenSource();
Global.StateMachineJob = Global.StateMachine.StartAsync(Global.StateMachineJobCancel.Token);

Enable registe unconfirmed if it spends previous CJ transaction