Skip to content

Commit c1745d7

Browse files
author
Armin Sabouri
committed
Implement tor interface in mock interface
1 parent 25025bb commit c1745d7

File tree

7 files changed

+118
-29
lines changed

7 files changed

+118
-29
lines changed

Chaincase.Common/Contracts/ITorManager.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ public interface ITorManager
2020

2121
string CreateHiddenServiceAsync();
2222

23-
Task DestroyHiddenServiceAsync();
23+
void DestroyHiddenServiceAsync(string serviceId);
2424
}
2525
}

Chaincase.Common/Global.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,11 @@ public async Task InitializeNoWalletAsync(CancellationToken cancellationToken =
148148
}
149149

150150
#region TorProcessInitialization
151-
151+
string serviceId = "";
152152
if (Config.UseTor)
153153
{
154154
await TorManager.StartAsync(ensureRunning: false, DataDir);
155+
//TorManager.CreateHiddenServiceAsync();
155156
Logger.LogInfo($"{nameof(TorManager)} is initialized.");
156157
}
157158

@@ -561,6 +562,7 @@ public async Task OnResuming()
561562
if (TorManager?.State != TorState.Started && TorManager.State != TorState.Connected)
562563
{
563564
await TorManager.StartAsync(false, DataDir);
565+
//var serviceId = TorManager.CreateHiddenServiceAsync();
564566
}
565567

566568
Nodes.Connect();
@@ -621,6 +623,7 @@ public async Task OnSleeping()
621623

622624
if (TorManager?.State != TorState.Stopped) // OnionBrowser && Dispose@Global
623625
{
626+
//TorManager.CreateHiddenServiceAsync();
624627
await TorManager.StopAsync();
625628
Logger.LogInfo($"Global.OnSleeping():{nameof(TorManager)} is stopped.");
626629
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,70 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using NBitcoin;
8+
using Newtonsoft.Json;
9+
using Newtonsoft.Json.Linq;
10+
using WalletWasabi.Helpers;
11+
using WalletWasabi.JsonConverters;
12+
using WalletWasabi.Wallets;
13+
214
namespace Chaincase.Common.Services
315
{
4-
public class P2EPRequestHandler
5-
{
6-
public P2EPRequestHandler()
7-
{
8-
}
9-
}
16+
public class P2EPRequestHandler
17+
{
18+
public P2EPRequestHandler(Network network, WalletManager walletManager, int privacyLevelThreshold)
19+
{
20+
Network = network;
21+
WalletManager = walletManager;
22+
PrivacyLevelThreshold = privacyLevelThreshold;
23+
}
24+
25+
public Network Network { get; }
26+
public WalletManager WalletManager { get; }
27+
public int PrivacyLevelThreshold { get; }
28+
29+
public Task<string> HandleAsync(string body, CancellationToken cancellationToken)
30+
{
31+
if (!PSBT.TryParse(body, Network, out var psbt))
32+
{
33+
throw new Exception("What the heck are you trying to do?");
34+
}
35+
if (!psbt.IsAllFinalized())
36+
{
37+
throw new Exception("The PSBT should be finalized");
38+
}
39+
40+
var toUse = WalletManager.GetWallets()
41+
.Where(x => x.State == WalletState.Started && !x.KeyManager.IsWatchOnly && !x.KeyManager.IsHardwareWallet)
42+
.SelectMany(wallet => wallet.Coins.Select(coin => new { wallet.KeyManager, coin }))
43+
.Where(x => x.coin.AnonymitySet >= PrivacyLevelThreshold && !x.coin.Unavailable)
44+
.OrderBy(x => x.coin.IsBanned)
45+
.ThenBy(x => x.coin.Confirmed)
46+
.ThenBy(x => x.coin.Height)
47+
.First();
48+
49+
var originalFeeRate = psbt.GetEstimatedFeeRate();
50+
var paymentTx = psbt.ExtractTransaction();
51+
foreach (var input in paymentTx.Inputs)
52+
{
53+
input.WitScript = WitScript.Empty;
54+
}
55+
var serverCoinKey = toUse.KeyManager.GetSecrets("", toUse.coin.ScriptPubKey).First();
56+
var serverCoin = toUse.coin.GetCoin();
57+
paymentTx.Inputs.Add(serverCoin.Outpoint);
58+
var paymentOutput = paymentTx.Outputs.First();
59+
var inputSizeInVBytes = (int)Math.Ceiling(((3 * Constants.P2wpkhInputSizeInBytes) + Constants.P2pkhInputSizeInBytes) / 4m);
60+
paymentOutput.Value += (Money)serverCoin.Amount - originalFeeRate.GetFee(inputSizeInVBytes);
61+
var newPsbt = PSBT.FromTransaction(paymentTx, Network.Main);
62+
var serverCoinToSign = newPsbt.Inputs.FindIndexedInput(serverCoin.Outpoint);
63+
serverCoinToSign.UpdateFromCoin(serverCoin);
64+
serverCoinToSign.Sign(serverCoinKey.PrivateKey);
65+
serverCoinToSign.FinalizeInput();
66+
67+
return Task.FromResult(newPsbt.ToHex());
68+
}
69+
}
1070
}

Chaincase.Common/Services/P2EPServer.cs

+5-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Threading;
66
using System.Threading.Tasks;
77
using Microsoft.Extensions.Hosting;
8-
using WalletWasabi.TorControl;
98
using Chaincase.Common.Contracts;
109

1110
namespace Chaincase.Common.Services
@@ -33,12 +32,10 @@ public override async Task StartAsync(CancellationToken cancellationToken)
3332
//{
3433
// await Task.Delay(TimeSpan.FromSeconds(10)).ConfigureAwait(false);
3534
//}
35+
ServiceId = TorManager.CreateHiddenServiceAsync();
3636

37-
ServiceId = await TorManager.CreateHiddenServiceAsync().ConfigureAwait(false);
38-
39-
await TorControlClient.ConnectAsync().ConfigureAwait(false);
40-
await TorControlClient.AuthenticateAsync("MyLittlePonny").ConfigureAwait(false);
41-
ServiceId = await TorControlClient.CreateHiddenServiceAsync().ConfigureAwait(false);
37+
//await TorControlClient.ConnectAsync().ConfigureAwait(false);
38+
//await TorControlClient.AuthenticateAsync("MyLittlePonny").ConfigureAwait(false);
4239

4340
Listener.Start();
4441
await base.StartAsync(cancellationToken).ConfigureAwait(false);
@@ -51,7 +48,7 @@ public override async Task StopAsync(CancellationToken cancellationToken)
5148
var serviceId = ServiceId;
5249
if (!string.IsNullOrWhiteSpace(serviceId))
5350
{
54-
await TorControlClient.DestroyHiddenService(serviceId);
51+
TorManager.DestroyHiddenServiceAsync(serviceId);
5552
}
5653
}
5754

@@ -81,7 +78,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
8178
await output.WriteAsync(buffer, 0, buffer.Length, stoppingToken).ConfigureAwait(false);
8279
await output.FlushAsync(stoppingToken).ConfigureAwait(false);
8380
}
84-
catch (P2EPException e)
81+
catch (Exception e)
8582
{
8683
response.StatusCode = (int)HttpStatusCode.BadRequest;
8784
response.StatusDescription = e.Message;
@@ -100,7 +97,6 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
10097
}
10198
catch (Exception ex)
10299
{
103-
Logger.LogError(ex);
104100
}
105101
}
106102
}

Chaincase.SSB/MockTorManager.cs

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ public class MockTorManager : ITorManager
88
{
99
public TorState State { get; } = TorState.Connected;
1010

11+
public string CreateHiddenServiceAsync()
12+
{
13+
throw new System.NotImplementedException();
14+
}
15+
16+
public void DestroyHiddenServiceAsync(string serviceId)
17+
{
18+
throw new System.NotImplementedException();
19+
}
20+
1121
public Task StartAsync(bool ensureRunning, string dataDir)
1222
{
1323
return Task.CompletedTask;

Chaincase.iOS/Services/iOSTorManager.cs

+22-12
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using WalletWasabi.Helpers;
1414
using WalletWasabi.Logging;
1515
using WalletWasabi.TorSocks5;
16+
using System.Threading;
1617

1718
namespace Chaincase.iOS.Services
1819
{
@@ -282,22 +283,31 @@ public async Task StopAsync()
282283
}
283284
}
284285

285-
public async Task CreateHiddenServiceAsync() {
286-
try
287-
{
288-
TorController.SendCommand("ADD_ONION", new String[] { "NEW:BEST" }, "Flags=DiscardPK Port=37129,37129",
289-
(keys, values, boolPointer) => {
290-
return true;
286+
public string CreateHiddenServiceAsync() {
287+
EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
288+
string serviceId = "";
289+
TorController.SendCommand(new NSString("ADD_ONION"),
290+
new string[] { "NEW:BEST", "Port=37129,37129", "Flags=DiscardPK" },
291+
null, (keys, values, _) => {
292+
serviceId = values[0].ToString().Split('=')[1];
293+
ewh.Set();
294+
return true;
291295
});
292-
}
293-
catch (Exception error) {
294-
295-
}
296+
ewh.WaitOne();
297+
return serviceId;
296298
}
297299

298-
public async Task DestroyHiddenServiceAsync()
300+
public void DestroyHiddenServiceAsync(string serviceId)
299301
{
300-
302+
EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
303+
TorController.SendCommand(new NSString("DEL_ONION"),
304+
new string[] { $"{serviceId}" }, null,
305+
(keys, values, _) =>
306+
{
307+
ewh.Set();
308+
return true;
309+
});
310+
ewh.WaitOne();
301311
}
302312

303313

Chaincase/MockServices/MockTorManager.cs

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ public class MockTorManager : ITorManager
88
{
99
public TorState State { get; } = TorState.Connected;
1010

11+
public string CreateHiddenServiceAsync()
12+
{
13+
throw new System.NotImplementedException();
14+
}
15+
16+
public void DestroyHiddenServiceAsync(string serviceId)
17+
{
18+
throw new System.NotImplementedException();
19+
}
20+
1121
public Task StartAsync(bool ensureRunning, string dataDir)
1222
{
1323
return Task.CompletedTask;

0 commit comments

Comments
 (0)