Skip to content

Commit

Permalink
feat: random walk to discover peers
Browse files Browse the repository at this point in the history
  • Loading branch information
richardschneider committed May 21, 2019
1 parent c8713c2 commit 34d534d
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 34 deletions.
2 changes: 1 addition & 1 deletion IpfsServer/IpfsServer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ipfs.Core" Version="0.50.0" />
<PackageReference Include="Ipfs.Core" Version="0.50.1" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="4.0.1" />
</ItemGroup>
Expand Down
6 changes: 6 additions & 0 deletions src/DiscoveryOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,11 @@ public class DiscoveryOptions
/// and advertising of this peer.
/// </summary>
public bool DisableMdns;

/// <summary>
/// Disables discovery of other peers by walking the
/// DHT.
/// </summary>
public bool DisableRandomWalk;
}
}
8 changes: 8 additions & 0 deletions src/IpfsEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,14 @@ public async Task StartAsync()
stopTasks.Add(async () => await mdns.StopAsync().ConfigureAwait(false));
await mdns.StartAsync().ConfigureAwait(false);
},
async () =>
{
if (Options.Discovery.DisableRandomWalk)
return;
var randomWalk = new RandomWalk { Dht = Dht };
stopTasks.Add(async () => await randomWalk.StopAsync().ConfigureAwait(false));
await randomWalk.StartAsync().ConfigureAwait(false);
}
};
log.Debug("waiting for discovery services to start");
await Task.WhenAll(tasks.Select(t => t())).ConfigureAwait(false);
Expand Down
4 changes: 2 additions & 2 deletions src/IpfsEngine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Ipfs.Core" Version="0.50.0" />
<PackageReference Include="Ipfs.Core" Version="0.50.1" />
<PackageReference Include="Makaretu.Dns.Unicast" Version="0.8.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="Nito.AsyncEx.Coordination" Version="5.0.0" />
<PackageReference Include="PeerTalk" Version="0.11.2" />
<PackageReference Include="PeerTalk" Version="0.11.3" />
<PackageReference Include="PeterO.Cbor" Version="3.1.0" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.5" />
<PackageReference Include="protobuf-net" Version="2.4.0" />
Expand Down
9 changes: 7 additions & 2 deletions src/RandomWalk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace Ipfs.Engine
/// <remarks>
/// This is a background task that runs every <see cref="Period"/>.
/// </remarks>
class RandomWalk : IService
public class RandomWalk : IService
{
static ILog log = LogManager.GetLogger(typeof(RandomWalk));
Random rng = new Random();
Expand Down Expand Up @@ -49,7 +49,7 @@ class RandomWalk : IService
/// </summary>
public Task StartAsync()
{
if (this != null)
if (thread != null)
{
throw new Exception("Already started.");
}
Expand All @@ -59,6 +59,7 @@ public Task StartAsync()
IsBackground = true
};
thread.Start();
log.Debug("started");

return Task.CompletedTask;
}
Expand All @@ -71,6 +72,8 @@ public Task StopAsync()
thread?.Abort();
thread = null;

log.Debug("stopped");

return Task.CompletedTask;
}

Expand All @@ -95,6 +98,8 @@ void Runner()

void RunQuery()
{
log.Debug("Running a query");

// Get a random peer id.
byte[] x = new byte[32];
rng.NextBytes(x);
Expand Down
29 changes: 0 additions & 29 deletions test/CoreApi/DhtApiTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,35 +65,6 @@ public async Task FindProvider()
}
}

[TestMethod]
public async Task RandomWalk()
{
//var id = "QmSoLMeWqB7YGVLJN3pxxQpmmEk35v6wYtsMGLzSr5QBU3"; // TODO
byte[] x = new byte[32];
(new Random()).NextBytes(x);
var id = MultiHash.ComputeHash(x);

var ipfs = TestFixture.Ipfs;
await ipfs.StartAsync();
try
{
var prevPeers = (await ipfs.Swarm.AddressesAsync()).ToArray();
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1 * 60));
await ipfs.Dht.FindPeerAsync(id, cts.Token);
var peers = (await ipfs.Swarm.AddressesAsync()).ToArray();
foreach (var peer in peers)
{
if (!prevPeers.Contains(peer))
{
Console.WriteLine($"found {peer} conn={peer.ConnectedAddress}");
}
}
}
finally
{
await ipfs.StopAsync();
}
}
}
}

49 changes: 49 additions & 0 deletions test/RandomWalkTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Ipfs.Engine
{
[TestClass]
public class RandomWalkTest
{
[TestMethod]
public async Task CanStartAndStop()
{
var walk = new RandomWalk();
await walk.StartAsync();
await walk.StopAsync();

await walk.StartAsync();
await walk.StopAsync();
}

[TestMethod]
public void CannotStartTwice()
{
var walk = new RandomWalk();
walk.StartAsync().Wait();
ExceptionAssert.Throws<Exception>(() =>
{
walk.StartAsync().Wait();
});
}

[TestMethod]
public async Task CanStopMultipletimes()
{
var walk = new RandomWalk();
await walk.StartAsync();
await walk.StopAsync();
await walk.StopAsync();
await walk.StartAsync();
await walk.StopAsync();
}
}
}

0 comments on commit 34d534d

Please sign in to comment.