Skip to content

Commit

Permalink
Merge pull request #1551 from dahlia/fix-maintain-static-peers
Browse files Browse the repository at this point in the history
Fix `Swarm<T>.MaintainStaticPeersAsync()` throwing `PingTimeoutException`
  • Loading branch information
dahlia committed Oct 26, 2021
2 parents 2e80048 + 3736e1d commit e555137
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 16 deletions.
5 changes: 5 additions & 0 deletions CHANGES.md
Expand Up @@ -46,6 +46,9 @@ To be released.
silently no-op when a given `sourceChainId` had not existed, which had not
been compliant with `IStore.ForkBlockIndexes()` method's specification.
[[#1544]]
- Fixed `Swarm<T>`'s bug that it had thrown `PingTimeoutException` if any
peer in configured `SwarmOptions.StaticPeers` is unreachable.
[[#1550], [#1551]]
- (Libplanet.RocksDBStore) Fixed `RocksDBStore.ForkBlockIndexes()` method's
bug that it had done silently no-op when a given `sourceChainId` had not
existed, which had not been compliant with `IStore.ForkBlockIndexes()`
Expand All @@ -62,6 +65,8 @@ To be released.
[#1535]: https://github.com/planetarium/libplanet/pull/1535
[#1537]: https://github.com/planetarium/libplanet/pull/1537
[#1544]: https://github.com/planetarium/libplanet/pull/1544
[#1550]: https://github.com/planetarium/libplanet/issues/1550
[#1551]: https://github.com/planetarium/libplanet/pull/1551


Version 0.18.2
Expand Down
16 changes: 10 additions & 6 deletions Libplanet.Tests/Net/SwarmTest.cs
Expand Up @@ -30,6 +30,7 @@
using xRetry;
using Xunit;
using Xunit.Abstractions;
using static Libplanet.Tests.TestUtils;

namespace Libplanet.Tests.Net
{
Expand Down Expand Up @@ -300,14 +301,18 @@ public async Task MaintainStaticPeers()
{
(BoundPeer)swarmA.AsPeer,
(BoundPeer)swarmB.AsPeer,
// Unreachable peer:
new BoundPeer(
new PrivateKey().PublicKey,
new DnsEndPoint("127.0.0.1", 65535)
),
}.ToImmutableHashSet(),
StaticPeersMaintainPeriod = TimeSpan.FromMilliseconds(100),
});

await StartAsync(swarm);
await Task.Delay(500);
Assert.Contains(swarmA.AsPeer, swarm.Peers);
Assert.Contains(swarmB.AsPeer, swarm.Peers);
await AssertThatEventually(() => swarm.Peers.Contains(swarmA.AsPeer), 5_000);
await AssertThatEventually(() => swarm.Peers.Contains(swarmB.AsPeer), 5_000);

_logger.Debug("Address of swarmA: {Address}", swarmA.Address);
await StopAsync(swarmA);
Expand All @@ -324,9 +329,8 @@ public async Task MaintainStaticPeers()
Assert.Contains(swarmB.AsPeer, swarm.Peers);

await StartAsync(swarmC);
await Task.Delay(500);
Assert.Contains(swarmC.AsPeer, swarm.Peers);
Assert.Contains(swarmB.AsPeer, swarm.Peers);
await AssertThatEventually(() => swarm.Peers.Contains(swarmB.AsPeer), 5_000);
await AssertThatEventually(() => swarm.Peers.Contains(swarmC.AsPeer), 5_000);

await StopAsync(swarm);
}
Expand Down
24 changes: 14 additions & 10 deletions Libplanet/Net/Swarm.cs
Expand Up @@ -1286,19 +1286,23 @@ private bool IsBlockNeeded(IBlockExcerpt target)
TimeSpan period,
CancellationToken cancellationToken)
{
TimeSpan timeout = TimeSpan.FromSeconds(3);
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(period, cancellationToken);
Options.StaticPeers.AsParallel().ForAll(async boundPeer =>
{
if (!RoutingTable.Contains(boundPeer))
var tasks = Options.StaticPeers
.Where(peer => !RoutingTable.Contains(peer))
.Select(async peer =>
{
await AddPeersAsync(
new[] { boundPeer },
TimeSpan.FromSeconds(3),
cancellationToken);
}
});
try
{
await AddPeersAsync(new[] { peer }, timeout, cancellationToken);
}
catch (TimeoutException)
{
}
});
await Task.WhenAll(tasks);
await Task.Delay(period, cancellationToken);
}
}
}
Expand Down

0 comments on commit e555137

Please sign in to comment.